CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 1.2 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 1.2
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Classes

  • AclBase
  • AclBehavior
  • AclComponent
  • AclNode
  • AclShell
  • Aco
  • AcoAction
  • AjaxHelper
  • ApcEngine
  • ApiShell
  • App
  • AppController
  • AppHelper
  • AppModel
  • Aro
  • AuthComponent
  • BakeShell
  • BehaviorCollection
  • Cache
  • CacheEngine
  • CacheHelper
  • CakeErrorController
  • CakeLog
  • CakeSchema
  • CakeSession
  • CakeSocket
  • ClassRegistry
  • Component
  • Configure
  • ConnectionManager
  • ConsoleShell
  • ContainableBehavior
  • Controller
  • ControllerTask
  • CookieComponent
  • DataSource
  • DbAcl
  • DbAclSchema
  • DbConfigTask
  • DboAdodb
  • DboDb2
  • DboFirebird
  • DboMssql
  • DboMysql
  • DboMysqlBase
  • DboMysqli
  • DboOdbc
  • DboOracle
  • DboPostgres
  • DboSource
  • DboSqlite
  • DboSybase
  • Debugger
  • EmailComponent
  • ErrorHandler
  • ExtractTask
  • File
  • FileEngine
  • Flay
  • Folder
  • FormHelper
  • Helper
  • HtmlHelper
  • HttpSocket
  • I18n
  • I18nModel
  • i18nSchema
  • I18nShell
  • Inflector
  • IniAcl
  • JavascriptHelper
  • JsHelper
  • JsHelperObject
  • L10n
  • MagicDb
  • MagicFileResource
  • MediaView
  • MemcacheEngine
  • Model
  • ModelBehavior
  • ModelTask
  • Multibyte
  • NumberHelper
  • Object
  • Overloadable
  • Overloadable2
  • PagesController
  • PaginatorHelper
  • Permission
  • PluginTask
  • ProjectTask
  • RequestHandlerComponent
  • Router
  • RssHelper
  • Sanitize
  • Scaffold
  • ScaffoldView
  • SchemaShell
  • Security
  • SecurityComponent
  • SessionComponent
  • SessionHelper
  • SessionsSchema
  • Set
  • Shell
  • String
  • TestSuiteShell
  • TestTask
  • TextHelper
  • ThemeView
  • TimeHelper
  • TranslateBehavior
  • TreeBehavior
  • Validation
  • View
  • ViewTask
  • XcacheEngine
  • Xml
  • XmlElement
  • XmlHelper
  • XmlManager
  • XmlNode
  • XmlTextNode

Functions

  • __enclose
  • make_clean_css
  • mb_encode_mimeheader
  • mb_stripos
  • mb_stristr
  • mb_strlen
  • mb_strpos
  • mb_strrchr
  • mb_strrichr
  • mb_strripos
  • mb_strrpos
  • mb_strstr
  • mb_strtolower
  • mb_strtoupper
  • mb_substr
  • mb_substr_count
  • write_css_cache
  1: <?php
  2: /* SVN FILE: $Id$ */
  3: /**
  4:  * The ModelTask handles creating and updating models files.
  5:  *
  6:  * Long description for file
  7:  *
  8:  * PHP versions 4 and 5
  9:  *
 10:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 11:  * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 12:  *
 13:  * Licensed under The MIT License
 14:  * Redistributions of files must retain the above copyright notice.
 15:  *
 16:  * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 17:  * @link          http://cakephp.org CakePHP(tm) Project
 18:  * @package       cake
 19:  * @subpackage    cake.cake.console.libs.tasks
 20:  * @since         CakePHP(tm) v 1.2
 21:  * @version       $Revision$
 22:  * @modifiedby    $LastChangedBy$
 23:  * @lastmodified  $Date$
 24:  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
 25:  */
 26: App::import('Model', 'ConnectionManager');
 27: /**
 28:  * Task class for creating and updating model files.
 29:  *
 30:  * @package       cake
 31:  * @subpackage    cake.cake.console.libs.tasks
 32:  */
 33: class ModelTask extends Shell {
 34: /**
 35:  * Name of plugin
 36:  *
 37:  * @var string
 38:  * @access public
 39:  */
 40:     var $plugin = null;
 41: /**
 42:  * path to MODELS directory
 43:  *
 44:  * @var string
 45:  * @access public
 46:  */
 47:     var $path = MODELS;
 48: /**
 49:  * tasks
 50:  *
 51:  * @var array
 52:  * @access public
 53:  */
 54:     var $tasks = array('DbConfig');
 55: /**
 56:  * Execution method always used for tasks
 57:  *
 58:  * @access public
 59:  */
 60:     function execute() {
 61:         if (empty($this->args)) {
 62:             $this->__interactive();
 63:         }
 64: 
 65:         if (!empty($this->args[0])) {
 66:             $model = Inflector::camelize($this->args[0]);
 67:             $this->useDbConfig = 'default';
 68:             if ($this->bake($model)) {
 69:                 if ($this->_checkUnitTest()) {
 70:                     $this->bakeTest($model);
 71:                 }
 72:             }
 73:         }
 74:     }
 75: /**
 76:  * Handles interactive baking
 77:  *
 78:  * @access private
 79:  */
 80:     function __interactive() {
 81:         $this->hr();
 82:         $this->out(sprintf("Bake Model\nPath: %s", $this->path));
 83:         $this->hr();
 84:         $this->interactive = true;
 85: 
 86:         $useTable = null;
 87:         $primaryKey = 'id';
 88:         $validate = array();
 89:         $associations = array('belongsTo'=> array(), 'hasOne'=> array(), 'hasMany' => array(), 'hasAndBelongsToMany'=> array());
 90: 
 91:         $useDbConfig = 'default';
 92:         $configs = get_class_vars('DATABASE_CONFIG');
 93: 
 94:         if (!is_array($configs)) {
 95:             return $this->DbConfig->execute();
 96:         }
 97: 
 98:         $connections = array_keys($configs);
 99:         if (count($connections) > 1) {
100:             $useDbConfig = $this->in(__('Use Database Config', true) .':', $connections, 'default');
101:         }
102:         $this->useDbConfig = $useDbConfig;
103: 
104:         $currentModelName = $this->getName($useDbConfig);
105:         $db =& ConnectionManager::getDataSource($useDbConfig);
106:         $useTable = Inflector::tableize($currentModelName);
107:         $fullTableName = $db->fullTableName($useTable, false);
108:         $tableIsGood = false;
109: 
110:         if (array_search($useTable, $this->__tables) === false) {
111:             $this->out('');
112:             $this->out(sprintf(__("Given your model named '%s', Cake would expect a database table named %s", true), $currentModelName, $fullTableName));
113:             $tableIsGood = $this->in(__('Do you want to use this table?', true), array('y','n'), 'y');
114:         }
115: 
116:         if (strtolower($tableIsGood) == 'n' || strtolower($tableIsGood) == 'no') {
117:             $useTable = $this->in(__('What is the name of the table (enter "null" to use NO table)?', true));
118:         }
119: 
120:         while ($tableIsGood == false && strtolower($useTable) != 'null') {
121:             if (is_array($this->__tables) && !in_array($useTable, $this->__tables)) {
122:                 $fullTableName = $db->fullTableName($useTable, false);
123:                 $this->out($fullTableName . ' does not exist.');
124:                 $useTable = $this->in(__('What is the name of the table (enter "null" to use NO table)?', true));
125:                 $tableIsGood = false;
126:             } else {
127:                 $tableIsGood = true;
128:             }
129:         }
130: 
131:         $wannaDoValidation = $this->in(__('Would you like to supply validation criteria for the fields in your model?', true), array('y','n'), 'y');
132: 
133:         if (in_array($useTable, $this->__tables)) {
134:             App::import('Model');
135:             $tempModel = new Model(array('name' => $currentModelName, 'table' => $useTable, 'ds' => $useDbConfig));
136: 
137:             $fields = $tempModel->schema();
138:             if (!array_key_exists('id', $fields)) {
139:                 foreach ($fields as $name => $field) {
140:                     if (isset($field['key']) && $field['key'] == 'primary') {
141:                         break;
142:                     }
143:                 }
144:                 $primaryKey = $this->in(__('What is the primaryKey?', true), null, $name);
145:             }
146:         }
147: 
148:         if (array_search($useTable, $this->__tables) !== false && (strtolower($wannaDoValidation) == 'y' || strtolower($wannaDoValidation) == 'yes')) {
149:             $validate = $this->doValidation($tempModel);
150:         }
151: 
152:         $wannaDoAssoc = $this->in(__('Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)?', true), array('y','n'), 'y');
153:         if ((strtolower($wannaDoAssoc) == 'y' || strtolower($wannaDoAssoc) == 'yes')) {
154:             $associations = $this->doAssociations($tempModel);
155:         }
156: 
157:         $this->out('');
158:         $this->hr();
159:         $this->out(__('The following Model will be created:', true));
160:         $this->hr();
161:         $this->out("Name:       " . $currentModelName);
162: 
163:         if ($useDbConfig !== 'default') {
164:             $this->out("DB Config:  " . $useDbConfig);
165:         }
166:         if ($fullTableName !== Inflector::tableize($currentModelName)) {
167:             $this->out("DB Table:   " . $fullTableName);
168:         }
169:         if ($primaryKey != 'id') {
170:             $this->out("Primary Key: " . $primaryKey);
171:         }
172:         if (!empty($validate)) {
173:             $this->out("Validation: " . print_r($validate, true));
174:         }
175:         if (!empty($associations)) {
176:             $this->out("Associations:");
177: 
178:             if (!empty($associations['belongsTo'])) {
179:                 for ($i = 0; $i < count($associations['belongsTo']); $i++) {
180:                     $this->out("            $currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}");
181:                 }
182:             }
183: 
184:             if (!empty($associations['hasOne'])) {
185:                 for ($i = 0; $i < count($associations['hasOne']); $i++) {
186:                     $this->out("            $currentModelName hasOne    {$associations['hasOne'][$i]['alias']}");
187:                 }
188:             }
189: 
190:             if (!empty($associations['hasMany'])) {
191:                 for ($i = 0; $i < count($associations['hasMany']); $i++) {
192:                     $this->out("            $currentModelName hasMany   {$associations['hasMany'][$i]['alias']}");
193:                 }
194:             }
195: 
196:             if (!empty($associations['hasAndBelongsToMany'])) {
197:                 for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
198:                     $this->out("            $currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}");
199:                 }
200:             }
201:         }
202:         $this->hr();
203:         $looksGood = $this->in(__('Look okay?', true), array('y','n'), 'y');
204: 
205:         if (strtolower($looksGood) == 'y' || strtolower($looksGood) == 'yes') {
206:             if ($this->bake($currentModelName, $associations, $validate, $primaryKey, $useTable, $useDbConfig)) {
207:                 if ($this->_checkUnitTest()) {
208:                     $this->bakeTest($currentModelName, $useTable, $associations);
209:                 }
210:             }
211:         } else {
212:             return false;
213:         }
214:     }
215: /**
216:  * Handles associations
217:  *
218:  * @param object $model
219:  * @param boolean $interactive
220:  * @return array $validate
221:  * @access public
222:  */
223:     function doValidation(&$model, $interactive = true) {
224:         if (!is_object($model)) {
225:             return false;
226:         }
227:         $fields = $model->schema();
228: 
229:         if (empty($fields)) {
230:             return false;
231:         }
232: 
233:         $validate = array();
234: 
235:         $options = array();
236: 
237:         if (class_exists('Validation')) {
238:             $parent = get_class_methods(get_parent_class('Validation'));
239:             $options = array_diff(get_class_methods('Validation'), $parent);
240:         }
241: 
242:         foreach ($fields as $fieldName => $field) {
243:             $prompt = 'Field: ' . $fieldName . "\n";
244:             $prompt .= 'Type: ' . $field['type'] . "\n";
245:             $prompt .= '---------------------------------------------------------------'."\n";
246:             $prompt .= 'Please select one of the following validation options:'."\n";
247:             $prompt .= '---------------------------------------------------------------'."\n";
248: 
249:             sort($options);
250: 
251:             $skip = 1;
252:             foreach ($options as $key => $option) {
253:                 if ($option{0} != '_' && strtolower($option) != 'getinstance') {
254:                     $prompt .= "{$skip} - {$option}\n";
255:                     $choices[$skip] = strtolower($option);
256:                     $skip++;
257:                 }
258:             }
259: 
260:             $methods = array_flip($choices);
261: 
262:             $prompt .=  "{$skip} - Do not do any validation on this field.\n";
263:             $prompt .= "... or enter in a valid regex validation string.\n";
264: 
265:             $guess = $skip;
266:             if ($field['null'] != 1 && $fieldName != $model->primaryKey && !in_array($fieldName, array('created', 'modified', 'updated'))) {
267:                 if ($fieldName == 'email') {
268:                     $guess = $methods['email'];
269:                 } elseif ($field['type'] == 'string') {
270:                     $guess = $methods['notempty'];
271:                 } elseif ($field['type'] == 'integer') {
272:                     $guess = $methods['numeric'];
273:                 } elseif ($field['type'] == 'boolean') {
274:                     $guess = $methods['numeric'];
275:                 } elseif ($field['type'] == 'datetime') {
276:                     $guess = $methods['date'];
277:                 }
278:             }
279: 
280:             if ($interactive === true) {
281:                 $this->out('');
282:                 $choice = $this->in($prompt, null, $guess);
283:             } else {
284:                 $choice = $guess;
285:             }
286:             if ($choice != $skip) {
287:                 if (is_numeric($choice) && isset($choices[$choice])) {
288:                     $validate[$fieldName] = $choices[$choice];
289:                 } else {
290:                     $validate[$fieldName] = $choice;
291:                 }
292:             }
293:         }
294:         return $validate;
295:     }
296: 
297: /**
298:  * Handles associations
299:  *
300:  * @param object $model
301:  * @param boolean $interactive
302:  * @return array $assocaitons
303:  * @access public
304:  */
305:     function doAssociations(&$model, $interactive = true) {
306: 
307:         if (!is_object($model)) {
308:             return false;
309:         }
310:         $this->out(__('One moment while the associations are detected.', true));
311: 
312:         $fields = $model->schema();
313: 
314:         if (empty($fields)) {
315:             return false;
316:         }
317: 
318:         $primaryKey = $model->primaryKey;
319:         $foreignKey = $this->_modelKey($model->name);
320: 
321:         $associations = array('belongsTo' => array(), 'hasMany' => array(), 'hasOne'=> array(), 'hasAndBelongsToMany' => array());
322:         $possibleKeys = array();
323: 
324:         //Look for belongsTo
325:         $i = 0;
326:         foreach ($fields as $fieldName => $field) {
327:             $offset = strpos($fieldName, '_id');
328:             if ($fieldName != $model->primaryKey && $offset !== false) {
329:                 $tmpModelName = $this->_modelNameFromKey($fieldName);
330:                 $associations['belongsTo'][$i]['alias'] = $tmpModelName;
331:                 $associations['belongsTo'][$i]['className'] = $tmpModelName;
332:                 $associations['belongsTo'][$i]['foreignKey'] = $fieldName;
333:                 $i++;
334:             }
335:         }
336:         //Look for hasOne and hasMany and hasAndBelongsToMany
337:         $i = $j = 0;
338: 
339:         foreach ($this->__tables as $otherTable) {
340:             App::import('Model');
341:             $tmpModelName = $this->_modelName($otherTable);
342:             $tempOtherModel = & new Model(array('name' => $tmpModelName, 'table' => $otherTable, 'ds' => $model->useDbConfig));
343:             $modelFieldsTemp = $tempOtherModel->schema();
344: 
345:             $offset = strpos($otherTable, $model->table . '_');
346:             $otherOffset = strpos($otherTable, '_' . $model->table);
347: 
348:             foreach ($modelFieldsTemp as $fieldName => $field) {
349:                 if ($field['type'] == 'integer' || $field['type'] == 'string') {
350:                     $possibleKeys[$otherTable][] = $fieldName;
351:                 }
352:                 if ($fieldName != $model->primaryKey && $fieldName == $foreignKey && $offset === false && $otherOffset === false) {
353:                     $associations['hasOne'][$j]['alias'] = $tempOtherModel->name;
354:                     $associations['hasOne'][$j]['className'] = $tempOtherModel->name;
355:                     $associations['hasOne'][$j]['foreignKey'] = $fieldName;
356: 
357:                     $associations['hasMany'][$j]['alias'] = $tempOtherModel->name;
358:                     $associations['hasMany'][$j]['className'] = $tempOtherModel->name;
359:                     $associations['hasMany'][$j]['foreignKey'] = $fieldName;
360:                     $j++;
361:                 }
362:             }
363: 
364:             if ($offset !== false) {
365:                 $offset = strlen($model->table . '_');
366:                 $tmpModelName = $this->_modelName(substr($otherTable, $offset));
367:                 $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
368:                 $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
369:                 $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $foreignKey;
370:                 $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->_modelKey($tmpModelName);
371:                 $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
372:                 $i++;
373:             }
374: 
375:             if ($otherOffset !== false) {
376:                 $tmpModelName = $this->_modelName(substr($otherTable, 0, $otherOffset));
377:                 $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
378:                 $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
379:                 $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $foreignKey;
380:                 $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->_modelKey($tmpModelName);
381:                 $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
382:                 $i++;
383:             }
384:         }
385: 
386:         if ($interactive !== true) {
387:             unset($associations['hasOne']);
388:         }
389: 
390:         if ($interactive === true) {
391:             $this->hr();
392:             if (empty($associations)) {
393:                 $this->out(__('None found.', true));
394:             } else {
395:                 $this->out(__('Please confirm the following associations:', true));
396:                 $this->hr();
397:                 foreach ($associations as $type => $settings) {
398:                     if (!empty($associations[$type])) {
399:                         $count = count($associations[$type]);
400:                         $response = 'y';
401:                         for ($i = 0; $i < $count; $i++) {
402:                             $prompt = "{$model->name} {$type} {$associations[$type][$i]['alias']}";
403:                             $response = $this->in("{$prompt}?", array('y','n'), 'y');
404: 
405:                             if ('n' == strtolower($response) || 'no' == strtolower($response)) {
406:                                 unset($associations[$type][$i]);
407:                             } else {
408:                                 if ($model->name === $associations[$type][$i]['alias']) {
409:                                     if ($type === 'belongsTo') {
410:                                         $alias = 'Parent' . $associations[$type][$i]['alias'];
411:                                     }
412:                                     if ($type === 'hasOne' || $type === 'hasMany') {
413:                                         $alias = 'Child' . $associations[$type][$i]['alias'];
414:                                     }
415: 
416:                                     $alternateAlias = $this->in(sprintf(__('This is a self join. Use %s as the alias', true), $alias), array('y', 'n'), 'y');
417: 
418:                                     if ('n' == strtolower($alternateAlias) || 'no' == strtolower($alternateAlias)) {
419:                                         $associations[$type][$i]['alias'] = $this->in(__('Specify an alternate alias.', true));
420:                                     } else {
421:                                         $associations[$type][$i]['alias'] = $alias;
422:                                     }
423:                                 }
424:                             }
425:                         }
426:                         $associations[$type] = array_merge($associations[$type]);
427:                     }
428:                 }
429:             }
430: 
431:             $wannaDoMoreAssoc = $this->in(__('Would you like to define some additional model associations?', true), array('y','n'), 'n');
432: 
433:             while ((strtolower($wannaDoMoreAssoc) == 'y' || strtolower($wannaDoMoreAssoc) == 'yes')) {
434:                 $assocs = array(1 => 'belongsTo', 2 => 'hasOne', 3 => 'hasMany', 4 => 'hasAndBelongsToMany');
435:                 $bad = true;
436:                 while ($bad) {
437:                     $this->out(__('What is the association type?', true));
438:                     $prompt = "1. belongsTo\n";
439:                     $prompt .= "2. hasOne\n";
440:                     $prompt .= "3. hasMany\n";
441:                     $prompt .= "4. hasAndBelongsToMany\n";
442:                     $assocType = intval($this->in($prompt, null, __("Enter a number", true)));
443: 
444:                     if (intval($assocType) < 1 || intval($assocType) > 4) {
445:                         $this->out(__('The selection you entered was invalid. Please enter a number between 1 and 4.', true));
446:                     } else {
447:                         $bad = false;
448:                     }
449:                 }
450:                 $this->out(__('For the following options be very careful to match your setup exactly. Any spelling mistakes will cause errors.', true));
451:                 $this->hr();
452:                 $alias = $this->in(__('What is the alias for this association?', true));
453:                 $className = $this->in(sprintf(__('What className will %s use?', true), $alias), null, $alias );
454:                 $suggestedForeignKey = null;
455:                 if ($assocType == '1') {
456:                     $showKeys = $possibleKeys[$model->table];
457:                     $suggestedForeignKey = $this->_modelKey($alias);
458:                 } else {
459:                     $otherTable = Inflector::tableize($className);
460:                     if (in_array($otherTable, $this->__tables)) {
461:                         if ($assocType < '4') {
462:                             $showKeys = $possibleKeys[$otherTable];
463:                         } else {
464:                             $showKeys = null;
465:                         }
466:                     } else {
467:                         $otherTable = $this->in(__('What is the table for this model?', true));
468:                         $showKeys = $possibleKeys[$otherTable];
469:                     }
470:                     $suggestedForeignKey = $this->_modelKey($model->name);
471:                 }
472:                 if (!empty($showKeys)) {
473:                     $this->out(__('A helpful List of possible keys', true));
474:                     for ($i = 0; $i < count($showKeys); $i++) {
475:                         $this->out($i + 1 . ". " . $showKeys[$i]);
476:                     }
477:                     $foreignKey = $this->in(__('What is the foreignKey?', true), null, __("Enter a number", true));
478:                     if (intval($foreignKey) > 0 && intval($foreignKey) <= $i ) {
479:                         $foreignKey = $showKeys[intval($foreignKey) - 1];
480:                     }
481:                 }
482:                 if (!isset($foreignKey)) {
483:                     $foreignKey = $this->in(__('What is the foreignKey? Specify your own.', true), null, $suggestedForeignKey);
484:                 }
485:                 if ($assocType == '4') {
486:                     $associationForeignKey = $this->in(__('What is the associationForeignKey?', true), null, $this->_modelKey($model->name));
487:                     $joinTable = $this->in(__('What is the joinTable?', true));
488:                 }
489:                 $associations[$assocs[$assocType]] = array_values((array)$associations[$assocs[$assocType]]);
490:                 $count = count($associations[$assocs[$assocType]]);
491:                 $i = ($count > 0) ? $count : 0;
492:                 $associations[$assocs[$assocType]][$i]['alias'] = $alias;
493:                 $associations[$assocs[$assocType]][$i]['className'] = $className;
494:                 $associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
495:                 if ($assocType == '4') {
496:                     $associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
497:                     $associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
498:                 }
499:                 $wannaDoMoreAssoc = $this->in(__('Define another association?', true), array('y','n'), 'y');
500:             }
501:         }
502:         return $associations;
503:     }
504: /**
505:  * Assembles and writes a Model file.
506:  *
507:  * @param mixed $name Model name or object
508:  * @param mixed $associations if array and $name is not an object assume Model associations array otherwise boolean interactive
509:  * @param array $validate Validation rules
510:  * @param string $primaryKey Primary key to use
511:  * @param string $useTable Table to use
512:  * @param string $useDbConfig Database configuration setting to use
513:  * @access private
514:  */
515:     function bake($name, $associations = array(),  $validate = array(), $primaryKey = 'id', $useTable = null, $useDbConfig = 'default') {
516: 
517:         if (is_object($name)) {
518:             if (!is_array($associations)) {
519:                 $associations = $this->doAssociations($name, $associations);
520:                 $validate = $this->doValidation($name, $associations);
521:             }
522:             $primaryKey = $name->primaryKey;
523:             $useTable = $name->table;
524:             $useDbConfig = $name->useDbConfig;
525:             $name = $name->name;
526:         }
527: 
528:         $out = "<?php\n";
529:         $out .= "class {$name} extends {$this->plugin}AppModel {\n\n";
530:         $out .= "\tvar \$name = '{$name}';\n";
531: 
532:         if ($useDbConfig !== 'default') {
533:             $out .= "\tvar \$useDbConfig = '$useDbConfig';\n";
534:         }
535: 
536:         if (($useTable && $useTable !== Inflector::tableize($name)) || $useTable === false) {
537:             $table = "'$useTable'";
538:             if (!$useTable) {
539:                 $table = 'false';
540:             }
541:             $out .= "\tvar \$useTable = $table;\n";
542:         }
543: 
544:         if ($primaryKey !== 'id') {
545:             $out .= "\tvar \$primaryKey = '$primaryKey';\n";
546:         }
547: 
548:         $validateCount = count($validate);
549:         if (is_array($validate) && $validateCount > 0) {
550:             $out .= "\tvar \$validate = array(\n";
551:             $keys = array_keys($validate);
552:             for ($i = 0; $i < $validateCount; $i++) {
553:                 $val = "'" . $validate[$keys[$i]] . "'";
554:                 $out .= "\t\t'" . $keys[$i] . "' => array({$val})";
555:                 if ($i + 1 < $validateCount) {
556:                     $out .= ",";
557:                 }
558:                 $out .= "\n";
559:             }
560:             $out .= "\t);\n";
561:         }
562:         $out .= "\n";
563: 
564:         if (!empty($associations)) {
565:             if (!empty($associations['belongsTo']) || !empty($associations['hasOne']) || !empty($associations['hasMany']) || !empty($associations['hasAndBelongsToMany'])) {
566:                 $out.= "\t//The Associations below have been created with all possible keys, those that are not needed can be removed\n";
567:             }
568: 
569:             if (!empty($associations['belongsTo'])) {
570:                 $out .= "\tvar \$belongsTo = array(\n";
571:                 $belongsToCount = count($associations['belongsTo']);
572: 
573:                 for ($i = 0; $i < $belongsToCount; $i++) {
574:                     $out .= "\t\t'{$associations['belongsTo'][$i]['alias']}' => array(\n";
575:                     $out .= "\t\t\t'className' => '{$associations['belongsTo'][$i]['className']}',\n";
576:                     $out .= "\t\t\t'foreignKey' => '{$associations['belongsTo'][$i]['foreignKey']}',\n";
577:                     $out .= "\t\t\t'conditions' => '',\n";
578:                     $out .= "\t\t\t'fields' => '',\n";
579:                     $out .= "\t\t\t'order' => ''\n";
580:                     $out .= "\t\t)";
581:                     if ($i + 1 < $belongsToCount) {
582:                         $out .= ",";
583:                     }
584:                     $out .= "\n";
585: 
586:                 }
587:                 $out .= "\t);\n\n";
588:             }
589: 
590:             if (!empty($associations['hasOne'])) {
591:                 $out .= "\tvar \$hasOne = array(\n";
592:                 $hasOneCount = count($associations['hasOne']);
593: 
594:                 for ($i = 0; $i < $hasOneCount; $i++) {
595:                     $out .= "\t\t'{$associations['hasOne'][$i]['alias']}' => array(\n";
596:                     $out .= "\t\t\t'className' => '{$associations['hasOne'][$i]['className']}',\n";
597:                     $out .= "\t\t\t'foreignKey' => '{$associations['hasOne'][$i]['foreignKey']}',\n";
598:                     $out .= "\t\t\t'dependent' => false,\n";
599:                     $out .= "\t\t\t'conditions' => '',\n";
600:                     $out .= "\t\t\t'fields' => '',\n";
601:                     $out .= "\t\t\t'order' => ''\n";
602:                     $out .= "\t\t)";
603:                     if ($i + 1 < $hasOneCount) {
604:                         $out .= ",";
605:                     }
606:                     $out .= "\n";
607: 
608:                 }
609:                 $out .= "\t);\n\n";
610:             }
611: 
612:             if (!empty($associations['hasMany'])) {
613:                 $out .= "\tvar \$hasMany = array(\n";
614:                 $hasManyCount = count($associations['hasMany']);
615: 
616:                 for ($i = 0; $i < $hasManyCount; $i++) {
617:                     $out .= "\t\t'{$associations['hasMany'][$i]['alias']}' => array(\n";
618:                     $out .= "\t\t\t'className' => '{$associations['hasMany'][$i]['className']}',\n";
619:                     $out .= "\t\t\t'foreignKey' => '{$associations['hasMany'][$i]['foreignKey']}',\n";
620:                     $out .= "\t\t\t'dependent' => false,\n";
621:                     $out .= "\t\t\t'conditions' => '',\n";
622:                     $out .= "\t\t\t'fields' => '',\n";
623:                     $out .= "\t\t\t'order' => '',\n";
624:                     $out .= "\t\t\t'limit' => '',\n";
625:                     $out .= "\t\t\t'offset' => '',\n";
626:                     $out .= "\t\t\t'exclusive' => '',\n";
627:                     $out .= "\t\t\t'finderQuery' => '',\n";
628:                     $out .= "\t\t\t'counterQuery' => ''\n";
629:                     $out .= "\t\t)";
630:                     if ($i + 1 < $hasManyCount) {
631:                         $out .= ",";
632:                     }
633:                     $out .= "\n";
634:                 }
635:                 $out .= "\t);\n\n";
636:             }
637: 
638:             if (!empty($associations['hasAndBelongsToMany'])) {
639:                 $out .= "\tvar \$hasAndBelongsToMany = array(\n";
640:                 $hasAndBelongsToManyCount = count($associations['hasAndBelongsToMany']);
641: 
642:                 for ($i = 0; $i < $hasAndBelongsToManyCount; $i++) {
643:                     $out .= "\t\t'{$associations['hasAndBelongsToMany'][$i]['alias']}' => array(\n";
644:                     $out .= "\t\t\t'className' => '{$associations['hasAndBelongsToMany'][$i]['className']}',\n";
645:                     $out .= "\t\t\t'joinTable' => '{$associations['hasAndBelongsToMany'][$i]['joinTable']}',\n";
646:                     $out .= "\t\t\t'foreignKey' => '{$associations['hasAndBelongsToMany'][$i]['foreignKey']}',\n";
647:                     $out .= "\t\t\t'associationForeignKey' => '{$associations['hasAndBelongsToMany'][$i]['associationForeignKey']}',\n";
648:                     $out .= "\t\t\t'unique' => true,\n";
649:                     $out .= "\t\t\t'conditions' => '',\n";
650:                     $out .= "\t\t\t'fields' => '',\n";
651:                     $out .= "\t\t\t'order' => '',\n";
652:                     $out .= "\t\t\t'limit' => '',\n";
653:                     $out .= "\t\t\t'offset' => '',\n";
654:                     $out .= "\t\t\t'finderQuery' => '',\n";
655:                     $out .= "\t\t\t'deleteQuery' => '',\n";
656:                     $out .= "\t\t\t'insertQuery' => ''\n";
657:                     $out .= "\t\t)";
658:                     if ($i + 1 < $hasAndBelongsToManyCount) {
659:                         $out .= ",";
660:                     }
661:                     $out .= "\n";
662:                 }
663:                 $out .= "\t);\n\n";
664:             }
665:         }
666:         $out .= "}\n";
667:         $out .= "?>";
668:         ClassRegistry::flush();
669:         $filename = $this->path . Inflector::underscore($name) . '.php';
670:         $this->out("\nBaking model class for $name...");
671:         return $this->createFile($filename, $out);
672:     }
673: 
674: /**
675:  * Assembles and writes a unit test file
676:  *
677:  * @param string $className Model class name
678:  * @access private
679:  */
680:     function bakeTest($className, $useTable = null, $associations = array()) {
681:         $results = $this->fixture($className, $useTable);
682: 
683:         if ($results) {
684:             $fixtureInc = 'app';
685:             if ($this->plugin) {
686:                 $fixtureInc = 'plugin.'.Inflector::underscore($this->plugin);
687:             }
688: 
689:             $fixture[] = "'{$fixtureInc}." . Inflector::underscore($className) ."'";
690: 
691:             if (!empty($associations)) {
692:                 $assoc[] = Set::extract($associations, 'belongsTo.{n}.className');
693:                 $assoc[] = Set::extract($associations, 'hasOne.{n}.className');
694:                 $assoc[] = Set::extract($associations, 'hasMany.{n}.className');
695:                 foreach ($assoc as $key => $value) {
696:                     if (is_array($value)) {
697:                         foreach ($value as $class) {
698:                             $fixture[] = "'{$fixtureInc}." . Inflector::underscore($class) ."'";
699:                         }
700:                     }
701:                 }
702:             }
703:             $fixture = implode(", ", $fixture);
704: 
705:             $import = $className;
706:             if (isset($this->plugin)) {
707:                 $import = $this->plugin . '.' . $className;
708:             }
709: 
710:             $out = "App::import('Model', '$import');\n\n";
711:             $out .= "class {$className}TestCase extends CakeTestCase {\n";
712:             $out .= "\tvar \${$className} = null;\n";
713:             $out .= "\tvar \$fixtures = array($fixture);\n\n";
714:             $out .= "\tfunction startTest() {\n";
715:             $out .= "\t\t\$this->{$className} =& ClassRegistry::init('{$className}');\n";
716:             $out .= "\t}\n\n";
717:             $out .= "\tfunction test{$className}Instance() {\n";
718:             $out .= "\t\t\$this->assertTrue(is_a(\$this->{$className}, '{$className}'));\n";
719:             $out .= "\t}\n\n";
720:             $out .= "\tfunction test{$className}Find() {\n";
721:             $out .= "\t\t\$this->{$className}->recursive = -1;\n";
722:             $out .= "\t\t\$results = \$this->{$className}->find('first');\n\t\t\$this->assertTrue(!empty(\$results));\n\n";
723:             $out .= "\t\t\$expected = array('$className' => array(\n$results\n\t\t));\n";
724:             $out .= "\t\t\$this->assertEqual(\$results, \$expected);\n";
725:             $out .= "\t}\n";
726:             $out .= "}\n";
727: 
728:             $path = MODEL_TESTS;
729:             if (isset($this->plugin)) {
730:                 $pluginPath = 'plugins' . DS . Inflector::underscore($this->plugin) . DS;
731:                 $path = APP . $pluginPath . 'tests' . DS . 'cases' . DS . 'models' . DS;
732:             }
733: 
734:             $filename = Inflector::underscore($className).'.test.php';
735:             $this->out("\nBaking unit test for $className...");
736: 
737:             $header = '$Id';
738:             $content = "<?php \n/* SVN FILE: $header$ */\n/* " . $className . " Test cases generated on: " . date('Y-m-d H:i:s') . " : " . time() . "*/\n{$out}?>";
739:             return $this->createFile($path . $filename, $content);
740:         }
741:         return false;
742:     }
743: /**
744:  * outputs the a list of possible models or controllers from database
745:  *
746:  * @param string $useDbConfig Database configuration name
747:  * @access public
748:  */
749:     function listAll($useDbConfig = 'default', $interactive = true) {
750:         $db =& ConnectionManager::getDataSource($useDbConfig);
751:         $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
752:         if ($usePrefix) {
753:             $tables = array();
754:             foreach ($db->listSources() as $table) {
755:                 if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
756:                     $tables[] = substr($table, strlen($usePrefix));
757:                 }
758:             }
759:         } else {
760:             $tables = $db->listSources();
761:         }
762:         if (empty($tables)) {
763:             $this->err(__('Your database does not have any tables.', true));
764:             $this->_stop();
765:         }
766: 
767:         $this->__tables = $tables;
768: 
769:         if ($interactive === true) {
770:             $this->out(__('Possible Models based on your current database:', true));
771:             $this->_modelNames = array();
772:             $count = count($tables);
773:             for ($i = 0; $i < $count; $i++) {
774:                 $this->_modelNames[] = $this->_modelName($tables[$i]);
775:                 $this->out($i + 1 . ". " . $this->_modelNames[$i]);
776:             }
777:         }
778:     }
779: /**
780:  * Forces the user to specify the model he wants to bake, and returns the selected model name.
781:  *
782:  * @return string the model name
783:  * @access public
784:  */
785:     function getName($useDbConfig) {
786:         $this->listAll($useDbConfig);
787: 
788:         $enteredModel = '';
789: 
790:         while ($enteredModel == '') {
791:             $enteredModel = $this->in(__("Enter a number from the list above, type in the name of another model, or 'q' to exit", true), null, 'q');
792: 
793:             if ($enteredModel === 'q') {
794:                 $this->out(__("Exit", true));
795:                 $this->_stop();
796:             }
797: 
798:             if ($enteredModel == '' || intval($enteredModel) > count($this->_modelNames)) {
799:                 $this->err(__("The model name you supplied was empty, or the number you selected was not an option. Please try again.", true));
800:                 $enteredModel = '';
801:             }
802:         }
803: 
804:         if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->_modelNames)) {
805:             $currentModelName = $this->_modelNames[intval($enteredModel) - 1];
806:         } else {
807:             $currentModelName = $enteredModel;
808:         }
809: 
810:         return $currentModelName;
811:     }
812: /**
813:  * Displays help contents
814:  *
815:  * @access public
816:  */
817:     function help() {
818:         $this->hr();
819:         $this->out("Usage: cake bake model <arg1>");
820:         $this->hr();
821:         $this->out('Commands:');
822:         $this->out("\n\tmodel\n\t\tbakes model in interactive mode.");
823:         $this->out("\n\tmodel <name>\n\t\tbakes model file with no associations or validation");
824:         $this->out("");
825:         $this->_stop();
826:     }
827: /**
828:  * Builds the tests fixtures for the model and create the file
829:  *
830:  * @param string $model the name of the model
831:  * @param string $useTable table name
832:  * @return array $records, used in ModelTask::bakeTest() to create $expected
833:  * @todo move this to a task
834:  */
835:     function fixture($model, $useTable = null) {
836:         if (!class_exists('CakeSchema')) {
837:             App::import('Model', 'Schema');
838:         }
839:         $out = "\nclass {$model}Fixture extends CakeTestFixture {\n";
840:         $out .= "\tvar \$name = '$model';\n";
841: 
842:         if (!$useTable) {
843:             $useTable = Inflector::tableize($model);
844:         } else {
845:             $out .= "\tvar \$table = '$useTable';\n";
846:         }
847:         $schema = new CakeSchema();
848:         $data = $schema->read(array('models' => false, 'connection' => $this->useDbConfig));
849: 
850:         if (!isset($data['tables'][$useTable])) {
851:             return false;
852:         }
853:         $tables[$model] = $data['tables'][$useTable];
854: 
855:         foreach ($tables as $table => $fields) {
856:             if (!is_numeric($table) && $table !== 'missing') {
857:                 $out .= "\tvar \$fields = array(\n";
858:                 $records = array();
859:                 if (is_array($fields)) {
860:                     $cols = array();
861:                     foreach ($fields as $field => $value) {
862:                         if ($field != 'indexes') {
863:                             if (is_string($value)) {
864:                                 $type = $value;
865:                                 $value = array('type'=> $type);
866:                             }
867:                             $col = "\t\t'{$field}' => array('type'=>'" . $value['type'] . "', ";
868: 
869:                             switch ($value['type']) {
870:                                 case 'float':
871:                                 case 'integer':
872:                                     $insert = 1;
873:                                 break;
874:                                 case 'binary':
875:                                 case 'string';
876:                                     $insert = "Lorem ipsum dolor sit amet";
877:                                     if (!empty($value['length'])) {
878:                                         $insert = substr($insert, 0, (int)$value['length'] - 2);
879:                                     }
880:                                     $insert = "'$insert'";
881:                                 break;
882:                                 case 'datetime':
883:                                     $ts = date('Y-m-d H:i:s');
884:                                     $insert = "'$ts'";
885:                                 break;
886:                                 case 'date':
887:                                     $ts = date('Y-m-d');
888:                                     $insert = "'$ts'";
889:                                 break;
890:                                 case 'time':
891:                                     $ts = date('H:i:s');
892:                                     $insert = "'$ts'";
893:                                 break;
894:                                 case 'boolean':
895:                                     $insert = 1;
896:                                 break;
897:                                 case 'text':
898:                                     $insert =
899:                                     "'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida,";
900:                                     $insert .= "phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam,";
901:                                     $insert .= "vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit,";
902:                                     $insert .= "feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.'";
903:                                 break;
904:                             }
905:                             $records[] = "\t\t'$field' => $insert";
906:                             unset($value['type']);
907:                             $col .= implode(', ',  $schema->__values($value));
908:                         } else {
909:                             $col = "\t\t'indexes' => array(";
910:                             $props = array();
911:                             foreach ((array)$value as $key => $index) {
912:                                 $props[] = "'{$key}' => array(" . implode(', ',  $schema->__values($index)) . ")";
913:                             }
914:                             $col .= implode(', ', $props);
915:                         }
916:                         $col .= ")";
917:                         $cols[] = $col;
918:                     }
919:                     $out .= implode(",\n", $cols);
920:                 }
921:                 $out .= "\n\t);\n";
922:             }
923:         }
924:         $records = implode(",\n", $records);
925:         $out .= "\tvar \$records = array(array(\n$records\n\t));\n";
926:         $out .= "}\n";
927:         $path = TESTS . DS . 'fixtures' . DS;
928:         if (isset($this->plugin)) {
929:             $pluginPath = 'plugins' . DS . Inflector::underscore($this->plugin) . DS;
930:             $path = APP . $pluginPath . 'tests' . DS . 'fixtures' . DS;
931:         }
932:         $filename = Inflector::underscore($model) . '_fixture.php';
933:         $header = '$Id';
934:         $content = "<?php \n/* SVN FILE: $header$ */\n/* " . $model . " Fixture generated on: " . date('Y-m-d H:i:s') . " : " . time() . "*/\n{$out}?>";
935:         $this->out("\nBaking test fixture for $model...");
936:         if ($this->createFile($path . $filename, $content)) {
937:             return str_replace("\t\t", "\t\t\t", $records);
938:         }
939:         return false;
940:     }
941: }
942: ?>
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs