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