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