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:
106: protected function _loadFixtures($fixtures) {
107: foreach ($fixtures as $index => $fixture) {
108: $fixtureFile = null;
109: $fixtureIndex = $fixture;
110: if (isset($this->_loaded[$fixture])) {
111: continue;
112: }
113:
114: if (strpos($fixture, 'core.') === 0) {
115: $fixture = substr($fixture, strlen('core.'));
116: $fixturePaths[] = CAKE . 'Test' . DS . 'Fixture';
117: } elseif (strpos($fixture, 'app.') === 0) {
118: $fixture = substr($fixture, strlen('app.'));
119: $fixturePaths = array(
120: TESTS . 'Fixture'
121: );
122: } elseif (strpos($fixture, 'plugin.') === 0) {
123: $parts = explode('.', $fixture, 3);
124: $pluginName = $parts[1];
125: $fixture = $parts[2];
126: $fixturePaths = array(
127: CakePlugin::path(Inflector::camelize($pluginName)) . 'Test' . DS . 'Fixture',
128: TESTS . 'Fixture'
129: );
130: } else {
131: $fixturePaths = array(
132: TESTS . 'Fixture',
133: CAKE . 'Test' . DS . 'Fixture'
134: );
135: }
136:
137: $loaded = false;
138: foreach ($fixturePaths as $path) {
139: $className = Inflector::camelize($fixture);
140: if (is_readable($path . DS . $className . 'Fixture.php')) {
141: $fixtureFile = $path . DS . $className . 'Fixture.php';
142: require_once $fixtureFile;
143: $fixtureClass = $className . 'Fixture';
144: $this->_loaded[$fixtureIndex] = new $fixtureClass();
145: $this->_fixtureMap[$fixtureClass] = $this->_loaded[$fixtureIndex];
146: $loaded = true;
147: break;
148: }
149: }
150:
151: if (!$loaded) {
152: $firstPath = str_replace(array(APP, CAKE_CORE_INCLUDE_PATH, ROOT), '', $fixturePaths[0] . DS . $className . 'Fixture.php');
153: throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s (%s) not found', $className, $firstPath));
154: }
155: }
156: }
157:
158: 159: 160: 161: 162: 163: 164: 165:
166: protected function _setupTable($fixture, $db = null, $drop = true) {
167: if (!$db) {
168: if (!empty($fixture->useDbConfig)) {
169: $db = ConnectionManager::getDataSource($fixture->useDbConfig);
170: } else {
171: $db = $this->_db;
172: }
173: }
174: if (!empty($fixture->created) && in_array($db->configKeyName, $fixture->created)) {
175: return;
176: }
177:
178: $sources = (array)$db->listSources();
179: $table = $db->config['prefix'] . $fixture->table;
180: $exists = in_array($table, $sources);
181:
182: if ($drop && $exists) {
183: $fixture->drop($db);
184: $fixture->create($db);
185: } elseif (!$exists) {
186: $fixture->create($db);
187: } else {
188: $fixture->created[] = $db->configKeyName;
189: }
190: }
191:
192: 193: 194: 195: 196: 197:
198: public function load(CakeTestCase $test) {
199: if (empty($test->fixtures)) {
200: return;
201: }
202: $fixtures = $test->fixtures;
203: if (empty($fixtures) || $test->autoFixtures == false) {
204: return;
205: }
206:
207: foreach ($fixtures as $f) {
208: if (!empty($this->_loaded[$f])) {
209: $fixture = $this->_loaded[$f];
210: $db = ConnectionManager::getDataSource($fixture->useDbConfig);
211: $db->begin();
212: $this->_setupTable($fixture, $db, $test->dropTables);
213: $fixture->insert($db);
214: $db->commit();
215: }
216: }
217: }
218:
219: 220: 221: 222: 223: 224:
225: public function unload(CakeTestCase $test) {
226: $fixtures = !empty($test->fixtures) ? $test->fixtures : array();
227: foreach (array_reverse($fixtures) as $f) {
228: if (isset($this->_loaded[$f])) {
229: $fixture = $this->_loaded[$f];
230: if (!empty($fixture->created)) {
231: foreach ($fixture->created as $ds) {
232: $db = ConnectionManager::getDataSource($ds);
233: $fixture->truncate($db);
234: }
235: }
236: }
237: }
238: }
239:
240: 241: 242: 243: 244: 245: 246: 247:
248: public function loadSingle($name, $db = null) {
249: $name .= 'Fixture';
250: if (isset($this->_fixtureMap[$name])) {
251: $fixture = $this->_fixtureMap[$name];
252: if (!$db) {
253: $db = ConnectionManager::getDataSource($fixture->useDbConfig);
254: }
255: $this->_setupTable($fixture, $db);
256: $fixture->truncate($db);
257: $fixture->insert($db);
258: } else {
259: throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s not found', $name));
260: }
261: }
262:
263: 264: 265: 266: 267:
268: public function shutDown() {
269: foreach ($this->_loaded as $fixture) {
270: if (!empty($fixture->created)) {
271: foreach ($fixture->created as $ds) {
272: $db = ConnectionManager::getDataSource($ds);
273: $fixture->drop($db);
274: }
275: }
276: }
277: }
278:
279: }
280: