1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
20:
21: include_once dirname(__FILE__) . DS . 'bake.php';
22:
23: 24: 25: 26: 27: 28:
29: class ModelTask extends BakeTask {
30:
31: 32: 33: 34: 35: 36:
37: var $path = MODELS;
38:
39: 40: 41: 42: 43: 44:
45: var $tasks = array('DbConfig', 'Fixture', 'Test', 'Template');
46:
47: 48: 49: 50: 51: 52:
53: var $skipTables = array('i18n');
54:
55: 56: 57: 58: 59: 60:
61: var $_tables = array();
62:
63: 64: 65: 66: 67: 68:
69: var $_validations = array();
70:
71: 72: 73: 74: 75:
76: function execute() {
77: App::import('Model', 'Model', false);
78:
79: if (empty($this->args)) {
80: $this->__interactive();
81: }
82:
83: if (!empty($this->args[0])) {
84: $this->interactive = false;
85: if (!isset($this->connection)) {
86: $this->connection = 'default';
87: }
88: if (strtolower($this->args[0]) == 'all') {
89: return $this->all();
90: }
91: $model = $this->_modelName($this->args[0]);
92: $object = $this->_getModelObject($model);
93: if ($this->bake($object, false)) {
94: if ($this->_checkUnitTest()) {
95: $this->bakeFixture($model);
96: $this->bakeTest($model);
97: }
98: }
99: }
100: }
101:
102: 103: 104: 105: 106:
107: function all() {
108: $this->listAll($this->connection, false);
109: $unitTestExists = $this->_checkUnitTest();
110: foreach ($this->_tables as $table) {
111: if (in_array($table, $this->skipTables)) {
112: continue;
113: }
114: $modelClass = Inflector::classify($table);
115: $this->out(sprintf(__('Baking %s', true), $modelClass));
116: $object = $this->_getModelObject($modelClass);
117: if ($this->bake($object, false) && $unitTestExists) {
118: $this->bakeFixture($modelClass);
119: $this->bakeTest($modelClass);
120: }
121: }
122: }
123:
124: 125: 126: 127: 128: 129:
130: function &_getModelObject($className, $table = null) {
131: if (!$table) {
132: $table = Inflector::tableize($className);
133: }
134: $object =& new Model(array('name' => $className, 'table' => $table, 'ds' => $this->connection));
135: return $object;
136: }
137:
138: 139: 140: 141: 142: 143: 144: 145:
146: function inOptions($options, $prompt = null, $default = null) {
147: $valid = false;
148: $max = count($options);
149: while (!$valid) {
150: foreach ($options as $i => $option) {
151: $this->out($i + 1 .'. ' . $option);
152: }
153: if (empty($prompt)) {
154: $prompt = __('Make a selection from the choices above', true);
155: }
156: $choice = $this->in($prompt, null, $default);
157: if (intval($choice) > 0 && intval($choice) <= $max) {
158: $valid = true;
159: }
160: }
161: return $choice - 1;
162: }
163:
164: 165: 166: 167: 168:
169: function __interactive() {
170: $this->hr();
171: $this->out(sprintf("Bake Model\nPath: %s", $this->path));
172: $this->hr();
173: $this->interactive = true;
174:
175: $primaryKey = 'id';
176: $validate = $associations = array();
177:
178: if (empty($this->connection)) {
179: $this->connection = $this->DbConfig->getConfig();
180: }
181: $currentModelName = $this->getName();
182: $useTable = $this->getTable($currentModelName);
183: $db =& ConnectionManager::getDataSource($this->connection);
184: $fullTableName = $db->fullTableName($useTable);
185:
186: if (in_array($useTable, $this->_tables)) {
187: $tempModel = new Model(array('name' => $currentModelName, 'table' => $useTable, 'ds' => $this->connection));
188: $fields = $tempModel->schema(true);
189: if (!array_key_exists('id', $fields)) {
190: $primaryKey = $this->findPrimaryKey($fields);
191: }
192: } else {
193: $this->err(sprintf(__('Table %s does not exist, cannot bake a model without a table.', true), $useTable));
194: $this->_stop();
195: return false;
196: }
197: $displayField = $tempModel->hasField(array('name', 'title'));
198: if (!$displayField) {
199: $displayField = $this->findDisplayField($tempModel->schema());
200: }
201:
202: $prompt = __("Would you like to supply validation criteria \nfor the fields in your model?", true);
203: $wannaDoValidation = $this->in($prompt, array('y','n'), 'y');
204: if (array_search($useTable, $this->_tables) !== false && strtolower($wannaDoValidation) == 'y') {
205: $validate = $this->doValidation($tempModel);
206: }
207:
208: $prompt = __("Would you like to define model associations\n(hasMany, hasOne, belongsTo, etc.)?", true);
209: $wannaDoAssoc = $this->in($prompt, array('y','n'), 'y');
210: if (strtolower($wannaDoAssoc) == 'y') {
211: $associations = $this->doAssociations($tempModel);
212: }
213:
214: $this->out();
215: $this->hr();
216: $this->out(__('The following Model will be created:', true));
217: $this->hr();
218: $this->out("Name: " . $currentModelName);
219:
220: if ($this->connection !== 'default') {
221: $this->out(sprintf(__("DB Config: %s", true), $this->connection));
222: }
223: if ($fullTableName !== Inflector::tableize($currentModelName)) {
224: $this->out(sprintf(__("DB Table: %s", true), $fullTableName));
225: }
226: if ($primaryKey != 'id') {
227: $this->out(sprintf(__("Primary Key: %s", true), $primaryKey));
228: }
229: if (!empty($validate)) {
230: $this->out(sprintf(__("Validation: %s", true), print_r($validate, true)));
231: }
232: if (!empty($associations)) {
233: $this->out(__("Associations:", true));
234: $assocKeys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
235: foreach ($assocKeys as $assocKey) {
236: $this->_printAssociation($currentModelName, $assocKey, $associations);
237: }
238: }
239:
240: $this->hr();
241: $looksGood = $this->in(__('Look okay?', true), array('y','n'), 'y');
242:
243: if (strtolower($looksGood) == 'y') {
244: $vars = compact('associations', 'validate', 'primaryKey', 'useTable', 'displayField');
245: $vars['useDbConfig'] = $this->connection;
246: if ($this->bake($currentModelName, $vars)) {
247: if ($this->_checkUnitTest()) {
248: $this->bakeFixture($currentModelName, $useTable);
249: $this->bakeTest($currentModelName, $useTable, $associations);
250: }
251: }
252: } else {
253: return false;
254: }
255: }
256:
257: 258: 259: 260: 261: 262: 263: 264: 265:
266: function _printAssociation($modelName, $type, $associations) {
267: if (!empty($associations[$type])) {
268: for ($i = 0; $i < count($associations[$type]); $i++) {
269: $out = "\t" . $modelName . ' ' . $type . ' ' . $associations[$type][$i]['alias'];
270: $this->out($out);
271: }
272: }
273: }
274:
275: 276: 277: 278: 279: 280: 281:
282: function findPrimaryKey($fields) {
283: foreach ($fields as $name => $field) {
284: if (isset($field['key']) && $field['key'] == 'primary') {
285: break;
286: }
287: }
288: return $this->in(__('What is the primaryKey?', true), null, $name);
289: }
290:
291: 292: 293: 294: 295: 296:
297: function findDisplayField($fields) {
298: $fieldNames = array_keys($fields);
299: $prompt = __("A displayField could not be automatically detected\nwould you like to choose one?", true);
300: $continue = $this->in($prompt, array('y', 'n'));
301: if (strtolower($continue) == 'n') {
302: return false;
303: }
304: $prompt = __('Choose a field from the options above:', true);
305: $choice = $this->inOptions($fieldNames, $prompt);
306: return $fieldNames[$choice];
307: }
308:
309: 310: 311: 312: 313: 314: 315:
316: function doValidation(&$model) {
317: if (!is_object($model)) {
318: return false;
319: }
320: $fields = $model->schema();
321:
322: if (empty($fields)) {
323: return false;
324: }
325: $validate = array();
326: $this->initValidations();
327: foreach ($fields as $fieldName => $field) {
328: $validation = $this->fieldValidation($fieldName, $field, $model->primaryKey);
329: if (!empty($validation)) {
330: $validate[$fieldName] = $validation;
331: }
332: }
333: return $validate;
334: }
335:
336: 337: 338: 339: 340:
341: function initValidations() {
342: $options = $choices = array();
343: if (class_exists('Validation')) {
344: $parent = get_class_methods(get_parent_class('Validation'));
345: $options = get_class_methods('Validation');
346: $options = array_diff($options, $parent);
347: }
348: sort($options);
349: $default = 1;
350: foreach ($options as $key => $option) {
351: if ($option{0} != '_' && strtolower($option) != 'getinstance') {
352: $choices[$default] = strtolower($option);
353: $default++;
354: }
355: }
356: $choices[$default] = 'none';
357: $this->_validations = $choices;
358: return $choices;
359: }
360:
361: 362: 363: 364: 365: 366: 367:
368: function fieldValidation($fieldName, $metaData, $primaryKey = 'id') {
369: $defaultChoice = count($this->_validations);
370: $validate = $alreadyChosen = array();
371:
372: $anotherValidator = 'y';
373: while ($anotherValidator == 'y') {
374: if ($this->interactive) {
375: $this->out();
376: $this->out(sprintf(__('Field: %s', true), $fieldName));
377: $this->out(sprintf(__('Type: %s', true), $metaData['type']));
378: $this->hr();
379: $this->out(__('Please select one of the following validation options:', true));
380: $this->hr();
381: }
382:
383: $prompt = '';
384: for ($i = 1; $i < $defaultChoice; $i++) {
385: $prompt .= $i . ' - ' . $this->_validations[$i] . "\n";
386: }
387: $prompt .= sprintf(__("%s - Do not do any validation on this field.\n", true), $defaultChoice);
388: $prompt .= __("... or enter in a valid regex validation string.\n", true);
389:
390: $methods = array_flip($this->_validations);
391: $guess = $defaultChoice;
392: if ($metaData['null'] != 1 && !in_array($fieldName, array($primaryKey, 'created', 'modified', 'updated'))) {
393: if ($fieldName == 'email') {
394: $guess = $methods['email'];
395: } elseif ($metaData['type'] == 'string' && $metaData['length'] == 36) {
396: $guess = $methods['uuid'];
397: } elseif ($metaData['type'] == 'string') {
398: $guess = $methods['notempty'];
399: } elseif ($metaData['type'] == 'integer') {
400: $guess = $methods['numeric'];
401: } elseif ($metaData['type'] == 'boolean') {
402: $guess = $methods['boolean'];
403: } elseif ($metaData['type'] == 'date') {
404: $guess = $methods['date'];
405: } elseif ($metaData['type'] == 'time') {
406: $guess = $methods['time'];
407: }
408: }
409:
410: if ($this->interactive === true) {
411: $choice = $this->in($prompt, null, $guess);
412: if (in_array($choice, $alreadyChosen)) {
413: $this->out(__("You have already chosen that validation rule,\nplease choose again", true));
414: continue;
415: }
416: if (!isset($this->_validations[$choice]) && is_numeric($choice)) {
417: $this->out(__('Please make a valid selection.', true));
418: continue;
419: }
420: $alreadyChosen[] = $choice;
421: } else {
422: $choice = $guess;
423: }
424:
425: if (isset($this->_validations[$choice])) {
426: $validatorName = $this->_validations[$choice];
427: } else {
428: $validatorName = Inflector::slug($choice);
429: }
430:
431: if ($choice != $defaultChoice) {
432: if (is_numeric($choice) && isset($this->_validations[$choice])) {
433: $validate[$validatorName] = $this->_validations[$choice];
434: } else {
435: $validate[$validatorName] = $choice;
436: }
437: }
438: if ($this->interactive == true && $choice != $defaultChoice) {
439: $anotherValidator = $this->in(__('Would you like to add another validation rule?', true), array('y', 'n'), 'n');
440: } else {
441: $anotherValidator = 'n';
442: }
443: }
444: return $validate;
445: }
446:
447: 448: 449: 450: 451: 452: 453:
454: function doAssociations(&$model) {
455: if (!is_object($model)) {
456: return false;
457: }
458: if ($this->interactive === true) {
459: $this->out(__('One moment while the associations are detected.', true));
460: }
461:
462: $fields = $model->schema(true);
463: if (empty($fields)) {
464: return false;
465: }
466:
467: if (empty($this->_tables)) {
468: $this->_tables = $this->getAllTables();
469: }
470:
471: $associations = array(
472: 'belongsTo' => array(), 'hasMany' => array(), 'hasOne'=> array(), 'hasAndBelongsToMany' => array()
473: );
474: $possibleKeys = array();
475:
476: $associations = $this->findBelongsTo($model, $associations);
477: $associations = $this->findHasOneAndMany($model, $associations);
478: $associations = $this->findHasAndBelongsToMany($model, $associations);
479:
480: if ($this->interactive !== true) {
481: unset($associations['hasOne']);
482: }
483:
484: if ($this->interactive === true) {
485: $this->hr();
486: if (empty($associations)) {
487: $this->out(__('None found.', true));
488: } else {
489: $this->out(__('Please confirm the following associations:', true));
490: $this->hr();
491: $associations = $this->confirmAssociations($model, $associations);
492: }
493: $associations = $this->doMoreAssociations($model, $associations);
494: }
495: return $associations;
496: }
497:
498: 499: 500: 501: 502: 503: 504:
505: function findBelongsTo(&$model, $associations) {
506: $fields = $model->schema(true);
507: foreach ($fields as $fieldName => $field) {
508: $offset = strpos($fieldName, '_id');
509: if ($fieldName != $model->primaryKey && $fieldName != 'parent_id' && $offset !== false) {
510: $tmpModelName = $this->_modelNameFromKey($fieldName);
511: $associations['belongsTo'][] = array(
512: 'alias' => $tmpModelName,
513: 'className' => $tmpModelName,
514: 'foreignKey' => $fieldName,
515: );
516: } elseif ($fieldName == 'parent_id') {
517: $associations['belongsTo'][] = array(
518: 'alias' => 'Parent' . $model->name,
519: 'className' => $model->name,
520: 'foreignKey' => $fieldName,
521: );
522: }
523: }
524: return $associations;
525: }
526:
527: 528: 529: 530: 531: 532: 533:
534: function findHasOneAndMany(&$model, $associations) {
535: $foreignKey = $this->_modelKey($model->name);
536: foreach ($this->_tables as $otherTable) {
537: $tempOtherModel = $this->_getModelObject($this->_modelName($otherTable), $otherTable);
538: $modelFieldsTemp = $tempOtherModel->schema(true);
539:
540: $pattern = '/_' . preg_quote($model->table, '/') . '|' . preg_quote($model->table, '/') . '_/';
541: $possibleJoinTable = preg_match($pattern , $otherTable);
542: if ($possibleJoinTable == true) {
543: continue;
544: }
545: foreach ($modelFieldsTemp as $fieldName => $field) {
546: $assoc = false;
547: if ($fieldName != $model->primaryKey && $fieldName == $foreignKey) {
548: $assoc = array(
549: 'alias' => $tempOtherModel->name,
550: 'className' => $tempOtherModel->name,
551: 'foreignKey' => $fieldName
552: );
553: } elseif ($otherTable == $model->table && $fieldName == 'parent_id') {
554: $assoc = array(
555: 'alias' => 'Child' . $model->name,
556: 'className' => $model->name,
557: 'foreignKey' => $fieldName
558: );
559: }
560: if ($assoc) {
561: $associations['hasOne'][] = $assoc;
562: $associations['hasMany'][] = $assoc;
563: }
564:
565: }
566: }
567: return $associations;
568: }
569:
570: 571: 572: 573: 574: 575: 576:
577: function findHasAndBelongsToMany(&$model, $associations) {
578: $foreignKey = $this->_modelKey($model->name);
579: foreach ($this->_tables as $otherTable) {
580: $tempOtherModel = $this->_getModelObject($this->_modelName($otherTable), $otherTable);
581: $modelFieldsTemp = $tempOtherModel->schema(true);
582:
583: $offset = strpos($otherTable, $model->table . '_');
584: $otherOffset = strpos($otherTable, '_' . $model->table);
585:
586: if ($offset !== false) {
587: $offset = strlen($model->table . '_');
588: $habtmName = $this->_modelName(substr($otherTable, $offset));
589: $associations['hasAndBelongsToMany'][] = array(
590: 'alias' => $habtmName,
591: 'className' => $habtmName,
592: 'foreignKey' => $foreignKey,
593: 'associationForeignKey' => $this->_modelKey($habtmName),
594: 'joinTable' => $otherTable
595: );
596: } elseif ($otherOffset !== false) {
597: $habtmName = $this->_modelName(substr($otherTable, 0, $otherOffset));
598: $associations['hasAndBelongsToMany'][] = array(
599: 'alias' => $habtmName,
600: 'className' => $habtmName,
601: 'foreignKey' => $foreignKey,
602: 'associationForeignKey' => $this->_modelKey($habtmName),
603: 'joinTable' => $otherTable
604: );
605: }
606: }
607: return $associations;
608: }
609:
610: 611: 612: 613: 614: 615: 616:
617: function confirmAssociations(&$model, $associations) {
618: foreach ($associations as $type => $settings) {
619: if (!empty($associations[$type])) {
620: $count = count($associations[$type]);
621: $response = 'y';
622: foreach ($associations[$type] as $i => $assoc) {
623: $prompt = "{$model->name} {$type} {$assoc['alias']}?";
624: $response = $this->in($prompt, array('y','n'), 'y');
625:
626: if ('n' == strtolower($response)) {
627: unset($associations[$type][$i]);
628: } elseif ($type == 'hasMany') {
629: unset($associations['hasOne'][$i]);
630: }
631: }
632: $associations[$type] = array_merge($associations[$type]);
633: }
634: }
635: return $associations;
636: }
637:
638: 639: 640: 641: 642: 643: 644:
645: function doMoreAssociations($model, $associations) {
646: $prompt = __('Would you like to define some additional model associations?', true);
647: $wannaDoMoreAssoc = $this->in($prompt, array('y','n'), 'n');
648: $possibleKeys = $this->_generatePossibleKeys();
649: while (strtolower($wannaDoMoreAssoc) == 'y') {
650: $assocs = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
651: $this->out(__('What is the association type?', true));
652: $assocType = intval($this->inOptions($assocs, __('Enter a number',true)));
653:
654: $this->out(__("For the following options be very careful to match your setup exactly.\nAny spelling mistakes will cause errors.", true));
655: $this->hr();
656:
657: $alias = $this->in(__('What is the alias for this association?', true));
658: $className = $this->in(sprintf(__('What className will %s use?', true), $alias), null, $alias );
659: $suggestedForeignKey = null;
660:
661: if ($assocType == 0) {
662: $showKeys = $possibleKeys[$model->table];
663: $suggestedForeignKey = $this->_modelKey($alias);
664: } else {
665: $otherTable = Inflector::tableize($className);
666: if (in_array($otherTable, $this->_tables)) {
667: if ($assocType < 3) {
668: $showKeys = $possibleKeys[$otherTable];
669: } else {
670: $showKeys = null;
671: }
672: } else {
673: $otherTable = $this->in(__('What is the table for this model?', true));
674: $showKeys = $possibleKeys[$otherTable];
675: }
676: $suggestedForeignKey = $this->_modelKey($model->name);
677: }
678: if (!empty($showKeys)) {
679: $this->out(__('A helpful List of possible keys', true));
680: $foreignKey = $this->inOptions($showKeys, __('What is the foreignKey?', true));
681: $foreignKey = $showKeys[intval($foreignKey)];
682: }
683: if (!isset($foreignKey)) {
684: $foreignKey = $this->in(__('What is the foreignKey? Specify your own.', true), null, $suggestedForeignKey);
685: }
686: if ($assocType == 3) {
687: $associationForeignKey = $this->in(__('What is the associationForeignKey?', true), null, $this->_modelKey($model->name));
688: $joinTable = $this->in(__('What is the joinTable?', true));
689: }
690: $associations[$assocs[$assocType]] = array_values((array)$associations[$assocs[$assocType]]);
691: $count = count($associations[$assocs[$assocType]]);
692: $i = ($count > 0) ? $count : 0;
693: $associations[$assocs[$assocType]][$i]['alias'] = $alias;
694: $associations[$assocs[$assocType]][$i]['className'] = $className;
695: $associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
696: if ($assocType == 3) {
697: $associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
698: $associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
699: }
700: $wannaDoMoreAssoc = $this->in(__('Define another association?', true), array('y','n'), 'y');
701: }
702: return $associations;
703: }
704:
705: 706: 707: 708: 709:
710: function _generatePossibleKeys() {
711: $possible = array();
712: foreach ($this->_tables as $otherTable) {
713: $tempOtherModel = & new Model(array('table' => $otherTable, 'ds' => $this->connection));
714: $modelFieldsTemp = $tempOtherModel->schema(true);
715: foreach ($modelFieldsTemp as $fieldName => $field) {
716: if ($field['type'] == 'integer' || $field['type'] == 'string') {
717: $possible[$otherTable][] = $fieldName;
718: }
719: }
720: }
721: return $possible;
722: }
723:
724: 725: 726: 727: 728: 729: 730:
731: function bake($name, $data = array()) {
732: if (is_object($name)) {
733: if ($data == false) {
734: $data = $associations = array();
735: $data['associations'] = $this->doAssociations($name, $associations);
736: $data['validate'] = $this->doValidation($name);
737: }
738: $data['primaryKey'] = $name->primaryKey;
739: $data['useTable'] = $name->table;
740: $data['useDbConfig'] = $name->useDbConfig;
741: $data['name'] = $name = $name->name;
742: } else {
743: $data['name'] = $name;
744: }
745: $defaults = array('associations' => array(), 'validate' => array(), 'primaryKey' => 'id',
746: 'useTable' => null, 'useDbConfig' => 'default', 'displayField' => null);
747: $data = array_merge($defaults, $data);
748:
749: $this->Template->set($data);
750: $this->Template->set('plugin', Inflector::camelize($this->plugin));
751: $out = $this->Template->generate('classes', 'model');
752:
753: $path = $this->getPath();
754: $filename = $path . Inflector::underscore($name) . '.php';
755: $this->out("\nBaking model class for $name...");
756: $this->createFile($filename, $out);
757: ClassRegistry::flush();
758: return $out;
759: }
760:
761: 762: 763: 764: 765: 766:
767: function bakeTest($className) {
768: $this->Test->interactive = $this->interactive;
769: $this->Test->plugin = $this->plugin;
770: $this->Test->connection = $this->connection;
771: return $this->Test->bake('Model', $className);
772: }
773:
774: 775: 776: 777: 778: 779:
780: function listAll($useDbConfig = null) {
781: $this->_tables = $this->getAllTables($useDbConfig);
782:
783: if ($this->interactive === true) {
784: $this->out(__('Possible Models based on your current database:', true));
785: $this->_modelNames = array();
786: $count = count($this->_tables);
787: for ($i = 0; $i < $count; $i++) {
788: $this->_modelNames[] = $this->_modelName($this->_tables[$i]);
789: $this->out($i + 1 . ". " . $this->_modelNames[$i]);
790: }
791: }
792: return $this->_tables;
793: }
794:
795: 796: 797: 798: 799: 800: 801:
802: function getTable($modelName, $useDbConfig = null) {
803: if (!isset($useDbConfig)) {
804: $useDbConfig = $this->connection;
805: }
806: App::import('Model', 'ConnectionManager', false);
807:
808: $db =& ConnectionManager::getDataSource($useDbConfig);
809: $useTable = Inflector::tableize($modelName);
810: $fullTableName = $db->fullTableName($useTable, false);
811: $tableIsGood = false;
812:
813: if (array_search($useTable, $this->_tables) === false) {
814: $this->out();
815: $this->out(sprintf(__("Given your model named '%s',\nCake would expect a database table named '%s'", true), $modelName, $fullTableName));
816: $tableIsGood = $this->in(__('Do you want to use this table?', true), array('y','n'), 'y');
817: }
818: if (strtolower($tableIsGood) == 'n') {
819: $useTable = $this->in(__('What is the name of the table?', true));
820: }
821: return $useTable;
822: }
823:
824: 825: 826: 827: 828: 829: 830:
831: function getAllTables($useDbConfig = null) {
832: if (!isset($useDbConfig)) {
833: $useDbConfig = $this->connection;
834: }
835: App::import('Model', 'ConnectionManager', false);
836:
837: $tables = array();
838: $db =& ConnectionManager::getDataSource($useDbConfig);
839: $db->cacheSources = false;
840: $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
841: if ($usePrefix) {
842: foreach ($db->listSources() as $table) {
843: if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
844: $tables[] = substr($table, strlen($usePrefix));
845: }
846: }
847: } else {
848: $tables = $db->listSources();
849: }
850: if (empty($tables)) {
851: $this->err(__('Your database does not have any tables.', true));
852: $this->_stop();
853: }
854: return $tables;
855: }
856:
857: 858: 859: 860: 861: 862:
863: function getName($useDbConfig = null) {
864: $this->listAll($useDbConfig);
865:
866: $enteredModel = '';
867:
868: while ($enteredModel == '') {
869: $enteredModel = $this->in(__("Enter a number from the list above,\ntype in the name of another model, or 'q' to exit", true), null, 'q');
870:
871: if ($enteredModel === 'q') {
872: $this->out(__("Exit", true));
873: $this->_stop();
874: }
875:
876: if ($enteredModel == '' || intval($enteredModel) > count($this->_modelNames)) {
877: $this->err(__("The model name you supplied was empty,\nor the number you selected was not an option. Please try again.", true));
878: $enteredModel = '';
879: }
880: }
881: if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->_modelNames)) {
882: $currentModelName = $this->_modelNames[intval($enteredModel) - 1];
883: } else {
884: $currentModelName = $enteredModel;
885: }
886: return $currentModelName;
887: }
888:
889: 890: 891: 892: 893:
894: function help() {
895: $this->hr();
896: $this->out("Usage: cake bake model <arg1>");
897: $this->hr();
898: $this->out('Arguments:');
899: $this->out();
900: $this->out("<name>");
901: $this->out("\tName of the model to bake. Can use Plugin.name");
902: $this->out("\tas a shortcut for plugin baking.");
903: $this->out();
904: $this->out('Params:');
905: $this->out();
906: $this->out('-connection <config>');
907: $this->out("\tset db config <config>. uses 'default' if none is specified");
908: $this->out();
909: $this->out('Commands:');
910: $this->out();
911: $this->out("model");
912: $this->out("\tbakes model in interactive mode.");
913: $this->out();
914: $this->out("model <name>");
915: $this->out("\tbakes model file with no associations or validation");
916: $this->out();
917: $this->out("model all");
918: $this->out("\tbakes all model files with associations and validation");
919: $this->out();
920: $this->_stop();
921: }
922:
923: 924: 925: 926: 927: 928: 929: 930: 931:
932: function bakeFixture($className, $useTable = null) {
933: $this->Fixture->interactive = $this->interactive;
934: $this->Fixture->connection = $this->connection;
935: $this->Fixture->plugin = $this->plugin;
936: $this->Fixture->bake($className, $useTable);
937: }
938: }
939: