1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
19:
20: App::uses('ConnectionManager', 'Model');
21: App::uses('ClassRegistry', 'Utility');
22:
23: 24: 25: 26: 27:
28: class CakeFixtureManager {
29:
30: 31: 32: 33: 34:
35: protected $_initialized = false;
36:
37: 38: 39: 40: 41:
42: protected $_db = null;
43:
44: 45: 46: 47: 48:
49: protected $_loaded = array();
50:
51: 52: 53: 54: 55:
56: protected $_fixtureMap = array();
57:
58: 59: 60: 61: 62: 63:
64: public function fixturize($test) {
65: if (!$this->_initialized) {
66: ClassRegistry::config(array('ds' => 'test', 'testing' => true));
67: }
68: if (empty($test->fixtures) || !empty($this->_processed[get_class($test)])) {
69: $test->db = $this->_db;
70: return;
71: }
72: $this->_initDb();
73: $test->db = $this->_db;
74: if (!is_array($test->fixtures)) {
75: $test->fixtures = array_map('trim', explode(',', $test->fixtures));
76: }
77: if (isset($test->fixtures)) {
78: $this->_loadFixtures($test->fixtures);
79: }
80:
81: $this->_processed[get_class($test)] = true;
82: }
83:
84: 85: 86: 87: 88:
89: protected function _initDb() {
90: if ($this->_initialized) {
91: return;
92: }
93: $db = ConnectionManager::getDataSource('test');
94: $db->cacheSources = false;
95: $this->_db = $db;
96: $this->_initialized = true;
97: }
98:
99: 100: 101: 102: 103: 104:
105: protected function _loadFixtures($fixtures) {
106: foreach ($fixtures as $index => $fixture) {
107: $fixtureFile = null;
108: $fixtureIndex = $fixture;
109: if (isset($this->_loaded[$fixture])) {
110: continue;
111: }
112:
113: if (strpos($fixture, 'core.') === 0) {
114: $fixture = substr($fixture, strlen('core.'));
115: $fixturePaths[] = CAKE . 'Test' . DS . 'Fixture';
116: } elseif (strpos($fixture, 'app.') === 0) {
117: $fixture = substr($fixture, strlen('app.'));
118: $fixturePaths = array(
119: TESTS . 'Fixture'
120: );
121: } elseif (strpos($fixture, 'plugin.') === 0) {
122: $parts = explode('.', $fixture, 3);
123: $pluginName = $parts[1];
124: $fixture = $parts[2];
125: $fixturePaths = array(
126: CakePlugin::path(Inflector::camelize($pluginName)) . 'Test' . DS . 'Fixture',
127: TESTS . 'Fixture'
128: );
129: } else {
130: $fixturePaths = array(
131: TESTS . 'Fixture',
132: CAKE . 'Test' . DS . 'Fixture'
133: );
134: }
135:
136: foreach ($fixturePaths as $path) {
137: $className = Inflector::camelize($fixture);
138: if (is_readable($path . DS . $className . 'Fixture.php')) {
139: $fixtureFile = $path . DS . $className . 'Fixture.php';
140: require_once $fixtureFile;
141: $fixtureClass = $className . 'Fixture';
142: $this->_loaded[$fixtureIndex] = new $fixtureClass();
143: $this->_fixtureMap[$fixtureClass] = $this->_loaded[$fixtureIndex];
144: break;
145: }
146: }
147: }
148: }
149:
150: 151: 152: 153: 154: 155: 156: 157:
158: protected function _setupTable($fixture, $db = null, $drop = true) {
159: if (!$db) {
160: if (!empty($fixture->useDbConfig)) {
161: $db = ClassRegistry::getDataSource($fixture->useDbConfig);
162: } else {
163: $db = $this->_db;
164: }
165: }
166: if (!empty($fixture->created) && in_array($db->configKeyName, $fixture->created)) {
167: return;
168: }
169:
170: $sources = $db->listSources();
171: $table = $db->config['prefix'] . $fixture->table;
172: $exists = in_array($table, $sources);
173:
174: if ($drop && $exists) {
175: $fixture->drop($db);
176: $fixture->create($db);
177: } elseif (!$exists) {
178: $fixture->create($db);
179: } else {
180: $fixture->created[] = $db->configKeyName;
181: }
182: }
183:
184: 185: 186: 187: 188: 189:
190: public function load(CakeTestCase $test) {
191: if (empty($test->fixtures)) {
192: return;
193: }
194: $fixtures = $test->fixtures;
195: if (empty($fixtures) || $test->autoFixtures == false) {
196: return;
197: }
198:
199: $test->db->begin();
200: foreach ($fixtures as $f) {
201: if (!empty($this->_loaded[$f])) {
202: $fixture = $this->_loaded[$f];
203: $db = ConnectionManager::getDataSource($fixture->useDbConfig);
204: $this->_setupTable($fixture, $db, $test->dropTables);
205: $fixture->insert($db);
206: }
207: }
208: $test->db->commit();
209: }
210:
211: 212: 213: 214: 215: 216:
217: public function unload(CakeTestCase $test) {
218: $fixtures = !empty($test->fixtures) ? $test->fixtures : array();
219: foreach (array_reverse($fixtures) as $f) {
220: if (isset($this->_loaded[$f])) {
221: $fixture = $this->_loaded[$f];
222: if (!empty($fixture->created)) {
223: foreach ($fixture->created as $ds) {
224: $db = ConnectionManager::getDataSource($ds);
225: $fixture->truncate($db);
226: }
227: }
228: }
229: }
230: }
231:
232: 233: 234: 235: 236: 237: 238: 239:
240: public function loadSingle($name, $db = null) {
241: $name .= 'Fixture';
242: if (isset($this->_fixtureMap[$name])) {
243: $fixture = $this->_fixtureMap[$name];
244: if (!$db) {
245: $db = ConnectionManager::getDataSource($fixture->useDbConfig);
246: }
247: $this->_setupTable($fixture, $db);
248: $fixture->truncate($db);
249: $fixture->insert($db);
250: } else {
251: throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s not found', $name));
252: }
253: }
254:
255: 256: 257: 258: 259:
260: public function shutDown() {
261: foreach ($this->_loaded as $fixture) {
262: if (!empty($fixture->created)) {
263: foreach ($fixture->created as $ds) {
264: $db = ConnectionManager::getDataSource($ds);
265: $fixture->drop($db);
266: }
267: }
268: }
269: }
270:
271: }
272: