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 (empty($test->fixtures) || !empty($this->_processed[get_class($test)])) {
66: $test->db = $this->_db;
67: return;
68: }
69: $this->_initDb();
70: $test->db = $this->_db;
71: if (!is_array($test->fixtures)) {
72: $test->fixtures = array_map('trim', explode(',', $test->fixtures));
73: }
74: if (isset($test->fixtures)) {
75: $this->_loadFixtures($test->fixtures);
76: }
77:
78: $this->_processed[get_class($test)] = true;
79: }
80:
81: 82: 83: 84: 85:
86: protected function _initDb() {
87: if ($this->_initialized) {
88: return;
89: }
90: $db = ConnectionManager::getDataSource('test');
91: $db->cacheSources = false;
92: $this->_db = $db;
93: ClassRegistry::config(array('ds' => 'test'));
94: $this->_initialized = true;
95: }
96:
97: 98: 99: 100: 101: 102:
103: protected function _loadFixtures($fixtures) {
104: foreach ($fixtures as $index => $fixture) {
105: $fixtureFile = null;
106: $fixtureIndex = $fixture;
107: if (isset($this->_loaded[$fixture])) {
108: continue;
109: }
110:
111: if (strpos($fixture, 'core.') === 0) {
112: $fixture = substr($fixture, strlen('core.'));
113: $fixturePaths[] = CAKE . 'Test' . DS . 'Fixture';
114: } elseif (strpos($fixture, 'app.') === 0) {
115: $fixture = substr($fixture, strlen('app.'));
116: $fixturePaths = array(
117: TESTS . 'Fixture'
118: );
119: } elseif (strpos($fixture, 'plugin.') === 0) {
120: $parts = explode('.', $fixture, 3);
121: $pluginName = $parts[1];
122: $fixture = $parts[2];
123: $fixturePaths = array(
124: CakePlugin::path(Inflector::camelize($pluginName)) . 'Test' . DS . 'Fixture',
125: TESTS . 'Fixture'
126: );
127: } else {
128: $fixturePaths = array(
129: TESTS . 'Fixture',
130: CAKE . 'Test' . DS . 'Fixture'
131: );
132: }
133:
134: foreach ($fixturePaths as $path) {
135: $className = Inflector::camelize($fixture);
136: if (is_readable($path . DS . $className . 'Fixture.php')) {
137: $fixtureFile = $path . DS . $className . 'Fixture.php';
138: require_once($fixtureFile);
139: $fixtureClass = $className . 'Fixture';
140: $this->_loaded[$fixtureIndex] = new $fixtureClass($this->_db);
141: $this->_fixtureMap[$fixtureClass] = $this->_loaded[$fixtureIndex];
142: break;
143: }
144: }
145: }
146: }
147:
148: 149: 150: 151: 152: 153: 154: 155:
156: protected function _setupTable($fixture, $db = null, $drop = true) {
157: if (!$db) {
158: $db = $this->_db;
159: }
160: if (!empty($fixture->created) && $fixture->created == $db->configKeyName) {
161: return;
162: }
163:
164: $sources = $db->listSources();
165: $table = $db->config['prefix'] . $fixture->table;
166:
167: if ($drop && in_array($table, $sources)) {
168: $fixture->drop($db);
169: $fixture->create($db);
170: $fixture->created = $db->configKeyName;
171: } elseif (!in_array($table, $sources)) {
172: $fixture->create($db);
173: $fixture->created = $db->configKeyName;
174: }
175: }
176:
177: 178: 179: 180: 181: 182:
183: public function load(CakeTestCase $test) {
184: if (empty($test->fixtures)) {
185: return;
186: }
187: $fixtures = $test->fixtures;
188: if (empty($fixtures) || $test->autoFixtures == false) {
189: return;
190: }
191:
192: $test->db->begin();
193: foreach ($fixtures as $f) {
194: if (!empty($this->_loaded[$f])) {
195: $fixture = $this->_loaded[$f];
196: $this->_setupTable($fixture, $test->db, $test->dropTables);
197: $fixture->insert($test->db);
198: }
199: }
200: $test->db->commit();
201: }
202:
203: 204: 205: 206: 207: 208:
209: public function unload(CakeTestCase $test) {
210: $fixtures = !empty($test->fixtures) ? $test->fixtures : array();
211: foreach (array_reverse($fixtures) as $f) {
212: if (isset($this->_loaded[$f])) {
213: $fixture = $this->_loaded[$f];
214: if (!empty($fixture->created)) {
215: $fixture->truncate($test->db);
216: }
217: }
218: }
219: }
220:
221: 222: 223: 224: 225: 226: 227:
228: public function loadSingle($name, $db = null) {
229: $name .= 'Fixture';
230: if (isset($this->_fixtureMap[$name])) {
231: if (!$db) {
232: $db = $this->_db;
233: }
234: $fixture = $this->_fixtureMap[$name];
235: $this->_setupTable($fixture, $db);
236: $fixture->truncate($db);
237: $fixture->insert($db);
238: } else {
239: throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s not found', $name));
240: }
241: }
242:
243: 244: 245: 246: 247:
248: public function shutDown() {
249: foreach ($this->_loaded as $fixture) {
250: if (!empty($fixture->created)) {
251: $fixture->drop($this->_db);
252: }
253: }
254: }
255: }
256: