1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: App::uses('CakeSchema', 'Model');
17:
18: 19: 20: 21: 22: 23:
24: class CakeTestFixture {
25:
26: 27: 28: 29: 30:
31: public $name = null;
32:
33: 34: 35: 36: 37:
38: public $db = null;
39:
40: 41: 42: 43: 44:
45: public $useDbConfig = 'test';
46:
47: 48: 49: 50: 51:
52: public $table = null;
53:
54: 55: 56: 57: 58:
59: public $created = array();
60:
61: 62: 63: 64: 65:
66: public function __construct() {
67: if ($this->name === null) {
68: if (preg_match('/^(.*)Fixture$/', get_class($this), $matches)) {
69: $this->name = $matches[1];
70: } else {
71: $this->name = get_class($this);
72: }
73: }
74: $connection = 'test';
75: if (!empty($this->useDbConfig)) {
76: $connection = $this->useDbConfig;
77: if (strpos($connection, 'test') !== 0) {
78: $message = __d(
79: 'cake_dev',
80: 'Invalid datasource name "%s" for "%s" fixture. Fixture datasource names must begin with "test".',
81: $connection,
82: $this->name
83: );
84: throw new CakeException($message);
85: }
86: }
87: $this->Schema = new CakeSchema(array('name' => 'TestSuite', 'connection' => $connection));
88: $this->init();
89: }
90:
91: 92: 93: 94: 95: 96:
97: public function init() {
98: if (isset($this->import) && (is_string($this->import) || is_array($this->import))) {
99: $import = array_merge(
100: array('connection' => 'default', 'records' => false),
101: is_array($this->import) ? $this->import : array('model' => $this->import)
102: );
103:
104: $this->Schema->connection = $import['connection'];
105: if (isset($import['model'])) {
106: list($plugin, $modelClass) = pluginSplit($import['model'], true);
107: App::uses($modelClass, $plugin . 'Model');
108: if (!class_exists($modelClass)) {
109: throw new MissingModelException(array('class' => $modelClass));
110: }
111: $model = new $modelClass(null, null, $import['connection']);
112: $db = $model->getDataSource();
113: if (empty($model->tablePrefix)) {
114: $model->tablePrefix = $db->config['prefix'];
115: }
116: $this->fields = $model->schema(true);
117: $this->fields[$model->primaryKey]['key'] = 'primary';
118: $this->table = $db->fullTableName($model, false, false);
119: ClassRegistry::config(array('ds' => 'test'));
120: ClassRegistry::flush();
121: } elseif (isset($import['table'])) {
122: $model = new Model(null, $import['table'], $import['connection']);
123: $db = ConnectionManager::getDataSource($import['connection']);
124: $db->cacheSources = false;
125: $model->useDbConfig = $import['connection'];
126: $model->name = Inflector::camelize(Inflector::singularize($import['table']));
127: $model->table = $import['table'];
128: $model->tablePrefix = $db->config['prefix'];
129: $this->fields = $model->schema(true);
130: ClassRegistry::flush();
131: }
132:
133: if (!empty($db->config['prefix']) && strpos($this->table, $db->config['prefix']) === 0) {
134: $this->table = str_replace($db->config['prefix'], '', $this->table);
135: }
136:
137: if (isset($import['records']) && $import['records'] !== false && isset($model) && isset($db)) {
138: $this->records = array();
139: $query = array(
140: 'fields' => $db->fields($model, null, array_keys($this->fields)),
141: 'table' => $db->fullTableName($model),
142: 'alias' => $model->alias,
143: 'conditions' => array(),
144: 'order' => null,
145: 'limit' => null,
146: 'group' => null
147: );
148: $records = $db->fetchAll($db->buildStatement($query, $model), false, $model->alias);
149:
150: if ($records !== false && !empty($records)) {
151: $this->records = Hash::extract($records, '{n}.' . $model->alias);
152: }
153: }
154: }
155:
156: if (!isset($this->table)) {
157: $this->table = Inflector::underscore(Inflector::pluralize($this->name));
158: }
159:
160: if (!isset($this->primaryKey) && isset($this->fields['id'])) {
161: $this->primaryKey = 'id';
162: }
163: }
164:
165: 166: 167: 168: 169: 170:
171: public function create($db) {
172: if (!isset($this->fields) || empty($this->fields)) {
173: return false;
174: }
175:
176: if (empty($this->fields['tableParameters']['engine'])) {
177: $canUseMemory = true;
178: foreach ($this->fields as $field => $args) {
179:
180: if (is_string($args)) {
181: $type = $args;
182: } elseif (!empty($args['type'])) {
183: $type = $args['type'];
184: } else {
185: continue;
186: }
187:
188: if (in_array($type, array('blob', 'text', 'binary'))) {
189: $canUseMemory = false;
190: break;
191: }
192: }
193:
194: if ($canUseMemory) {
195: $this->fields['tableParameters']['engine'] = 'MEMORY';
196: }
197: }
198: $this->Schema->build(array($this->table => $this->fields));
199: try {
200: $db->execute($db->createSchema($this->Schema), array('log' => false));
201: $this->created[] = $db->configKeyName;
202: } catch (Exception $e) {
203: $msg = __d(
204: 'cake_dev',
205: 'Fixture creation for "%s" failed "%s"',
206: $this->table,
207: $e->getMessage()
208: );
209: CakeLog::error($msg);
210: trigger_error($msg, E_USER_WARNING);
211: return false;
212: }
213: return true;
214: }
215:
216: 217: 218: 219: 220: 221:
222: public function drop($db) {
223: if (empty($this->fields)) {
224: return false;
225: }
226: $this->Schema->build(array($this->table => $this->fields));
227: try {
228:
229: $db->execute($db->dropSchema($this->Schema), array('log' => false));
230: $this->created = array_diff($this->created, array($db->configKeyName));
231: } catch (Exception $e) {
232: return false;
233: }
234: return true;
235: }
236:
237: 238: 239: 240: 241: 242: 243:
244: public function insert($db) {
245: if (!isset($this->_insert)) {
246: $values = array();
247: if (isset($this->records) && !empty($this->records)) {
248: $fields = array();
249: foreach ($this->records as $record) {
250: $fields = array_merge($fields, array_keys(array_intersect_key($record, $this->fields)));
251: }
252: $fields = array_unique($fields);
253: $default = array_fill_keys($fields, null);
254: foreach ($this->records as $record) {
255: $fields = array_keys($record);
256: $values[] = array_values(array_merge($default, $record));
257: }
258: $nested = $db->useNestedTransactions;
259: $db->useNestedTransactions = false;
260: $result = $db->insertMulti($this->table, $fields, $values);
261: $db->useNestedTransactions = $nested;
262: return $result;
263: }
264: return true;
265: }
266: }
267:
268: 269: 270: 271: 272: 273: 274:
275: public function truncate($db) {
276: $fullDebug = $db->fullDebug;
277: $db->fullDebug = false;
278: $return = $db->truncate($this->table);
279: $db->fullDebug = $fullDebug;
280: return $return;
281: }
282:
283: }
284: