bake.php

Go to the documentation of this file.
00001 #!/usr/bin/php -q
00002 <?php
00003 /* SVN FILE: $Id: bake_8php-source.html 675 2008-12-26 00:27:14Z gwoo $ */
00004 /**
00005  * Command-line code generation utility to automate programmer chores.
00006  *
00007  * Bake is CakePHP's code generation script, which can help you kickstart
00008  * application development by writing fully functional skeleton controllers,
00009  * models, and views. Going further, Bake can also write Unit Tests for you.
00010  *
00011  * PHP versions 4 and 5
00012  *
00013  * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
00014  * Copyright 2005-2008, Cake Software Foundation, Inc.
00015  *                              1785 E. Sahara Avenue, Suite 490-204
00016  *                              Las Vegas, Nevada 89104
00017  *
00018  * Licensed under The MIT License
00019  * Redistributions of files must retain the above copyright notice.
00020  *
00021  * @filesource
00022  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00023  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00024  * @package         cake
00025  * @subpackage      cake.cake.scripts.bake
00026  * @since           CakePHP(tm) v 0.10.0.1232
00027  * @version         $Revision: 675 $
00028  * @modifiedby      $LastChangedBy: gwoo $
00029  * @lastmodified    $Date: 2008-12-25 16:27:14 -0800 (Thu, 25 Dec 2008) $
00030  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00031  */
00032     define ('DS', DIRECTORY_SEPARATOR);
00033     if (function_exists('ini_set')) {
00034         ini_set('display_errors', '1');
00035         ini_set('error_reporting', '7');
00036         ini_set('max_execution_time',0);
00037     }
00038 
00039     $app = null;
00040     $root = dirname(dirname(dirname(__FILE__)));
00041     $core = null;
00042     $here = $argv[0];
00043     $help = null;
00044     $project = null;
00045 
00046     for ($i = 1; $i < count($argv); $i += 2) {
00047         switch ($argv[$i]) {
00048             case '-a':
00049             case '-app':
00050                 $app = $argv[$i + 1];
00051             break;
00052             case '-c':
00053             case '-core':
00054                 $core = $argv[$i + 1];
00055             break;
00056             case '-r':
00057             case '-root':
00058                 $root = $argv[$i + 1];
00059             break;
00060             case '-h':
00061             case '-help':
00062                 $help = true;
00063             break;
00064             case '-p':
00065             case '-project':
00066                 $project = true;
00067                 $projectPath = $argv[$i + 1];
00068                 $app = $argv[$i + 1];
00069             break;
00070         }
00071     }
00072 
00073     if (!$app && isset($argv[1])) {
00074         $app = $argv[1];
00075     } elseif (!$app) {
00076         $app = 'app';
00077     }
00078     if (!is_dir($app)) {
00079         $project = true;
00080         $projectPath = $app;
00081 
00082     }
00083     if ($project) {
00084         $app = $projectPath;
00085     }
00086 
00087     $shortPath = str_replace($root, '', $app);
00088     $shortPath = str_replace('..'.DS, '', $shortPath);
00089     $shortPath = str_replace(DS.DS, DS, $shortPath);
00090 
00091     $pathArray = explode(DS, $shortPath);
00092     if (end($pathArray) != '') {
00093         $appDir = array_pop($pathArray);
00094     } else {
00095         array_pop($pathArray);
00096         $appDir = array_pop($pathArray);
00097     }
00098     $rootDir = implode(DS, $pathArray);
00099     $rootDir = str_replace(DS.DS, DS, $rootDir);
00100 
00101     if (!$rootDir) {
00102         $rootDir = $root;
00103         $projectPath = $root.DS.$appDir;
00104     }
00105 
00106     define ('ROOT', $rootDir);
00107     define ('APP_DIR', $appDir);
00108     define ('DEBUG', 1);
00109 
00110     if (!empty($core)) {
00111         define('CAKE_CORE_INCLUDE_PATH', dirname($core));
00112     } else {
00113         define('CAKE_CORE_INCLUDE_PATH', $root);
00114     }
00115 
00116     if (function_exists('ini_set')) {
00117         ini_set('include_path',ini_get('include_path').
00118                                                     PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.DS.
00119                                                     PATH_SEPARATOR.ROOT.DS.APP_DIR.DS);
00120         define('APP_PATH', null);
00121         define('CORE_PATH', null);
00122     } else {
00123         define('APP_PATH', ROOT . DS . APP_DIR . DS);
00124         define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
00125     }
00126 
00127     require_once (CORE_PATH.'cake'.DS.'basics.php');
00128     require_once (CORE_PATH.'cake'.DS.'config'.DS.'paths.php');
00129     require_once (CORE_PATH.'cake'.DS.'scripts'.DS.'templates'.DS.'skel'.DS.'config'.DS.'core.php');
00130     require_once (CORE_PATH.'cake'.DS.'dispatcher.php');
00131     uses('object', 'session', 'security', 'configure', 'inflector', 'model'.DS.'connection_manager');
00132 
00133     $pattyCake = new Bake();
00134     if ($help === true)
00135     {
00136         $pattyCake->help();
00137         exit();
00138     }
00139     if ($project === true)
00140     {
00141         $pattyCake->project($projectPath);
00142         exit();
00143     }
00144     $pattyCake->main();
00145 /**
00146  * Bake is a command-line code generation utility for automating programmer chores.
00147  *
00148  * @package     cake
00149  * @subpackage  cake.cake.scripts
00150  */
00151 class Bake {
00152 
00153 /**
00154  * Standard input stream.
00155  *
00156  * @var filehandle
00157  */
00158     var $stdin;
00159 /**
00160  * Standard output stream.
00161  *
00162  * @var filehandle
00163  */
00164     var $stdout;
00165 /**
00166  * Standard error stream.
00167  *
00168  * @var filehandle
00169  */
00170     var $stderr;
00171 /**
00172  * Associated controller name.
00173  *
00174  * @var string
00175  */
00176     var $controllerName = null;
00177 /**
00178  * If true, Bake will ask for permission to perform actions.
00179  *
00180  * @var boolean
00181  */
00182     var $interactive = false;
00183 
00184     var $__modelAlias = false;
00185 /**
00186  * Private helper function for constructor
00187  * @access private
00188  */
00189     function __construct() {
00190         $this->stdin = fopen('php://stdin', 'r');
00191         $this->stdout = fopen('php://stdout', 'w');
00192         $this->stderr = fopen('php://stderr', 'w');
00193         $this->welcome();
00194     }
00195 /**
00196  * Constructor.
00197  *
00198  * @return Bake
00199  */
00200     function Bake() {
00201         return $this->__construct();
00202     }
00203 /**
00204  * Main-loop method.
00205  *
00206  */
00207     function main() {
00208 
00209         $this->stdout('');
00210         $this->stdout('');
00211         $this->stdout('Baking...');
00212         $this->hr();
00213         $this->stdout('Name: '. APP_DIR);
00214         $this->stdout('Path: '. ROOT.DS.APP_DIR);
00215         $this->hr();
00216 
00217         if (!file_exists(CONFIGS.'database.php')) {
00218             $this->stdout('');
00219             $this->stdout('Your database configuration was not found. Take a moment to create one:');
00220             $this->doDbConfig();
00221         }
00222         require_once (CONFIGS.'database.php');
00223         $this->stdout('[M]odel');
00224         $this->stdout('[C]ontroller');
00225         $this->stdout('[V]iew');
00226         $invalidSelection = true;
00227 
00228         while ($invalidSelection) {
00229             $classToBake = strtoupper($this->getInput('What would you like to Bake?', array('M', 'V', 'C')));
00230             switch($classToBake) {
00231                 case 'M':
00232                     $invalidSelection = false;
00233                     $this->doModel();
00234                     break;
00235                 case 'V':
00236                     $invalidSelection = false;
00237                     $this->doView();
00238                     break;
00239                 case 'C':
00240                     $invalidSelection = false;
00241                     $this->doController();
00242                     break;
00243                 default:
00244                     $this->stdout('You have made an invalid selection. Please choose a type of class to Bake by entering M, V, or C.');
00245             }
00246         }
00247     }
00248 /**
00249  * Database configuration setup.
00250  *
00251  */
00252     function doDbConfig() {
00253         $this->hr();
00254         $this->stdout('Database Configuration:');
00255         $this->hr();
00256 
00257         $driver = '';
00258 
00259         while ($driver == '') {
00260             $driver = $this->getInput('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc'), 'mysql');
00261             if ($driver == '') {
00262                 $this->stdout('The database driver supplied was empty. Please supply a database driver.');
00263             }
00264         }
00265 
00266         switch($driver) {
00267             case 'mysql':
00268             $connect = 'mysql_connect';
00269             break;
00270             case 'mysqli':
00271             $connect = 'mysqli_connect';
00272             break;
00273             case 'mssql':
00274             $connect = 'mssql_connect';
00275             break;
00276             case 'sqlite':
00277             $connect = 'sqlite_open';
00278             break;
00279             case 'postgres':
00280             $connect = 'pg_connect';
00281             break;
00282             case 'odbc':
00283             $connect = 'odbc_connect';
00284             break;
00285             default:
00286             $this->stdout('The connection parameter could not be set.');
00287             break;
00288         }
00289 
00290         $host = '';
00291 
00292         while ($host == '') {
00293             $host = $this->getInput('What is the hostname for the database server?', null, 'localhost');
00294             if ($host == '') {
00295                 $this->stdout('The host name you supplied was empty. Please supply a hostname.');
00296             }
00297         }
00298         $login = '';
00299 
00300         while ($login == '') {
00301             $login = $this->getInput('What is the database username?', null, 'root');
00302 
00303             if ($login == '') {
00304                 $this->stdout('The database username you supplied was empty. Please try again.');
00305             }
00306         }
00307         $password = '';
00308         $blankPassword = false;
00309 
00310         while ($password == '' && $blankPassword == false) {
00311             $password = $this->getInput('What is the database password?');
00312             if ($password == '') {
00313                 $blank = $this->getInput('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
00314                 if ($blank == 'y')
00315                 {
00316                     $blankPassword = true;
00317                 }
00318             }
00319         }
00320         $database = '';
00321 
00322         while ($database == '') {
00323             $database = $this->getInput('What is the name of the database you will be using?', null, 'cake');
00324 
00325             if ($database == '')  {
00326                 $this->stdout('The database name you supplied was empty. Please try again.');
00327             }
00328         }
00329 
00330         $prefix = '';
00331 
00332         while ($prefix == '') {
00333             $prefix = $this->getInput('Enter a table prefix?', null, 'n');
00334         }
00335         if (low($prefix) == 'n') {
00336             $prefix = '';
00337         }
00338 
00339         $this->stdout('');
00340         $this->hr();
00341         $this->stdout('The following database configuration will be created:');
00342         $this->hr();
00343         $this->stdout("Driver:        $driver");
00344         $this->stdout("Connection:    $connect");
00345         $this->stdout("Host:          $host");
00346         $this->stdout("User:          $login");
00347         $this->stdout("Pass:          " . str_repeat('*', strlen($password)));
00348         $this->stdout("Database:      $database");
00349         $this->stdout("Table prefix:  $prefix");
00350         $this->hr();
00351         $looksGood = $this->getInput('Look okay?', array('y', 'n'), 'y');
00352 
00353         if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
00354             $this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
00355         } else {
00356             $this->stdout('Bake Aborted.');
00357         }
00358     }
00359 /**
00360  * Action to create a Model.
00361  *
00362  */
00363     function doModel()
00364     {
00365         $this->hr();
00366         $this->stdout('Model Bake:');
00367         $this->hr();
00368         $this->interactive = true;
00369 
00370         $useTable = null;
00371         $primaryKey = 'id';
00372         $validate = array();
00373         $associations = array();
00374         $useDbConfig = 'default';
00375         $this->__doList($useDbConfig);
00376 
00377 
00378         $enteredModel = '';
00379 
00380         while ($enteredModel == '') {
00381             $enteredModel = $this->getInput('Enter a number from the list above, or type in the name of another model.');
00382 
00383             if ($enteredModel == '' || intval($enteredModel) > count($this->__modelNames)) {
00384                 $this->stdout('Error:');
00385                 $this->stdout("The model name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
00386                 $enteredModel = '';
00387             }
00388         }
00389 
00390         if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->__modelNames)) {
00391             $currentModelName = $this->__modelNames[intval($enteredModel) - 1];
00392         } else {
00393             $currentModelName = $enteredModel;
00394         }
00395 
00396         $db =& ConnectionManager::getDataSource($useDbConfig);
00397 
00398         $useTable = Inflector::tableize($currentModelName);
00399         $fullTableName = $db->fullTableName($useTable, false);
00400         if (array_search($useTable, $this->__tables) === false) {
00401             $this->stdout("\nGiven your model named '$currentModelName', Cake would expect a database table named '" . $fullTableName . "'.");
00402             $tableIsGood = $this->getInput('do you want to use this table?', array('y','n'), 'y');
00403         }
00404 
00405         if (low($tableIsGood) == 'n' || low($tableIsGood) == 'no') {
00406             $useTable = $this->getInput('What is the name of the table (enter "null" to use NO table)?');
00407         }
00408         $tableIsGood = false;
00409         while ($tableIsGood == false && low($useTable) != 'null') {
00410             if (is_array($this->__tables) && !in_array($useTable, $this->__tables)) {
00411                 $fullTableName = $db->fullTableName($useTable, false);
00412                 $this->stdout($fullTableName . ' does not exist.');
00413                 $useTable = $this->getInput('What is the name of the table (enter "null" to use NO table)?');
00414                 $tableIsGood = false;
00415             } else {
00416                 $tableIsGood = true;
00417             }
00418         }
00419         $wannaDoValidation = $this->getInput('Would you like to supply validation criteria for the fields in your model?', array('y','n'), 'y');
00420 
00421         if (in_array($useTable, $this->__tables)) {
00422             loadModel();
00423             $tempModel = new Model(false, $useTable);
00424             $modelFields = $db->describe($tempModel);
00425 
00426             if (!array_key_exists('id', $modelFields)) {
00427                 foreach ($modelFields as $name => $field) {
00428                     break;
00429                 }
00430                 $primaryKey = $this->getInput('What is the primaryKey?', null, $name);
00431             }
00432         }
00433         $validate = array();
00434 
00435         if (array_search($useTable, $this->__tables) !== false && (low($wannaDoValidation) == 'y' || low($wannaDoValidation) == 'yes')) {
00436             foreach ($modelFields as $name => $field) {
00437                 $this->stdout('');
00438                 $prompt = 'Name: ' . $name . "\n";
00439                 $prompt .= 'Type: ' . $field['type'] . "\n";
00440                 $prompt .= '---------------------------------------------------------------'."\n";
00441                 $prompt .= 'Please select one of the following validation options:'."\n";
00442                 $prompt .= '---------------------------------------------------------------'."\n";
00443                 $prompt .= "1- VALID_NOT_EMPTY\n";
00444                 $prompt .= "2- VALID_EMAIL\n";
00445                 $prompt .= "3- VALID_NUMBER\n";
00446                 $prompt .= "4- VALID_YEAR\n";
00447                 $prompt .= "5- Do not do any validation on this field.\n\n";
00448                 $prompt .= "... or enter in a valid regex validation string.\n\n";
00449 
00450                 if ($field['null'] == 1 || $name == $primaryKey || $name == 'created' || $name == 'modified') {
00451                     $validation = $this->getInput($prompt, null, '5');
00452                 } else {
00453                     $validation = $this->getInput($prompt, null, '1');
00454                 }
00455 
00456                 switch ($validation) {
00457                     case '1':
00458                         $validate[$name] = 'VALID_NOT_EMPTY';
00459                         break;
00460                     case '2':
00461                         $validate[$name] = 'VALID_EMAIL';
00462                         break;
00463                     case '3':
00464                         $validate[$name] = 'VALID_NUMBER';
00465                         break;
00466                     case '4':
00467                         $validate[$name] = 'VALID_YEAR';
00468                         break;
00469                     case '5':
00470                         break;
00471                     default:
00472                         $validate[$name] = $validation;
00473                     break;
00474                 }
00475             }
00476         }
00477 
00478         $wannaDoAssoc = $this->getInput('Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)?', array('y','n'), 'y');
00479 
00480         if ((low($wannaDoAssoc) == 'y' || low($wannaDoAssoc) == 'yes')) {
00481             $this->stdout('One moment while I try to detect any associations...');
00482             $possibleKeys = array();
00483             $i = 0;
00484             foreach ($modelFields as $name => $field) {
00485                 $offset = strpos($name, '_id');
00486                 if ($name != $primaryKey && $offset !== false) {
00487                     $tmpModelName = $this->__modelNameFromKey($name);
00488                     $associations['belongsTo'][$i]['alias'] = $tmpModelName;
00489                     $associations['belongsTo'][$i]['className'] = $tmpModelName;
00490                     $associations['belongsTo'][$i]['foreignKey'] = $name;
00491                     $i++;
00492                 }
00493             }
00494             $i = 0;
00495             $j = 0;
00496             foreach ($this->__tables as $otherTable) {
00497                 $tempOtherModel = & new Model(false, $otherTable);
00498                 $modelFieldsTemp = $db->describe($tempOtherModel);
00499                 foreach ($modelFieldsTemp as $name => $field) {
00500                     if ($field['type'] == 'integer' || $field['type'] == 'string') {
00501                         $possibleKeys[$otherTable][] = $name;
00502                     }
00503                     if ($name != $primaryKey && $name == $this->__modelKey($currentModelName)) {
00504                         $tmpModelName = $this->__modelName($otherTable);
00505                         $associations['hasOne'][$j]['alias'] = $tmpModelName;
00506                         $associations['hasOne'][$j]['className'] = $tmpModelName;
00507                         $associations['hasOne'][$j]['foreignKey'] = $name;
00508 
00509                         $associations['hasMany'][$j]['alias'] = $tmpModelName;
00510                         $associations['hasMany'][$j]['className'] = $tmpModelName;
00511                         $associations['hasMany'][$j]['foreignKey'] = $name;
00512                         $j++;
00513                     }
00514                 }
00515                 $offset = strpos($otherTable, $useTable . '_');
00516                 if ($offset !== false) {
00517                     $offset = strlen($useTable . '_');
00518                     $tmpModelName = $this->__modelName(substr($otherTable, $offset));
00519                     $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
00520                     $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
00521                     $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
00522                     $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
00523                     $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
00524                     $i++;
00525                 }
00526                 $offset = strpos($otherTable, '_' . $useTable);
00527                 if ($offset !== false) {
00528                     $tmpModelName = $this->__modelName(substr($otherTable, 0, $offset));
00529                     $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
00530                     $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
00531                     $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
00532                     $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
00533                     $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
00534                     $i++;
00535                 }
00536             }
00537             $this->stdout('Done.');
00538             $this->hr();
00539             if (empty($associations)) {
00540                 $this->stdout('None found.');
00541             } else {
00542                 $this->stdout('Please confirm the following associations:');
00543                 $this->hr();
00544                 if (!empty($associations['belongsTo'])) {
00545                     $count = count($associations['belongsTo']);
00546                     for ($i = 0; $i < $count; $i++) {
00547                         if ($currentModelName == $associations['belongsTo'][$i]['alias']) {
00548                             $response = $this->getInput("{$currentModelName} belongsTo {$associations['belongsTo'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
00549                             if ('y' == low($response) || 'yes' == low($response)) {
00550                                 $associations['belongsTo'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['belongsTo'][$i]['alias']);
00551                             }
00552                             if ($currentModelName != $associations['belongsTo'][$i]['alias']) {
00553                                 $response = $this->getInput("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
00554                             } else {
00555                                 $response = 'n';
00556                             }
00557                         } else {
00558                             $response = $this->getInput("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
00559                         }
00560                         if ('n' == low($response) || 'no' == low($response)) {
00561                             unset($associations['belongsTo'][$i]);
00562                         }
00563                     }
00564                     $associations['belongsTo'] = array_merge($associations['belongsTo']);
00565                 }
00566 
00567                 if (!empty($associations['hasOne'])) {
00568                     $count = count($associations['hasOne']);
00569                     for ($i = 0; $i < $count; $i++) {
00570                         if ($currentModelName == $associations['hasOne'][$i]['alias']) {
00571                             $response = $this->getInput("{$currentModelName} hasOne {$associations['hasOne'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
00572                             if ('y' == low($response) || 'yes' == low($response)) {
00573                                 $associations['hasOne'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasOne'][$i]['alias']);
00574                             }
00575                             if ($currentModelName != $associations['hasOne'][$i]['alias']) {
00576                                 $response = $this->getInput("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
00577                             } else {
00578                                 $response = 'n';
00579                             }
00580                         } else {
00581                             $response = $this->getInput("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
00582                         }
00583                         if ('n' == low($response) || 'no' == low($response)) {
00584                             unset($associations['hasOne'][$i]);
00585                         }
00586                     }
00587                     $associations['hasOne'] = array_merge($associations['hasOne']);
00588                 }
00589 
00590                 if (!empty($associations['hasMany'])) {
00591                     $count = count($associations['hasMany']);
00592                     for ($i = 0; $i < $count; $i++) {
00593                         if ($currentModelName == $associations['hasMany'][$i]['alias']) {
00594                             $response = $this->getInput("{$currentModelName} hasMany {$associations['hasMany'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
00595                             if ('y' == low($response) || 'yes' == low($response)) {
00596                                 $associations['hasMany'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasMany'][$i]['alias']);
00597                             }
00598                             if ($currentModelName != $associations['hasMany'][$i]['alias']) {
00599                                 $response = $this->getInput("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
00600                             } else {
00601                                 $response = 'n';
00602                             }
00603                         } else {
00604                             $response = $this->getInput("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
00605                         }
00606                         if ('n' == low($response) || 'no' == low($response)) {
00607                             unset($associations['hasMany'][$i]);
00608                         }
00609                     }
00610                     $associations['hasMany'] = array_merge($associations['hasMany']);
00611                 }
00612 
00613                 if (!empty($associations['hasAndBelongsToMany'])) {
00614                     $count = count($associations['hasAndBelongsToMany']);
00615                     for ($i = 0; $i < $count; $i++) {
00616                         if ($currentModelName == $associations['hasAndBelongsToMany'][$i]['alias']) {
00617                             $response = $this->getInput("{$currentModelName} hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
00618                             if ('y' == low($response) || 'yes' == low($response)) {
00619                                 $associations['hasAndBelongsToMany'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasAndBelongsToMany'][$i]['alias']);
00620                             }
00621                             if ($currentModelName != $associations['hasAndBelongsToMany'][$i]['alias']) {
00622                                 $response = $this->getInput("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
00623                             } else {
00624                                 $response = 'n';
00625                             }
00626                         } else {
00627                             $response = $this->getInput("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
00628                         }
00629                         if ('n' == low($response) || 'no' == low($response)) {
00630                             unset($associations['hasAndBelongsToMany'][$i]);
00631                         }
00632                     }
00633                     $associations['hasAndBelongsToMany'] = array_merge($associations['hasAndBelongsToMany']);
00634                 }
00635             }
00636             $wannaDoMoreAssoc = $this->getInput('Would you like to define some additional model associations?', array('y','n'), 'y');
00637 
00638             while ((low($wannaDoMoreAssoc) == 'y' || low($wannaDoMoreAssoc) == 'yes')) {
00639                 $assocs = array(1=>'belongsTo', 2=>'hasOne', 3=>'hasMany', 4=>'hasAndBelongsToMany');
00640                 $bad = true;
00641                 while ($bad) {
00642                     $this->stdout('What is the association type?');
00643                     $prompt = "1- belongsTo\n";
00644                     $prompt .= "2- hasOne\n";
00645                     $prompt .= "3- hasMany\n";
00646                     $prompt .= "4- hasAndBelongsToMany\n";
00647                     $assocType = intval($this->getInput($prompt, null, null));
00648 
00649                     if (intval($assocType) < 1 || intval($assocType) > 4) {
00650                         $this->stdout('The selection you entered was invalid. Please enter a number between 1 and 4.');
00651                     } else {
00652                         $bad = false;
00653                     }
00654                 }
00655                 $this->stdout('For the following options be very careful to match your setup exactly. Any spelling mistakes will cause errors.');
00656                 $this->hr();
00657                 $associationName = $this->getInput('What is the name of this association?');
00658                 $className = $this->getInput('What className will '.$associationName.' use?', null, $associationName );
00659                 $suggestedForeignKey = null;
00660                 if ($assocType == '1') {
00661                     $showKeys = $possibleKeys[$useTable];
00662                     $suggestedForeignKey = $this->__modelKey($associationName);
00663                 } else {
00664                     $otherTable = Inflector::tableize($className);
00665                     if (in_array($otherTable, $this->__tables)) {
00666                         if ($assocType < '4') {
00667                             $showKeys = $possibleKeys[$otherTable];
00668                         } else {
00669                             $showKeys = null;
00670                         }
00671                     } else {
00672                         $otherTable = $this->getInput('What is the table for this class?');
00673                         $showKeys = $possibleKeys[$otherTable];
00674                     }
00675                     $suggestedForeignKey = $this->__modelKey($currentModelName);
00676                 }
00677                 if (!empty($showKeys)) {
00678                     $this->stdout('A helpful List of possible keys');
00679                     for ($i = 0; $i < count($showKeys); $i++) {
00680                         $this->stdout($i + 1 . ". " . $showKeys[$i]);
00681                     }
00682                     $foreignKey = $this->getInput('What is the foreignKey? Choose a number.');
00683                     if (intval($foreignKey) > 0 && intval($foreignKey) <= $i ) {
00684                         $foreignKey = $showKeys[intval($foreignKey) - 1];
00685                     }
00686                 }
00687                 if (!isset($foreignKey)) {
00688                     $foreignKey = $this->getInput('What is the foreignKey? Specify your own.', null, $suggestedForeignKey);
00689                 }
00690                 if ($assocType == '4') {
00691                     $associationForeignKey = $this->getInput('What is the associationForeignKey?', null, $this->__modelKey($currentModelName));
00692                     $joinTable = $this->getInput('What is the joinTable?');
00693                 }
00694                 $associations[$assocs[$assocType]] = array_values($associations[$assocs[$assocType]]);
00695                 $count = count($associations[$assocs[$assocType]]);
00696                 $i = ($count > 0) ? $count : 0;
00697                 $associations[$assocs[$assocType]][$i]['alias'] = $associationName;
00698                 $associations[$assocs[$assocType]][$i]['className'] = $className;
00699                 $associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
00700                 if ($assocType == '4') {
00701                     $associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
00702                     $associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
00703                 }
00704                 $wannaDoMoreAssoc = $this->getInput('Define another association?', array('y','n'), 'y');
00705             }
00706         }
00707         $this->stdout('');
00708         $this->hr();
00709         $this->stdout('The following model will be created:');
00710         $this->hr();
00711         $this->stdout("Model Name:    $currentModelName");
00712         $this->stdout("DB Connection: " . ($usingDefault ? 'default' : $useDbConfig));
00713         $this->stdout("DB Table:   " . $fullTableName);
00714         if ($primaryKey != 'id') {
00715             $this->stdout("Primary Key:   " . $primaryKey);
00716         }
00717         $this->stdout("Validation:    " . print_r($validate, true));
00718 
00719         if (!empty($associations)) {
00720             $this->stdout("Associations:");
00721 
00722             if (count($associations['belongsTo'])) {
00723                 for ($i = 0; $i < count($associations['belongsTo']); $i++) {
00724                     $this->stdout("            $currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}");
00725                 }
00726             }
00727 
00728             if (count($associations['hasOne'])) {
00729                 for ($i = 0; $i < count($associations['hasOne']); $i++) {
00730                     $this->stdout("            $currentModelName hasOne {$associations['hasOne'][$i]['alias']}");
00731                 }
00732             }
00733 
00734             if (count($associations['hasMany'])) {
00735                 for ($i = 0; $i < count($associations['hasMany']); $i++) {
00736                     $this->stdout("            $currentModelName hasMany   {$associations['hasMany'][$i]['alias']}");
00737                 }
00738             }
00739 
00740             if (count($associations['hasAndBelongsToMany'])) {
00741                 for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
00742                     $this->stdout("            $currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}");
00743                 }
00744             }
00745         }
00746         $this->hr();
00747         $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
00748 
00749         if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
00750             if ($useTable == Inflector::tableize($currentModelName)) {
00751                 $useTable = null;
00752             }
00753             $this->bakeModel($currentModelName, $useDbConfig, $useTable, $primaryKey, $validate, $associations);
00754 
00755             if ($this->doUnitTest()) {
00756                 $this->bakeUnitTest('model', $currentModelName);
00757             }
00758         } else {
00759             $this->stdout('Bake Aborted.');
00760         }
00761     }
00762 /**
00763  * Action to create a View.
00764  *
00765  */
00766     function doView() {
00767         $this->hr();
00768         $this->stdout('View Bake:');
00769         $this->hr();
00770         $uses = array();
00771         $wannaUseSession = 'y';
00772         $wannaDoScaffold = 'y';
00773 
00774 
00775         $useDbConfig = 'default';
00776         $this->__doList($useDbConfig, 'Controllers');
00777 
00778         $enteredController = '';
00779 
00780         while ($enteredController == '') {
00781             $enteredController = $this->getInput('Enter a number from the list above, or type in the name of another controller.');
00782 
00783             if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
00784                 $this->stdout('Error:');
00785                 $this->stdout("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
00786                 $enteredController = '';
00787             }
00788         }
00789 
00790         if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
00791             $controllerName = $this->__controllerNames[intval($enteredController) - 1];
00792         } else {
00793             $controllerName = Inflector::camelize($enteredController);
00794         }
00795 
00796         $controllerPath = low(Inflector::underscore($controllerName));
00797 
00798         $doItInteractive = $this->getInput("Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite {$controllerClassName} views if it exist.", array('y','n'), 'y');
00799 
00800         if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
00801             $this->interactive = true;
00802             $wannaDoScaffold = $this->getInput("Would you like to create some scaffolded views (index, add, view, edit) for this controller?\nNOTE: Before doing so, you'll need to create your controller and model classes (including associated models).", array('y','n'), 'n');
00803         }
00804 
00805         $admin = null;
00806         $admin_url = null;
00807         if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
00808             $wannaDoAdmin = $this->getInput("Would you like to create the views for admin routing?", array('y','n'), 'n');
00809         }
00810 
00811         if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
00812             require(CONFIGS.'core.php');
00813             if (defined('CAKE_ADMIN')) {
00814                 $admin = CAKE_ADMIN . '_';
00815                 $admin_url = '/'.CAKE_ADMIN;
00816             } else {
00817                 $adminRoute = '';
00818                 $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
00819                 $this->stdout('What would you like the admin route to be?');
00820                 $this->stdout('Example: www.example.com/admin/controller');
00821                 while ($adminRoute == '') {
00822                     $adminRoute = $this->getInput("What would you like the admin route to be?", null, 'admin');
00823                 }
00824                 if ($this->__addAdminRoute($adminRoute) !== true) {
00825                     $this->stdout('Unable to write to /app/config/core.php.');
00826                     $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
00827                     exit();
00828                 } else {
00829                     $admin = $adminRoute . '_';
00830                     $admin_url = '/'.$adminRoute;
00831                 }
00832             }
00833         }
00834         if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
00835             $file = CONTROLLERS . $controllerPath . '_controller.php';
00836 
00837             if (!file_exists($file)) {
00838                 $shortPath = str_replace(ROOT, null, $file);
00839                 $shortPath = str_replace('../', '', $shortPath);
00840                 $shortPath = str_replace('//', '/', $shortPath);
00841                 $this->stdout('');
00842                 $this->stdout("The file '$shortPath' could not be found.\nIn order to scaffold, you'll need to first create the controller. ");
00843                 $this->stdout('');
00844                 die();
00845             } else {
00846                 uses('controller'.DS.'controller');
00847                 loadController($controllerName);
00848                 if ($admin) {
00849                     $this->__bakeViews($controllerName, $controllerPath, $admin, $admin_url);
00850                 }
00851                 $this->__bakeViews($controllerName, $controllerPath, null, null);
00852 
00853                 $this->hr();
00854                 $this->stdout('');
00855                 $this->stdout('View Scaffolding Complete.'."\n");
00856             }
00857         } else {
00858             $actionName = '';
00859 
00860             while ($actionName == '') {
00861                 $actionName = $this->getInput('Action Name? (use camelCased function name)');
00862 
00863                 if ($actionName == '') {
00864                     $this->stdout('The action name you supplied was empty. Please try again.');
00865                 }
00866             }
00867             $this->stdout('');
00868             $this->hr();
00869             $this->stdout('The following view will be created:');
00870             $this->hr();
00871             $this->stdout("Controller Name: $controllerName");
00872             $this->stdout("Action Name:     $actionName");
00873             $this->stdout("Path:            app/views/" . $controllerPath . DS . Inflector::underscore($actionName) . '.thtml');
00874             $this->hr();
00875             $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
00876 
00877             if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
00878                 $this->bakeView($controllerName, $actionName);
00879             } else {
00880                 $this->stdout('Bake Aborted.');
00881             }
00882         }
00883     }
00884 
00885     function __bakeViews($controllerName, $controllerPath, $admin= null, $admin_url = null) {
00886         $controllerClassName = $controllerName.'Controller';
00887         $controllerObj = & new $controllerClassName();
00888 
00889         if (!in_array('Html', $controllerObj->helpers)) {
00890             $controllerObj->helpers[] = 'Html';
00891         }
00892         if (!in_array('Form', $controllerObj->helpers)) {
00893             $controllerObj->helpers[] = 'Form';
00894         }
00895 
00896         $controllerObj->constructClasses();
00897         $currentModelName = $controllerObj->modelClass;
00898         $this->__modelClass = $currentModelName;
00899         $modelKey = Inflector::underscore($currentModelName);
00900         $modelObj =& ClassRegistry::getObject($modelKey);
00901         $singularName = $this->__singularName($currentModelName);
00902         $pluralName = $this->__pluralName($currentModelName);
00903         $singularHumanName = $this->__singularHumanName($currentModelName);
00904         $pluralHumanName = $this->__pluralHumanName($controllerName);
00905 
00906         $fieldNames = $controllerObj->generateFieldNames(null, false);
00907         $indexView = null;
00908 
00909         if (!empty($modelObj->alias)) {
00910             foreach ($modelObj->alias as $key => $value) {
00911                 $alias[] = $key;
00912             }
00913         }
00914         $indexView .= "<div class=\"{$pluralName}\">\n";
00915         $indexView .= "<h2>List " . $pluralHumanName . "</h2>\n\n";
00916         $indexView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
00917         $indexView .= "<tr>\n";
00918 
00919         foreach ($fieldNames as $fieldName) {
00920             $indexView .= "\t<th>".$fieldName['prompt']."</th>\n";
00921         }
00922         $indexView .= "\t<th>Actions</th>\n";
00923         $indexView .= "</tr>\n";
00924         $indexView .= "<?php foreach (\${$pluralName} as \${$singularName}): ?>\n";
00925         $indexView .= "<tr>\n";
00926         $count = 0;
00927         foreach ($fieldNames as $field => $value) {
00928             if (isset($value['foreignKey'])) {
00929                 $otherModelName = $this->__modelName($value['model']);
00930                 $otherModelKey = Inflector::underscore($otherModelName);
00931                 $otherModelObj =& ClassRegistry::getObject($otherModelKey);
00932                 $otherControllerName = $this->__controllerName($otherModelName);
00933                 $otherControllerPath = $this->__controllerPath($otherControllerName);
00934                 if (is_object($otherModelObj)) {
00935                     $displayField = $otherModelObj->getDisplayField();
00936                     $indexView .= "\t<td>&nbsp;<?php echo \$html->link(\$".$singularName."['{$alias[$count]}']['{$displayField}'], '{$admin_url}/" . $otherControllerPath . "/view/' .\$".$singularName."['{$alias[$count]}']['{$otherModelObj->primaryKey}'])?></td>\n";
00937                 } else {
00938                     $indexView .= "\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
00939                 }
00940                 $count++;
00941             } else {
00942                 $indexView .= "\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
00943             }
00944         }
00945         $indexView .= "\t<td class=\"actions\">\n";
00946         $indexView .= "\t\t<?php echo \$html->link('View','{$admin_url}/{$controllerPath}/view/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
00947         $indexView .= "\t\t<?php echo \$html->link('Edit','{$admin_url}/{$controllerPath}/edit/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
00948         $indexView .= "\t\t<?php echo \$html->link('Delete','{$admin_url}/{$controllerPath}/delete/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'], null, 'Are you sure you want to delete id ' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
00949         $indexView .= "\t</td>\n";
00950         $indexView .= "</tr>\n";
00951         $indexView .= "<?php endforeach; ?>\n";
00952         $indexView .= "</table>\n\n";
00953         $indexView .= "<ul class=\"actions\">\n";
00954         $indexView .= "\t<li><?php echo \$html->link('New {$singularHumanName}', '{$admin_url}/{$controllerPath}/add'); ?></li>\n";
00955         $indexView .= "</ul>\n";
00956         $indexView .= "</div>";
00957         $viewView = null;
00958         $viewView .= "<div class=\"{$singularName}\">\n";
00959         $viewView .= "<h2>View " . $singularHumanName . "</h2>\n\n";
00960         $viewView .= "<dl>\n";
00961         $count = 0;
00962         foreach ($fieldNames as $field => $value) {
00963             $viewView .= "\t<dt>" . $value['prompt'] . "</dt>\n";
00964             if (isset($value['foreignKey'])) {
00965                 $otherModelName = $this->__modelName($value['model']);
00966                 $otherModelKey = Inflector::underscore($otherModelName);
00967                 $otherModelObj =& ClassRegistry::getObject($otherModelKey);
00968                 $otherControllerName = $this->__controllerName($otherModelName);
00969                 $otherControllerPath = $this->__controllerPath($otherControllerName);
00970                 $displayField = $otherModelObj->getDisplayField();
00971                 $viewView .= "\t<dd>&nbsp;<?php echo \$html->link(\$".$singularName."['{$alias[$count]}']['{$displayField}'], '{$admin_url}/" . $otherControllerPath . "/view/' .\$".$singularName."['{$alias[$count]}']['{$otherModelObj->primaryKey}'])?></dd>\n";
00972                 $count++;
00973             } else {
00974                 $viewView .= "\t<dd>&nbsp;<?php echo \$".$singularName."['{$modelObj->name}']['{$field}']?></dd>\n";
00975             }
00976         }
00977         $viewView .= "</dl>\n";
00978         $viewView .= "<ul class=\"actions\">\n";
00979         $viewView .= "\t<li><?php echo \$html->link('Edit " . $singularHumanName . "',   '{$admin_url}/{$controllerPath}/edit/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}']) ?> </li>\n";
00980         $viewView .= "\t<li><?php echo \$html->link('Delete " . $singularHumanName . "', '{$admin_url}/{$controllerPath}/delete/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'], null, 'Are you sure you want to delete: id ' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'] . '?') ?> </li>\n";
00981         $viewView .= "\t<li><?php echo \$html->link('List " . $pluralHumanName ."',   '{$admin_url}/{$controllerPath}/index') ?> </li>\n";
00982         $viewView .= "\t<li><?php echo \$html->link('New " . $singularHumanName . "',   '{$admin_url}/{$controllerPath}/add') ?> </li>\n";
00983         foreach ( $fieldNames as $field => $value ) {
00984             if ( isset( $value['foreignKey'] ) ) {
00985                 $otherModelName = $this->__modelName($value['model']);
00986                 if ($otherModelName != $currentModelName) {
00987                     $otherControllerName = $this->__controllerName($otherModelName);
00988                     $otherControllerPath = $this->__controllerPath($otherControllerName);
00989                     $otherSingularHumanName = $this->__singularHumanName($value['controller']);
00990                     $otherPluralHumanName = $this->__pluralHumanName($value['controller']);
00991                     $viewView .= "\t<li><?php echo \$html->link('List " . $otherSingularHumanName . "', '{$admin_url}/" . $otherControllerPath . "/index/')?> </li>\n";
00992                     $viewView .= "\t<li><?php echo \$html->link('New " . $otherPluralHumanName . "', '{$admin_url}/" . $otherControllerPath . "/add/')?> </li>\n";
00993                 }
00994             }
00995         }
00996         $viewView .= "</ul>\n\n";
00997 
00998         $viewView .= "</div>\n";
00999 
01000 
01001         foreach ($modelObj->hasOne as $associationName => $relation) {
01002             $new = true;
01003 
01004             $otherModelName = $this->__modelName($relation['className']);
01005             $otherControllerName = $this->__controllerName($otherModelName);
01006             $otherControllerPath = $this->__controllerPath($otherControllerName);
01007             $otherSingularName = $this->__singularName($associationName);
01008             $otherPluralHumanName = $this->__pluralHumanName($associationName);
01009             $otherSingularHumanName = $this->__singularHumanName($associationName);
01010 
01011             $viewView .= "<div class=\"related\">\n";
01012             $viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
01013             $viewView .= "<?php if (!empty(\$".$singularName."['{$associationName}'])): ?>\n";
01014             $viewView .= "<dl>\n";
01015             $viewView .= "\t<?php foreach (\$".$singularName."['{$associationName}'] as \$field => \$value): ?>\n";
01016             $viewView .= "\t\t<dt><?php echo \$field ?></dt>\n";
01017             $viewView .= "\t\t<dd>&nbsp;<?php echo \$value ?></dd>\n";
01018             $viewView .= "\t<?php endforeach; ?>\n";
01019             $viewView .= "</dl>\n";
01020             $viewView .= "<?php endif; ?>\n";
01021             $viewView .= "<ul class=\"actions\">\n";
01022             $viewView .= "\t<li><?php echo \$html->link('Edit " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/edit/' . \$".$singularName."['{$associationName}']['" . $modelObj->{$otherModelName}->primaryKey . "']);?></li>\n";
01023             $viewView .= "\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/add/');?> </li>\n";
01024             $viewView .= "</ul>\n";
01025             $viewView .= "</div>\n";
01026         }
01027         $relations = array_merge($modelObj->hasMany, $modelObj->hasAndBelongsToMany);
01028 
01029         foreach ($relations as $associationName => $relation) {
01030             $otherModelName = $this->__modelName($relation['className']);
01031             $otherControllerName = $this->__controllerName($otherModelName);
01032             $otherControllerPath = $this->__controllerPath($otherControllerName);
01033             $otherSingularName = $this->__singularName($associationName);
01034             $otherPluralHumanName = $this->__pluralHumanName($associationName);
01035             $otherSingularHumanName = $this->__singularHumanName($associationName);
01036             $otherModelKey = Inflector::underscore($otherModelName);
01037             $otherModelObj =& ClassRegistry::getObject($otherModelKey);
01038 
01039             $viewView .= "<div class=\"related\">\n";
01040             $viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
01041             $viewView .= "<?php if (!empty(\$".$singularName."['{$associationName}'])):?>\n";
01042             $viewView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
01043             $viewView .= "<tr>\n";
01044             $viewView .= "<?php foreach (\$".$singularName."['{$associationName}']['0'] as \$column => \$value): ?>\n";
01045             $viewView .= "<th><?php echo \$column?></th>\n";
01046             $viewView .= "<?php endforeach; ?>\n";
01047             $viewView .= "<th>Actions</th>\n";
01048             $viewView .= "</tr>\n";
01049             $viewView .= "<?php foreach (\$".$singularName."['{$associationName}'] as \$".$otherSingularName."):?>\n";
01050             $viewView .= "<tr>\n";
01051             $viewView .= "\t<?php foreach (\$".$otherSingularName." as \$column => \$value):?>\n";
01052             $viewView .= "\t\t<td><?php echo \$value;?></td>\n";
01053             $viewView .= "\t<?php endforeach;?>\n";
01054             $viewView .= "\t<td class=\"actions\">\n";
01055             $viewView .= "\t\t<?php echo \$html->link('View', '{$admin_url}/" . $otherControllerPath . "/view/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}']);?>\n";
01056             $viewView .= "\t\t<?php echo \$html->link('Edit', '{$admin_url}/" . $otherControllerPath . "/edit/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}']);?>\n";
01057             $viewView .= "\t\t<?php echo \$html->link('Delete', '{$admin_url}/" . $otherControllerPath . "/delete/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'], null, 'Are you sure you want to delete: id ' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'] . '?');?>\n";
01058             $viewView .= "\t</td>\n";
01059             $viewView .= "</tr>\n";
01060             $viewView .= "<?php endforeach; ?>\n";
01061             $viewView .= "</table>\n";
01062             $viewView .= "<?php endif; ?>\n\n";
01063             $viewView .= "<ul class=\"actions\">\n";
01064             $viewView .= "\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/add/');?> </li>\n";
01065             $viewView .= "</ul>\n";
01066 
01067             $viewView .= "</div>\n";
01068         }
01069         $addView = null;
01070         $addView .= "<h2>New " . $singularHumanName . "</h2>\n";
01071         $addView .= "<form action=\"<?php echo \$html->url('{$admin_url}/{$controllerPath}/add'); ?>\" method=\"post\">\n";
01072         $addView .= $this->generateFields($controllerObj->generateFieldNames(null, true));
01073         $addView .= $this->generateSubmitDiv('Add');
01074         $addView .= "</form>\n";
01075         $addView .= "<ul class=\"actions\">\n";
01076         $addView .= "<li><?php echo \$html->link('List {$pluralHumanName}', '{$admin_url}/{$controllerPath}/index')?></li>\n";
01077         foreach ($modelObj->belongsTo as $associationName => $relation) {
01078             $otherModelName = $this->__modelName($associationName);
01079             if ($otherModelName != $currentModelName) {
01080                 $otherControllerName = $this->__controllerName($otherModelName);
01081                 $otherControllerPath = $this->__controllerPath($otherControllerName);
01082                 $otherSingularName = $this->__singularName($associationName);
01083                 $otherPluralName = $this->__pluralHumanName($associationName);
01084                 $addView .= "<li><?php echo \$html->link('View " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/index/');?></li>\n";
01085                 $addView .= "<li><?php echo \$html->link('Add " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/add/');?></li>\n";
01086             }
01087         }
01088         $addView .= "</ul>\n";
01089         $editView = null;
01090         $editView .= "<h2>Edit " . $singularHumanName . "</h2>\n";
01091         $editView .= "<form action=\"<?php echo \$html->url('{$admin_url}/{$controllerPath}/edit/'.\$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}')); ?>\" method=\"post\">\n";
01092         $editView .= $this->generateFields($controllerObj->generateFieldNames(null, true));
01093         $editView .= "<?php echo \$html->hidden('{$modelObj->name}/{$modelObj->primaryKey}')?>\n";
01094         $editView .= $this->generateSubmitDiv('Save');
01095         $editView .= "</form>\n";
01096         $editView .= "<ul class=\"actions\">\n";
01097         $editView .= "<li><?php echo \$html->link('Delete','{$admin_url}/{$controllerPath}/delete/' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}'), null, 'Are you sure you want to delete: id ' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}'));?>\n";
01098         $editView .= "<li><?php echo \$html->link('List {$pluralHumanName}', '{$admin_url}/{$controllerPath}/index')?></li>\n";
01099         foreach ($modelObj->belongsTo as $associationName => $relation) {
01100             $otherModelName = $this->__modelName($associationName);
01101             if ($otherModelName != $currentModelName) {
01102                 $otherControllerName = $this->__controllerName($otherModelName);
01103                 $otherControllerPath = $this->__controllerPath($otherControllerName);
01104                 $otherSingularName = $this->__singularName($associationName);
01105                 $otherPluralName = $this->__pluralHumanName($associationName);
01106                 $editView .= "<li><?php echo \$html->link('View " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/index/');?></li>\n";
01107                 $editView .= "<li><?php echo \$html->link('Add " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/add/');?></li>\n";
01108             }
01109         }
01110         $editView .= "</ul>\n";
01111 
01112         if (!file_exists(VIEWS.$controllerPath)) {
01113             mkdir(VIEWS.$controllerPath);
01114         }
01115         $filename = VIEWS . $controllerPath . DS .  $admin . 'index.thtml';
01116         $this->__createFile($filename, $indexView);
01117         $filename = VIEWS . $controllerPath . DS . $admin . 'view.thtml';
01118         $this->__createFile($filename, $viewView);
01119         $filename = VIEWS . $controllerPath . DS . $admin . 'add.thtml';
01120         $this->__createFile($filename, $addView);
01121         $filename = VIEWS . $controllerPath . DS . $admin . 'edit.thtml';
01122         $this->__createFile($filename, $editView);
01123     }
01124 /**
01125  * Action to create a Controller.
01126  *
01127  */
01128     function doController() {
01129         $this->hr();
01130         $this->stdout('Controller Bake:');
01131         $this->hr();
01132         $uses = array();
01133         $helpers = array();
01134         $components = array();
01135         $wannaUseSession = 'y';
01136         $wannaDoScaffolding = 'y';
01137 
01138         $useDbConfig = 'default';
01139         $this->__doList($useDbConfig, 'Controllers');
01140 
01141         $enteredController = '';
01142 
01143         while ($enteredController == '') {
01144             $enteredController = $this->getInput('Enter a number from the list above, or type in the name of another controller.');
01145 
01146             if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
01147                 $this->stdout('Error:');
01148                 $this->stdout("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
01149                 $enteredController = '';
01150             }
01151         }
01152 
01153         if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
01154             $controllerName = $this->__controllerNames[intval($enteredController) - 1];
01155         } else {
01156             $controllerName = Inflector::camelize($enteredController);
01157         }
01158 
01159         $controllerPath = low(Inflector::underscore($controllerName));
01160 
01161         $doItInteractive = $this->getInput("Would you like bake to build your controller interactively?\nWarning: Choosing no will overwrite {$controllerClassName} controller if it exist.", array('y','n'), 'y');
01162 
01163         if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
01164             $this->interactive = true;
01165 
01166             $wannaUseScaffold = $this->getInput("Would you like to use scaffolding?", array('y','n'), 'y');
01167 
01168             if (low($wannaUseScaffold) == 'n' || low($wannaUseScaffold) == 'no') {
01169 
01170                 $wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'n');
01171 
01172                 if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
01173                     $wannaDoAdmin = $this->getInput("Would you like to create the methods for admin routing?", array('y','n'), 'n');
01174                 }
01175 
01176                 $wannaDoUses = $this->getInput("Would you like this controller to use other models besides '" . $this->__modelName($controllerName) .  "'?", array('y','n'), 'n');
01177 
01178                 if (low($wannaDoUses) == 'y' || low($wannaDoUses) == 'yes') {
01179                     $usesList = $this->getInput("Please provide a comma separated list of the classnames of other models you'd like to use.\nExample: 'Author, Article, Book'");
01180                     $usesListTrimmed = str_replace(' ', '', $usesList);
01181                     $uses = explode(',', $usesListTrimmed);
01182                 }
01183                 $wannaDoHelpers = $this->getInput("Would you like this controller to use other helpers besides HtmlHelper and FormHelper?", array('y','n'), 'n');
01184 
01185                 if (low($wannaDoHelpers) == 'y' || low($wannaDoHelpers) == 'yes') {
01186                     $helpersList = $this->getInput("Please provide a comma separated list of the other helper names you'd like to use.\nExample: 'Ajax, Javascript, Time'");
01187                     $helpersListTrimmed = str_replace(' ', '', $helpersList);
01188                     $helpers = explode(',', $helpersListTrimmed);
01189                 }
01190                 $wannaDoComponents = $this->getInput("Would you like this controller to use any components?", array('y','n'), 'n');
01191 
01192                 if (low($wannaDoComponents) == 'y' || low($wannaDoComponents) == 'yes') {
01193                     $componentsList = $this->getInput("Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, MyNiftyHelper'");
01194                     $componentsListTrimmed = str_replace(' ', '', $componentsList);
01195                     $components = explode(',', $componentsListTrimmed);
01196                 }
01197 
01198                 $wannaUseSession = $this->getInput("Would you like to use Sessions?", array('y','n'), 'y');
01199             } else {
01200                 $wannaDoScaffolding = 'n';
01201             }
01202         } else {
01203             $wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'y');
01204 
01205             if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
01206                 $wannaDoAdmin = $this->getInput("Would you like to create the methods for admin routing?", array('y','n'), 'y');
01207             }
01208         }
01209 
01210         $admin = null;
01211         $admin_url = null;
01212         if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
01213             require(CONFIGS.'core.php');
01214             if (defined('CAKE_ADMIN')) {
01215                 $admin = CAKE_ADMIN.'_';
01216                 $admin_url = '/'.CAKE_ADMIN;
01217             } else {
01218                 $adminRoute = '';
01219                 $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
01220                 $this->stdout('What would you like the admin route to be?');
01221                 $this->stdout('Example: www.example.com/admin/controller');
01222                 while ($adminRoute == '') {
01223                     $adminRoute = $this->getInput("What would you like the admin route to be?", null, 'admin');
01224                 }
01225                 if ($this->__addAdminRoute($adminRoute) !== true) {
01226                     $this->stdout('Unable to write to /app/config/core.php.');
01227                     $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
01228                     exit();
01229                 } else {
01230                     $admin = $adminRoute . '_';
01231                     $admin_url = '/'.$adminRoute;
01232                 }
01233             }
01234         }
01235 
01236         if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
01237             $actions = $this->__bakeActions($controllerName, null, null, $wannaUseSession);
01238             if ($admin) {
01239                 $actions .= $this->__bakeActions($controllerName, $admin, $admin_url, $wannaUseSession);
01240             }
01241         }
01242 
01243         if ($this->interactive === true) {
01244             $this->stdout('');
01245             $this->hr();
01246             $this->stdout('The following controller will be created:');
01247             $this->hr();
01248             $this->stdout("Controller Name: $controllerName");
01249             if (low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
01250                 $this->stdout("         var \$scaffold;");
01251             }
01252             if (count($uses)) {
01253                 $this->stdout("Uses:            ", false);
01254 
01255                 foreach ($uses as $use) {
01256                     if ($use != $uses[count($uses) - 1]) {
01257                         $this->stdout(ucfirst($use) . ", ", false);
01258                     } else {
01259                         $this->stdout(ucfirst($use));
01260                     }
01261                 }
01262             }
01263 
01264             if (count($helpers)) {
01265                 $this->stdout("Helpers:         ", false);
01266 
01267                 foreach ($helpers as $help) {
01268                     if ($help != $helpers[count($helpers) - 1]) {
01269                         $this->stdout(ucfirst($help) . ", ", false);
01270                     } else {
01271                         $this->stdout(ucfirst($help));
01272                     }
01273                 }
01274             }
01275 
01276             if (count($components)) {
01277                 $this->stdout("Components:            ", false);
01278 
01279                 foreach ($components as $comp) {
01280                     if ($comp != $components[count($components) - 1]) {
01281                         $this->stdout(ucfirst($comp) . ", ", false);
01282                     } else {
01283                         $this->stdout(ucfirst($comp));
01284                     }
01285                 }
01286             }
01287             $this->hr();
01288             $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
01289 
01290             if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
01291                 $this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
01292 
01293                 if ($this->doUnitTest()) {
01294                     $this->bakeUnitTest('controller', $controllerName);
01295                 }
01296             } else {
01297                 $this->stdout('Bake Aborted.');
01298             }
01299         } else {
01300             $this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
01301             if ($this->doUnitTest()) {
01302                 $this->bakeUnitTest('controller', $controllerName);
01303             }
01304             exit();
01305         }
01306     }
01307 
01308     function __bakeActions($controllerName, $admin = null, $admin_url = null, $wannaUseSession = 'y') {
01309         $currentModelName = $this->__modelName($controllerName);
01310         loadModel($currentModelName);
01311         $modelObj =& new $currentModelName();
01312         $controllerPath = $this->__controllerPath($controllerName);
01313         $pluralName = $this->__pluralName($currentModelName);
01314         $singularName = $this->__singularName($currentModelName);
01315         $singularHumanName = $this->__singularHumanName($currentModelName);
01316         $pluralHumanName = $this->__pluralHumanName($controllerName);
01317         if (!class_exists($currentModelName)) {
01318             $this->stdout('You must have a model for this class to build scaffold methods. Please try again.');
01319             exit;
01320         }
01321         $actions .= "\n";
01322         $actions .= "\tfunction {$admin}index() {\n";
01323         $actions .= "\t\t\$this->{$currentModelName}->recursive = 0;\n";
01324         $actions .= "\t\t\$this->set('{$pluralName}', \$this->{$currentModelName}->findAll());\n";
01325         $actions .= "\t}\n";
01326         $actions .= "\n";
01327         $actions .= "\tfunction {$admin}view(\$id = null) {\n";
01328         $actions .= "\t\tif (!\$id) {\n";
01329         if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
01330         $actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}.');\n";
01331         $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
01332         } else {
01333         $actions .= "\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
01334         }
01335         $actions .= "\t\t}\n";
01336         $actions .= "\t\t\$this->set('".$singularName."', \$this->{$currentModelName}->read(null, \$id));\n";
01337         $actions .= "\t}\n";
01338         $actions .= "\n";
01339         $actions .= "\tfunction {$admin}add() {\n";
01340         $actions .= "\t\tif (empty(\$this->data)) {\n";
01341 
01342         foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
01343             if (!empty($associationName)) {
01344                 $otherModelName = $this->__modelName($associationName);
01345                 $otherSingularName = $this->__singularName($associationName);
01346                 $otherPluralName = $this->__pluralName($associationName);
01347                 $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
01348                 $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
01349                 $actions .= "\t\t\t\$this->set('{$selectedOtherPluralName}', null);\n";
01350             }
01351         }
01352         foreach ($modelObj->belongsTo as $associationName => $relation) {
01353             if (!empty($associationName)) {
01354                 $otherModelName = $this->__modelName($associationName);
01355                 $otherSingularName = $this->__singularName($associationName);
01356                 $otherPluralName = $this->__pluralName($associationName);
01357                 $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
01358             }
01359         }
01360         $actions .= "\t\t\t\$this->render();\n";
01361         $actions .= "\t\t} else {\n";
01362         $actions .= "\t\t\t\$this->cleanUpFields();\n";
01363         $actions .= "\t\t\tif (\$this->{$currentModelName}->save(\$this->data)) {\n";
01364         if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
01365         $actions .= "\t\t\t\t\$this->Session->setFlash('The ".$this->__singularHumanName($currentModelName)." has been saved');\n";
01366         $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
01367         } else {
01368         $actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', '{$admin_url}/{$controllerPath}/index');\n";
01369         }
01370         $actions .= "\t\t\t} else {\n";
01371         if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
01372         $actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
01373         }
01374 
01375         foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
01376             if (!empty($associationName)) {
01377                 $otherModelName = $this->__modelName($associationName);
01378                 $otherSingularName = $this->__singularName($associationName);
01379                 $otherPluralName = $this->__pluralName($associationName);
01380                 $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
01381                 $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
01382                 $actions .= "\t\t\t\tif (empty(\$this->data['{$associationName}']['{$associationName}'])) { \$this->data['{$associationName}']['{$associationName}'] = null; }\n";
01383                 $actions .= "\t\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->data['{$associationName}']['{$associationName}']);\n";
01384             }
01385         }
01386         foreach ($modelObj->belongsTo as $associationName => $relation) {
01387             if (!empty($associationName)) {
01388                 $otherModelName = $this->__modelName($associationName);
01389                 $otherSingularName = $this->__singularName($associationName);
01390                 $otherPluralName = $this->__pluralName($associationName);
01391                 $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
01392             }
01393         }
01394         $actions .= "\t\t\t}\n";
01395         $actions .= "\t\t}\n";
01396         $actions .= "\t}\n";
01397         $actions .= "\n";
01398         $actions .= "\tfunction {$admin}edit(\$id = null) {\n";
01399         $actions .= "\t\tif (empty(\$this->data)) {\n";
01400         $actions .= "\t\t\tif (!\$id) {\n";
01401         if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
01402         $actions .= "\t\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
01403         $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
01404         } else {
01405         $actions .= "\t\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
01406         }
01407         $actions .= "\t\t\t}\n";
01408         $actions .= "\t\t\t\$this->data = \$this->{$currentModelName}->read(null, \$id);\n";
01409 
01410         foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
01411             if (!empty($associationName)) {
01412                 $otherModelName = $this->__modelName($associationName);
01413                 $otherSingularName = $this->__singularName($associationName);
01414                 $otherPluralName = $this->__pluralName($associationName);
01415                 $otherModelKey = Inflector::underscore($otherModelName);
01416                 $otherModelObj =& ClassRegistry::getObject($otherModelKey);
01417                 $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
01418                 $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
01419                 $actions .= "\t\t\tif (empty(\$this->data['{$associationName}'])) { \$this->data['{$associationName}'] = null; }\n";
01420                 $actions .= "\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->_selectedArray(\$this->data['{$associationName}']));\n";
01421             }
01422         }
01423         foreach ($modelObj->belongsTo as $associationName => $relation) {
01424             if (!empty($associationName)) {
01425                 $otherModelName = $this->__modelName($associationName);
01426                 $otherSingularName = $this->__singularName($associationName);
01427                 $otherPluralName = $this->__pluralName($associationName);
01428                 $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
01429             }
01430         }
01431         $actions .= "\t\t} else {\n";
01432         $actions .= "\t\t\t\$this->cleanUpFields();\n";
01433         $actions .= "\t\t\tif (\$this->{$currentModelName}->save(\$this->data)) {\n";
01434         if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
01435         $actions .= "\t\t\t\t\$this->Session->setFlash('The ".Inflector::humanize($currentModelName)." has been saved');\n";
01436         $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
01437         } else {
01438         $actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', '{$admin_url}/{$controllerPath}/index');\n";
01439         }
01440         $actions .= "\t\t\t} else {\n";
01441         if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
01442         $actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
01443         }
01444 
01445         foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
01446             if (!empty($associationName)) {
01447                 $otherModelName = $this->__modelName($associationName);
01448                 $otherSingularName = $this->__singularName($associationName);
01449                 $otherPluralName = $this->__pluralName($associationName);
01450                 $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
01451                 $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
01452                 $actions .= "\t\t\t\tif (empty(\$this->data['{$associationName}']['{$associationName}'])) { \$this->data['{$associationName}']['{$associationName}'] = null; }\n";
01453                 $actions .= "\t\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->data['{$associationName}']['{$associationName}']);\n";
01454             }
01455         }
01456         foreach ($modelObj->belongsTo as $associationName => $relation) {
01457             if (!empty($associationName)) {
01458                 $otherModelName = $this->__modelName($associationName);
01459                 $otherSingularName = $this->__singularName($associationName);
01460                 $otherPluralName = $this->__pluralName($associationName);
01461                 $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
01462             }
01463         }
01464         $actions .= "\t\t\t}\n";
01465         $actions .= "\t\t}\n";
01466         $actions .= "\t}\n";
01467         $actions .= "\n";
01468         $actions .= "\tfunction {$admin}delete(\$id = null) {\n";
01469         $actions .= "\t\tif (!\$id) {\n";
01470         if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
01471         $actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
01472         $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
01473         } else {
01474         $actions .= "\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
01475         }
01476         $actions .= "\t\t}\n";
01477         $actions .= "\t\tif (\$this->{$currentModelName}->del(\$id)) {\n";
01478         if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
01479             $actions .= "\t\t\t\$this->Session->setFlash('The ".$this->__singularHumanName($currentModelName)." deleted: id '.\$id.'');\n";
01480             $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
01481         } else {
01482             $actions .= "\t\t\t\$this->flash('{$currentModelName} deleted: id '.\$id.'.', '{$admin_url}/{$controllerPath}/index');\n";
01483         }
01484         $actions .= "\t\t}\n";
01485         $actions .= "\t}\n";
01486         $actions .= "\n";
01487         return $actions;
01488     }
01489 /**
01490  * Action to create a Unit Test.
01491  *
01492  * @return Success
01493  */
01494     function doUnitTest() {
01495         if (is_dir(VENDORS.'simpletest') || is_dir(ROOT.DS.APP_DIR.DS.'vendors'.DS.'simpletest')) {
01496             return true;
01497         }
01498         $unitTest = $this->getInput('Cake test suite not installed.  Do you want to bake unit test files anyway?', array('y','n'), 'y');
01499         $result = low($unitTest) == 'y' || low($unitTest) == 'yes';
01500 
01501         if ($result) {
01502             $this->stdout("\nYou can download the Cake test suite from http://cakeforge.org/projects/testsuite/", true);
01503         }
01504         return $result;
01505     }
01506 /**
01507  * Creates a database configuration file for Bake.
01508  *
01509  * @param string $host
01510  * @param string $login
01511  * @param string $password
01512  * @param string $database
01513  */
01514     function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
01515         $out = "<?php\n";
01516         $out .= "class DATABASE_CONFIG {\n\n";
01517         $out .= "\tvar \$default = array(\n";
01518         $out .= "\t\t'driver' => '{$driver}',\n";
01519         $out .= "\t\t'connect' => '{$connect}',\n";
01520         $out .= "\t\t'host' => '{$host}',\n";
01521         $out .= "\t\t'login' => '{$login}',\n";
01522         $out .= "\t\t'password' => '{$password}',\n";
01523         $out .= "\t\t'database' => '{$database}', \n";
01524         $out .= "\t\t'prefix' => '{$prefix}' \n";
01525         $out .= "\t);\n";
01526         $out .= "}\n";
01527         $out .= "?>";
01528         $filename = CONFIGS.'database.php';
01529         $this->__createFile($filename, $out);
01530     }
01531 /**
01532  * Assembles and writes a Model file.
01533  *
01534  * @param string $name
01535  * @param object $useDbConfig
01536  * @param string $useTable
01537  * @param string $primaryKey
01538  * @param array $validate
01539  * @param array $associations
01540  */
01541     function bakeModel($name, $useDbConfig = 'default', $useTable = null, $primaryKey = 'id', $validate=array(), $associations=array()) {
01542         $out = "<?php\n";
01543         $out .= "class {$name} extends AppModel {\n\n";
01544         $out .= "\tvar \$name = '{$name}';\n";
01545 
01546         if ($useDbConfig != 'default') {
01547             $out .= "\tvar \$useDbConfig = '$useDbConfig';\n";
01548         }
01549 
01550         if ($useTable != null) {
01551             $out .= "\tvar \$useTable = '$useTable';\n";
01552         }
01553 
01554         if ($primaryKey != 'id') {
01555             $out .= "\tvar \$primaryKey = '$primaryKey';\n";
01556         }
01557 
01558 
01559         if (count($validate)) {
01560             $out .= "\tvar \$validate = array(\n";
01561             $keys = array_keys($validate);
01562             for ($i = 0; $i < count($validate); $i++) {
01563                 $out .= "\t\t'" . $keys[$i] . "' => " . $validate[$keys[$i]] . ",\n";
01564             }
01565             $out .= "\t);\n";
01566         }
01567         $out .= "\n";
01568 
01569         if (!empty($associations)) {
01570             $out.= "\t//The Associations below have been created with all possible keys, those that are not needed can be removed\n";
01571             if (!empty($associations['belongsTo'])) {
01572                 $out .= "\tvar \$belongsTo = array(\n";
01573 
01574                 for ($i = 0; $i < count($associations['belongsTo']); $i++) {
01575                     $out .= "\t\t\t'{$associations['belongsTo'][$i]['alias']}' =>\n";
01576                     $out .= "\t\t\t\tarray('className' => '{$associations['belongsTo'][$i]['className']}',\n";
01577                     $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['belongsTo'][$i]['foreignKey']}',\n";
01578                     $out .= "\t\t\t\t\t\t'conditions' => '',\n";
01579                     $out .= "\t\t\t\t\t\t'fields' => '',\n";
01580                     $out .= "\t\t\t\t\t\t'order' => '',\n";
01581                     $out .= "\t\t\t\t\t\t'counterCache' => ''\n";
01582                     $out .= "\t\t\t\t),\n\n";
01583                 }
01584                 $out .= "\t);\n\n";
01585             }
01586 
01587             if (!empty($associations['hasOne'])) {
01588                 $out .= "\tvar \$hasOne = array(\n";
01589 
01590                 for ($i = 0; $i < count($associations['hasOne']); $i++) {
01591                     $out .= "\t\t\t'{$associations['hasOne'][$i]['alias']}' =>\n";
01592                     $out .= "\t\t\t\tarray('className' => '{$associations['hasOne'][$i]['className']}',\n";
01593                     $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasOne'][$i]['foreignKey']}',\n";
01594                     $out .= "\t\t\t\t\t\t'conditions' => '',\n";
01595                     $out .= "\t\t\t\t\t\t'fields' => '',\n";
01596                     $out .= "\t\t\t\t\t\t'order' => '',\n";
01597                     $out .= "\t\t\t\t\t\t'dependent' => ''\n";
01598                     $out .= "\t\t\t\t),\n\n";
01599                 }
01600                 $out .= "\t);\n\n";
01601             }
01602 
01603             if (!empty($associations['hasMany'])) {
01604                 $out .= "\tvar \$hasMany = array(\n";
01605 
01606                 for ($i = 0; $i < count($associations['hasMany']); $i++) {
01607                     $out .= "\t\t\t'{$associations['hasMany'][$i]['alias']}' =>\n";
01608                     $out .= "\t\t\t\tarray('className' => '{$associations['hasMany'][$i]['className']}',\n";
01609                     $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasMany'][$i]['foreignKey']}',\n";
01610                     $out .= "\t\t\t\t\t\t'conditions' => '',\n";
01611                     $out .= "\t\t\t\t\t\t'fields' => '',\n";
01612                     $out .= "\t\t\t\t\t\t'order' => '',\n";
01613                     $out .= "\t\t\t\t\t\t'limit' => '',\n";
01614                     $out .= "\t\t\t\t\t\t'offset' => '',\n";
01615                     $out .= "\t\t\t\t\t\t'dependent' => '',\n";
01616                     $out .= "\t\t\t\t\t\t'exclusive' => '',\n";
01617                     $out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
01618                     $out .= "\t\t\t\t\t\t'counterQuery' => ''\n";
01619                     $out .= "\t\t\t\t),\n\n";
01620                 }
01621                 $out .= "\t);\n\n";
01622             }
01623 
01624             if (!empty($associations['hasAndBelongsToMany'])) {
01625                 $out .= "\tvar \$hasAndBelongsToMany = array(\n";
01626 
01627                 for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
01628                     $out .= "\t\t\t'{$associations['hasAndBelongsToMany'][$i]['alias']}' =>\n";
01629                     $out .= "\t\t\t\tarray('className' => '{$associations['hasAndBelongsToMany'][$i]['className']}',\n";
01630                     $out .= "\t\t\t\t\t\t'joinTable' => '{$associations['hasAndBelongsToMany'][$i]['joinTable']}',\n";
01631                     $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasAndBelongsToMany'][$i]['foreignKey']}',\n";
01632                     $out .= "\t\t\t\t\t\t'associationForeignKey' => '{$associations['hasAndBelongsToMany'][$i]['associationForeignKey']}',\n";
01633                     $out .= "\t\t\t\t\t\t'conditions' => '',\n";
01634                     $out .= "\t\t\t\t\t\t'fields' => '',\n";
01635                     $out .= "\t\t\t\t\t\t'order' => '',\n";
01636                     $out .= "\t\t\t\t\t\t'limit' => '',\n";
01637                     $out .= "\t\t\t\t\t\t'offset' => '',\n";
01638                     $out .= "\t\t\t\t\t\t'unique' => '',\n";
01639                     $out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
01640                     $out .= "\t\t\t\t\t\t'deleteQuery' => '',\n";
01641                     $out .= "\t\t\t\t\t\t'insertQuery' => ''\n";
01642                     $out .= "\t\t\t\t),\n\n";
01643                 }
01644                 $out .= "\t);\n\n";
01645             }
01646         }
01647         $out .= "}\n";
01648         $out .= "?>";
01649         $filename = MODELS.Inflector::underscore($name) . '.php';
01650         $this->__createFile($filename, $out);
01651     }
01652 /**
01653  * Assembles and writes a View file.
01654  *
01655  * @param string $controllerName
01656  * @param string $actionName
01657  * @param string $content
01658  */
01659     function bakeView($controllerName, $actionName, $content = '') {
01660         $out = "<h2>{$actionName}</h2>\n";
01661         $out .= $content;
01662         if (!file_exists(VIEWS.$this->__controllerPath($controllerName))) {
01663             mkdir(VIEWS.$this->__controllerPath($controllerName));
01664         }
01665         $filename = VIEWS . $this->__controllerPath($controllerName) . DS . Inflector::underscore($actionName) . '.thtml';
01666         $this->__createFile($filename, $out);
01667     }
01668 /**
01669  * Assembles and writes a Controller file.
01670  *
01671  * @param string $controllerName
01672  * @param array $uses
01673  * @param array $helpers
01674  * @param array $components
01675  * @param string $actions
01676  */
01677     function bakeController($controllerName, $uses, $helpers, $components, $actions = '', $wannaUseScaffold = 'y') {
01678         $out = "<?php\n";
01679         $out .= "class $controllerName" . "Controller extends AppController {\n\n";
01680         $out .= "\tvar \$name = '$controllerName';\n";
01681         if (low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
01682         $out .= "\tvar \$scaffold;\n";
01683         } else {
01684 
01685             if (count($uses)) {
01686                 $out .= "\tvar \$uses = array('" . $this->__modelName($controllerName) . "', ";
01687 
01688                 foreach ($uses as $use) {
01689                     if ($use != $uses[count($uses) - 1]) {
01690                         $out .= "'" . $this->__modelName($use) . "', ";
01691                     } else {
01692                         $out .= "'" . $this->__modelName($use) . "'";
01693                     }
01694                 }
01695                 $out .= ");\n";
01696             }
01697 
01698                 $out .= "\tvar \$helpers = array('Html', 'Form' ";
01699                 if (count($helpers)) {
01700                     foreach ($helpers as $help) {
01701                         if ($help != $helpers[count($helpers) - 1]) {
01702                             $out .= ", '" . Inflector::camelize($help) . "'";
01703                         } else {
01704                             $out .= ", '" . Inflector::camelize($help) . "'";
01705                         }
01706                     }
01707                 }
01708                 $out .= ");\n";
01709 
01710             if (count($components)) {
01711                 $out .= "\tvar \$components = array(";
01712 
01713                 foreach ($components as $comp) {
01714                     if ($comp != $components[count($components) - 1]) {
01715                         $out .= "'" . Inflector::camelize($comp) . "', ";
01716                     } else {
01717                         $out .= "'" . Inflector::camelize($comp) . "'";
01718                     }
01719                 }
01720                 $out .= ");\n";
01721             }
01722         }
01723         $out .= $actions;
01724         $out .= "}\n";
01725         $out .= "?>";
01726         $filename = CONTROLLERS . $this->__controllerPath($controllerName) . '_controller.php';
01727         $this->__createFile($filename, $out);
01728     }
01729 /**
01730  * Assembles and writes a unit test file.
01731  *
01732  * @param string $type One of "model", and "controller".
01733  * @param string $className
01734  */
01735     function bakeUnitTest($type, $className) {
01736         $out = '<?php '."\n\n";
01737         $error = false;
01738         switch ($type) {
01739             case 'model':
01740                 $out .= "loadModel('$className');\n\n";
01741                 $out .= "class {$className}TestCase extends UnitTestCase {\n";
01742                 $out .= "\tvar \$object = null;\n\n";
01743                 $out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}();\n";
01744                 $out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
01745                 $out .= "\n\t/*\n\tfunction testMe() {\n";
01746                 $out .= "\t\t\$result = \$this->object->doSomething();\n";
01747                 $out .= "\t\t\$expected = 1;\n";
01748                 $out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
01749                 $path = MODEL_TESTS;
01750                 $filename = $this->__singularName($className).'.test.php';
01751             break;
01752             case 'controller':
01753                 $out .= "loadController('$className');\n\n";
01754                 $out .= "class {$className}ControllerTestCase extends UnitTestCase {\n";
01755                 $out .= "\tvar \$object = null;\n\n";
01756                 $out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}Controller();\n";
01757                 $out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
01758                 $out .= "\n\t/*\n\tfunction testMe() {\n";
01759                 $out .= "\t\t\$result = \$this->object->doSomething();\n";
01760                 $out .= "\t\t\$expected = 1;\n";
01761                 $out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
01762                 $path = CONTROLLER_TESTS;
01763                 $filename = $this->__pluralName($className).'_controller.test.php';
01764             break;
01765             default:
01766                 $error = true;
01767             break;
01768         }
01769         $out .= "\n?>";
01770 
01771         if (!$error) {
01772             $this->stdout("Baking unit test for $className...");
01773             $path = explode(DS, $path);
01774             foreach ($path as $i => $val) {
01775                 if ($val == '' || $val == '../') {
01776                     unset($path[$i]);
01777                 }
01778             }
01779             $path = implode(DS, $path);
01780             $unixPath = DS;
01781             if (strpos(PHP_OS, 'WIN') === 0) {
01782                 $unixPath = null;
01783             }
01784             if (!is_dir($unixPath.$path)) {
01785                 $create = $this->getInput("Unit test directory does not exist.  Create it?", array('y','n'), 'y');
01786                 if (low($create) == 'y' || low($create) == 'yes') {
01787                     $build = array();
01788 
01789                     foreach (explode(DS, $path) as $i => $dir) {
01790                         $build[] = $dir;
01791                         if (!is_dir($unixPath.implode(DS, $build))) {
01792                             mkdir($unixPath.implode(DS, $build));
01793                         }
01794                     }
01795                 } else {
01796                     return false;
01797                 }
01798             }
01799             $this->__createFile($unixPath.$path.DS.$filename, $out);
01800         }
01801     }
01802 /**
01803  * Prompts the user for input, and returns it.
01804  *
01805  * @param string $prompt Prompt text.
01806  * @param mixed $options Array or string of options.
01807  * @param string $default Default input value.
01808  * @return Either the default value, or the user-provided input.
01809  */
01810     function getInput($prompt, $options = null, $default = null) {
01811         if (!is_array($options)) {
01812             $print_options = '';
01813         } else {
01814             $print_options = '(' . implode('/', $options) . ')';
01815         }
01816 
01817         if ($default == null) {
01818             $this->stdout('');
01819             $this->stdout($prompt . " $print_options \n" . '> ', false);
01820         } else {
01821             $this->stdout('');
01822             $this->stdout($prompt . " $print_options \n" . "[$default] > ", false);
01823         }
01824         $result = fgets($this->stdin);
01825 
01826         if($result === false){
01827             exit;
01828         }
01829         $result = trim($result);
01830 
01831         if ($default != null && empty($result)) {
01832             return $default;
01833         } else {
01834             return $result;
01835         }
01836     }
01837 /**
01838  * Outputs to the stdout filehandle.
01839  *
01840  * @param string $string String to output.
01841  * @param boolean $newline If true, the outputs gets an added newline.
01842  */
01843     function stdout($string, $newline = true) {
01844         if ($newline) {
01845             fwrite($this->stdout, $string . "\n");
01846         } else {
01847             fwrite($this->stdout, $string);
01848         }
01849     }
01850 /**
01851  * Outputs to the stderr filehandle.
01852  *
01853  * @param string $string Error text to output.
01854  */
01855     function stderr($string) {
01856         fwrite($this->stderr, $string, true);
01857     }
01858 /**
01859  * Outputs a series of minus characters to the standard output, acts as a visual separator.
01860  *
01861  */
01862     function hr() {
01863         $this->stdout('---------------------------------------------------------------');
01864     }
01865 /**
01866  * Creates a file at given path.
01867  *
01868  * @param string $path      Where to put the file.
01869  * @param string $contents Content to put in the file.
01870  * @return Success
01871  */
01872     function __createFile ($path, $contents) {
01873         $path = str_replace('//', '/', $path);
01874         echo "\nCreating file $path\n";
01875         if (is_file($path) && $this->interactive === true) {
01876             fwrite($this->stdout, __("File exists, overwrite?", true). " {$path} (y/n/q):");
01877             $key = trim(fgets($this->stdin));
01878 
01879             if ($key=='q') {
01880                 fwrite($this->stdout, __("Quitting.", true) ."\n");
01881                 exit;
01882             } elseif ($key == 'a') {
01883                 $this->dont_ask = true;
01884             } elseif ($key == 'y') {
01885             } else {
01886                 fwrite($this->stdout, __("Skip", true) ." {$path}\n");
01887                 return false;
01888             }
01889         }
01890 
01891         if ($f = fopen($path, 'w')) {
01892             fwrite($f, $contents);
01893             fclose($f);
01894             fwrite($this->stdout, __("Wrote", true) ."{$path}\n");
01895             return true;
01896         } else {
01897             fwrite($this->stderr, __("Error! Could not write to", true)." {$path}.\n");
01898             return false;
01899         }
01900     }
01901 /**
01902  * Takes an array of database fields, and generates an HTML form for a View.
01903  * This is an extraction from the Scaffold functionality.
01904  *
01905  * @param array $fields
01906  * @param boolean $readOnly
01907  * @return Generated HTML and PHP.
01908  */
01909     function generateFields( $fields, $readOnly = false ) {
01910         $strFormFields = '';
01911         foreach ( $fields as $field ) {
01912             if (isset( $field['type'])) {
01913                 if (!isset($field['required'])) {
01914                     $field['required'] = false;
01915                 }
01916 
01917                 if (!isset( $field['errorMsg'])) {
01918                     $field['errorMsg'] = null;
01919                 }
01920 
01921                 if (!isset( $field['htmlOptions'])) {
01922                     $field['htmlOptions'] = array();
01923                 }
01924 
01925                 if ( $readOnly ) {
01926                     $field['htmlOptions']['READONLY'] = "readonly";
01927                 }
01928 
01929                 switch( $field['type'] ) {
01930                     case "input" :
01931                         if (!isset( $field['size'])) {
01932                             $field['size'] = 60;
01933                         }
01934                         $strFormFields = $strFormFields.$this->generateInputDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions'] );
01935                     break;
01936                     case "checkbox" :
01937                         $strFormFields = $strFormFields.$this->generateCheckboxDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['htmlOptions'] );
01938                     break;
01939                     case "select";
01940                     case "selectMultiple";
01941                         if ( "selectMultiple" == $field['type'] ) {
01942                             $field['selectAttr']['multiple'] = 'multiple';
01943                             $field['selectAttr']['class'] = 'selectMultiple';
01944                         }
01945                         if (!isset( $field['selected'])) {
01946                             $field['selected'] = null;
01947                         }
01948                         if (!isset( $field['selectAttr'])) {
01949                             $field['selectAttr'] = null;
01950                         }
01951                         if (!isset( $field['optionsAttr'])) {
01952                             $field['optionsAttr'] = null;
01953                         }
01954                         if ($readOnly) {
01955                             $field['selectAttr']['DISABLED'] = true;
01956                         }
01957                         if (!isset( $field['options'])) {
01958                             $field['options'] = null;
01959                         }
01960                         $this->__modelAlias = null;
01961                         if (isset($field['foreignKey'])) {
01962                             $modelKey = Inflector::underscore($this->__modelClass);
01963                             $modelObj =& ClassRegistry::getObject($modelKey);
01964                             foreach ($modelObj->belongsTo as $associationName => $value) {
01965                                 if ($field['model'] == $value['className']) {
01966                                     $this->__modelAlias = $this->__modelName($associationName);
01967                                     break;
01968                                 }
01969                             }
01970                         }
01971                         $strFormFields = $strFormFields.$this->generateSelectDiv( $field['tagName'], $field['prompt'], $field['options'], $field['selected'], $field['selectAttr'], $field['optionsAttr'], $field['required'], $field['errorMsg'] );
01972                     break;
01973                     case "area";
01974                         if (!isset( $field['rows'])) {
01975                             $field['rows'] = 10;
01976                         }
01977                         if (!isset( $field['cols'])) {
01978                             $field['cols'] = 60;
01979                         }
01980                         $strFormFields = $strFormFields.$this->generateAreaDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['cols'], $field['rows'], $field['htmlOptions'] );
01981                     break;
01982                     case "fieldset";
01983                         $strFieldsetFields = $this->generateFields( $field['fields'] );
01984                         $strFieldSet = sprintf( '
01985                         <fieldset><legend>%s</legend><div class="notes"><h4>%s</h4><p class="last">%s</p></div>%s</fieldset>',
01986                         $field['legend'], $field['noteHeading'], $field['note'], $strFieldsetFields );
01987                         $strFormFields = $strFormFields.$strFieldSet;
01988                     break;
01989                     case "hidden";
01990                         //$strFormFields = $strFormFields . $this->Html->hiddenTag( $field['tagName']);
01991                     break;
01992                     case "date":
01993                         if (!isset($field['selected'])) {
01994                             $field['selected'] = null;
01995                         }
01996                         $strFormFields = $strFormFields . $this->generateDate($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
01997                     break;
01998                     case "datetime":
01999                         if (!isset($field['selected'])) {
02000                             $field['selected'] = null;
02001                         }
02002                         $strFormFields = $strFormFields . $this->generateDateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
02003                     break;
02004                     case "time":
02005                         if (!isset($field['selected'])) {
02006                             $field['selected'] = null;
02007                         }
02008                         $strFormFields = $strFormFields . $this->generateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
02009                     break;
02010                     default:
02011                     break;
02012                 }
02013             }
02014         }
02015         return $strFormFields;
02016     }
02017 /**
02018  * Generates PHP code for a View file that makes a textarea.
02019  *
02020  * @param string $tagName
02021  * @param string $prompt
02022  * @param boolean $required
02023  * @param string $errorMsg
02024  * @param integer $cols
02025  * @param integer $rows
02026  * @param array $htmlOptions
02027  * @return Generated HTML and PHP.
02028  */
02029     function generateAreaDiv($tagName, $prompt, $required=false, $errorMsg=null, $cols=60, $rows=10,  $htmlOptions=null ) {
02030         $htmlAttributes = $htmlOptions;
02031         $htmlAttributes['cols'] = $cols;
02032         $htmlAttributes['rows'] = $rows;
02033         $str = "\t<?php echo \$html->textarea('{$tagName}', " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
02034         $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please enter the {$prompt}.');?>\n";
02035         $strLabel = "\n\t<?php echo \$form->labelTag( '{$tagName}', '{$prompt}' );?>\n";
02036         $divClass = "optional";
02037 
02038         if ( $required ) {
02039             $divClass = "required";
02040         }
02041         $strError = "";
02042         $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
02043         return $this->divTag( $divClass, $divTagInside );
02044     }
02045 /**
02046  * Generates PHP code for a View file that makes a checkbox, wrapped in a DIV.
02047  *
02048  * @param string $tagName
02049  * @param string $prompt
02050  * @param boolean $required
02051  * @param string $errorMsg
02052  * @param array $htmlOptions
02053  * @return Generated HTML and PHP.
02054  */
02055     function generateCheckboxDiv($tagName, $prompt, $required=false, $errorMsg=null, $htmlOptions=null ) {
02056         $htmlAttributes = $htmlOptions;
02057         $strLabel = "\n\t<?php echo \$html->checkbox('{$tagName}', null, " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
02058         $strLabel .= "\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
02059         $str = "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please check the {$prompt}.');?>\n";
02060         $divClass = "optional";
02061 
02062         if ($required) {
02063             $divClass = "required";
02064         }
02065         $strError = "";
02066         $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str);
02067         return $this->divTag( $divClass, $divTagInside );
02068     }
02069 /**
02070  * Generates PHP code for a View file that makes a date-picker, wrapped in a DIV.
02071  *
02072  * @param string $tagName
02073  * @param string $prompt
02074  * @param boolean $required
02075  * @param string $errorMsg
02076  * @param integer $size
02077  * @param array $htmlOptions
02078  * @param string $selected
02079  * @return Generated HTML and PHP.
02080  */
02081     function generateDate($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null, $selected=null ) {
02082         $str = "\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'MDY' , 'NONE', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
02083         $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
02084         $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
02085         $divClass = "optional";
02086 
02087         if ($required) {
02088             $divClass = "required";
02089         }
02090         $strError = "";
02091         $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
02092         return $this->divTag( $divClass, $divTagInside );
02093     }
02094 /**
02095  * Generates PHP code for a View file that makes a time-picker, wrapped in a DIV.
02096  *
02097  * @param string $tagName
02098  * @param string $prompt
02099  * @param boolean $required
02100  * @param string $errorMsg
02101  * @param integer $size
02102  * @param array $htmlOptions
02103  * @param string $selected
02104  * @return Generated HTML and PHP.
02105  */
02106     function generateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
02107         $str = "\n\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'NONE', '24', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
02108         $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
02109         $divClass = "optional";
02110         if ($required) {
02111             $divClass = "required";
02112         }
02113         $strError = "";
02114         $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
02115         return $this->divTag($divClass, $divTagInside);
02116     }
02117 /**
02118  * EGenerates PHP code for a View file that makes a datetime-picker, wrapped in a DIV.
02119  *
02120  * @param string $tagName
02121  * @param string $prompt
02122  * @param boolean $required
02123  * @param string $errorMsg
02124  * @param integer $size
02125  * @param array $htmlOptions
02126  * @param string $selected
02127  * @return Generated HTML and PHP.
02128  */
02129     function generateDateTime($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null, $selected = null ) {
02130         $str = "\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'MDY' , '12', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
02131         $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
02132         $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
02133         $divClass = "optional";
02134 
02135         if ($required) {
02136             $divClass = "required";
02137         }
02138         $strError = "";
02139         $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
02140         return $this->divTag( $divClass, $divTagInside );
02141     }
02142 /**
02143  * Generates PHP code for a View file that makes an INPUT field, wrapped in a DIV.
02144  *
02145  * @param string $tagName
02146  * @param string $prompt
02147  * @param boolean $required
02148  * @param string $errorMsg
02149  * @param integer $size
02150  * @param array $htmlOptions
02151  * @return Generated HTML and PHP.
02152  */
02153     function generateInputDiv($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null ) {
02154         $htmlAttributes = $htmlOptions;
02155         $htmlAttributes['size'] = $size;
02156         $str = "\t<?php echo \$html->input('{$tagName}', " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
02157         $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please enter the {$prompt}.');?>\n";
02158          $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
02159         $divClass = "optional";
02160 
02161         if ($required) {
02162             $divClass = "required";
02163         }
02164         $strError = "";
02165         $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
02166         return $this->divTag( $divClass, $divTagInside );
02167     }
02168 
02169 /**
02170  * Generates PHP code for a View file that makes a SELECT box, wrapped in a DIV.
02171  *
02172  * @param string $tagName
02173  * @param string $prompt
02174  * @param array $options
02175  * @param string $selected
02176  * @param array $selectAttr
02177  * @param array $optionAttr
02178  * @param boolean $required
02179  * @param string $errorMsg
02180  * @return Generated HTML and PHP.
02181  */
02182     function generateSelectDiv($tagName, $prompt, $options, $selected=null, $selectAttr=null, $optionAttr=null, $required=false,  $errorMsg=null) {
02183 
02184         if ($this->__modelAlias) {
02185             $pluralName = $this->__pluralName($this->__modelAlias);
02186         } else {
02187             $tagArray = explode('/', $tagName);
02188             $pluralName = $this->__pluralName($this->__modelNameFromKey($tagArray[1]));
02189         }
02190         $showEmpty = 'true';
02191         if ($required) {
02192             $showEmpty = 'false';
02193         }
02194         if ($selectAttr['multiple'] != 'multiple') {
02195             $str = "\t<?php echo \$html->selectTag('{$tagName}', " . "\${$pluralName}, \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($selectAttr) . ", " . $this->__attributesToArray($optionAttr) . ", " . $showEmpty . ");?>\n";
02196             $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.') ?>\n";
02197         } else {
02198             $selectedPluralName = 'selected' . ucfirst($pluralName);
02199             $selectAttr = am(array('multiple' => 'multiple', 'class' => 'selectMultiple'), $selectAttr);
02200             $str = "\t<?php echo \$html->selectTag('{$tagName}', \${$pluralName}, \${$selectedPluralName}, " . $this->__attributesToArray($selectAttr) . ", " . $this->__attributesToArray($optionAttr) . ", " . $showEmpty . ");?>\n";
02201             $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
02202         }
02203         $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
02204         $divClass = "optional";
02205 
02206         if ($required) {
02207             $divClass = "required";
02208         }
02209         $strError = "";
02210         $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
02211         return $this->divTag( $divClass, $divTagInside );
02212     }
02213 /**
02214  * Generates PHP code for a View file that makes a submit button, wrapped in a DIV.
02215  *
02216  * @param string $displayText
02217  * @param array $htmlOptions
02218  * @return Generated HTML.
02219  */
02220     function generateSubmitDiv($displayText, $htmlOptions = null) {
02221         $str = "\n\t<?php echo \$html->submit('{$displayText}');?>\n";
02222         $divTagInside = sprintf( "%s", $str );
02223         return $this->divTag( 'submit', $divTagInside);
02224     }
02225 /**
02226  * Returns the text wrapped in an HTML DIV, followed by a newline.
02227  *
02228  * @param string $class
02229  * @param string $text
02230  * @return Generated HTML.
02231  */
02232     function divTag($class, $text) {
02233         return sprintf('<div class="%s">%s</div>', $class, $text ) . "\n";
02234     }
02235 /**
02236  * Parses the HTML attributes array, which is a common data structure in View files.
02237  * Returns PHP code for initializing this array in a View file.
02238  *
02239  * @param array $htmlAttributes
02240  * @return Generated PHP code.
02241  */
02242     function __attributesToArray($htmlAttributes) {
02243         if (is_array($htmlAttributes)) {
02244             $keys = array_keys($htmlAttributes);
02245             $vals = array_values($htmlAttributes);
02246             $out = "array(";
02247 
02248             for ($i = 0; $i < count($htmlAttributes); $i++) {
02249                 if (substr($vals[$i], 0, 1) != '$') {
02250                     $out .= "'{$keys[$i]}' => '{$vals[$i]}', ";
02251                 } else {
02252                     $out .= "'{$keys[$i]}' => {$vals[$i]}, ";
02253                 }
02254             }
02255             if (substr($out, -2, 1) == ',') {
02256                 $out = substr($out, 0, strlen($out) - 2);
02257             }
02258             $out .= ")";
02259             return $out;
02260         } else {
02261             return 'array()';
02262         }
02263     }
02264 /**
02265  * Outputs usage text on the standard output.
02266  *
02267  */
02268     function help() {
02269         $this->stdout('CakePHP Bake:');
02270         $this->hr();
02271         $this->stdout('The Bake script generates controllers, views and models for your application.');
02272         $this->stdout('If run with no command line arguments, Bake guides the user through the class');
02273         $this->stdout('creation process. You can customize the generation process by telling Bake');
02274         $this->stdout('where different parts of your application are using command line arguments.');
02275         $this->stdout('');
02276         $this->hr('');
02277         $this->stdout('usage: php bake.php [command] [path...]');
02278         $this->stdout('');
02279         $this->stdout('commands:');
02280         $this->stdout('   -app [path...] Absolute path to Cake\'s app Folder.');
02281         $this->stdout('   -core [path...] Absolute path to Cake\'s cake Folder.');
02282         $this->stdout('   -help Shows this help message.');
02283         $this->stdout('   -project [path...]  Generates a new app folder in the path supplied.');
02284         $this->stdout('   -root [path...] Absolute path to Cake\'s \app\webroot Folder.');
02285         $this->stdout('');
02286     }
02287 /**
02288  * Checks that given project path does not already exist, and
02289  * finds the app directory in it. Then it calls __buildDirLayout() with that information.
02290  *
02291  * @param string $projectPath
02292  */
02293     function project($projectPath = null) {
02294         if ($projectPath != '') {
02295             while ($this->__checkPath($projectPath) === true && $this->__checkPath(CONFIGS) === true) {
02296                 $response = $this->getInput('Bake -app in '.$projectPath, array('y','n'), 'y');
02297                 if (low($response) == 'y') {
02298                     $this->main();
02299                     exit();
02300                 } else {
02301                     $projectPath = $this->getInput("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
02302                 }
02303             }
02304         } else {
02305             while ($projectPath == '') {
02306                 $projectPath = $this->getInput("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
02307 
02308                 if ($projectPath == '') {
02309                     $this->stdout('The directory path you supplied was empty. Please try again.');
02310                 }
02311             }
02312         }
02313         while ($newPath != 'y' && ($this->__checkPath($projectPath) === true || $projectPath == '')) {
02314                 $newPath = $this->getInput('Directory '.$projectPath.'  exists. Overwrite (y) or insert a new path', null, 'y');
02315                 if ($newPath != 'y') {
02316                     $projectPath = $newPath;
02317                 }
02318             while ($projectPath == '') {
02319                 $projectPath = $this->getInput('The directory path you supplied was empty. Please try again.');
02320             }
02321         }
02322         $parentPath = explode(DS, $projectPath);
02323         $count = count($parentPath);
02324         $appName = $parentPath[$count - 1];
02325         if ($appName == '') {
02326             $appName = $parentPath[$count - 2];
02327         }
02328         $this->__buildDirLayout($projectPath, $appName);
02329         exit();
02330     }
02331 /**
02332  * Returns true if given path is a directory.
02333  *
02334  * @param string $projectPath
02335  * @return True if given path is a directory.
02336  */
02337     function __checkPath($projectPath) {
02338         if (is_dir($projectPath)) {
02339             return true;
02340         } else {
02341             return false;
02342         }
02343     }
02344 /**
02345  * Looks for a skeleton template of a Cake application,
02346  * and if not found asks the user for a path. When there is a path
02347  * this method will make a deep copy of the skeleton to the project directory.
02348  * A default home page will be added, and the tmp file storage will be chmod'ed to 0777.
02349  *
02350  * @param string $projectPath
02351  * @param string $appName
02352  */
02353     function __buildDirLayout($projectPath, $appName) {
02354         $skel = '';
02355         if ($this->__checkPath(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'skel') === true) {
02356             $skel = CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'skel';
02357         } else {
02358 
02359             while ($skel == '') {
02360                 $skel = $this->getInput("What is the full path for the cake install app directory?\nExample: ", null, ROOT.'myapp'.DS);
02361 
02362                 if ($skel == '') {
02363                     $this->stdout('The directory path you supplied was empty. Please try again.');
02364                 } else {
02365                     while ($this->__checkPath($skel) === false) {
02366                         $skel = $this->getInput('Directory path does not exist please choose another:');
02367                     }
02368                 }
02369             }
02370         }
02371         $this->stdout('');
02372         $this->hr();
02373         $this->stdout("Skel Directory: $skel");
02374         $this->stdout("Will be copied to:");
02375         $this->stdout("New App Directory: $projectPath");
02376         $this->hr();
02377         $looksGood = $this->getInput('Look okay?', array('y', 'n', 'q'), 'y');
02378 
02379         if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
02380             $verboseOuptut = $this->getInput('Do you want verbose output?', array('y', 'n'), 'n');
02381             $verbose = false;
02382 
02383             if (low($verboseOuptut) == 'y' || low($verboseOuptut) == 'yes') {
02384                 $verbose = true;
02385             }
02386             $this->__copydirr($skel, $projectPath, 0755, $verbose);
02387             $this->hr();
02388             $this->stdout('Created: '.$projectPath);
02389             $this->hr();
02390             $this->stdout('Creating welcome page');
02391             $this->hr();
02392             $this->__defaultHome($projectPath, $appName);
02393             $this->stdout('Welcome page created');
02394             if (chmodr($projectPath.DS.'tmp', 0777) === false) {
02395                 $this->stdout('Could not set permissions on '. $projectPath.DS.'tmp'.DS.'*');
02396                 $this->stdout('You must manually check that these directories can be wrote to by the server');
02397             }
02398             return;
02399         } elseif (low($looksGood) == 'q' || low($looksGood) == 'quit') {
02400             $this->stdout('Bake Aborted.');
02401         } else {
02402             $this->project();
02403         }
02404     }
02405 /**
02406  * Recursive directory copy.
02407  *
02408  * @param string $fromDir
02409  * @param string $toDir
02410  * @param octal $chmod
02411  * @param boolean    $verbose
02412  * @return Success.
02413  */
02414     function __copydirr($fromDir, $toDir, $chmod = 0755, $verbose = false) {
02415         $errors=array();
02416         $messages=array();
02417 
02418         uses('folder');
02419         $folder = new Folder($toDir, true, 0755);
02420 
02421         if (!is_writable($toDir)) {
02422             $errors[]='target '.$toDir.' is not writable';
02423         }
02424 
02425         if (!is_dir($fromDir)) {
02426             $errors[]='source '.$fromDir.' is not a directory';
02427         }
02428 
02429         if (!empty($errors)) {
02430             if ($verbose) {
02431                 foreach ($errors as $err) {
02432                     $this->stdout('Error: '.$err);
02433                 }
02434             }
02435             return false;
02436         }
02437         $exceptions=array('.','..','.svn');
02438         $handle = opendir($fromDir);
02439 
02440         while (false!==($item = readdir($handle))) {
02441             if (!in_array($item,$exceptions)) {
02442                 $from = $folder->addPathElement($fromDir, $item);
02443                 $to = $folder->addPathElement($toDir, $item);
02444                 if (is_file($from)) {
02445                     if (@copy($from, $to)) {
02446                         chmod($to, $chmod);
02447                         touch($to, filemtime($from));
02448                         $messages[]='File copied from '.$from.' to '.$to;
02449                     } else {
02450                         $errors[]='cannot copy file from '.$from.' to '.$to;
02451                     }
02452                 }
02453 
02454                 if (is_dir($from)) {
02455                     if (@mkdir($to)) {
02456                         chmod($to,$chmod);
02457                         $messages[]='Directory created: '.$to;
02458                     } else {
02459                         $errors[]='cannot create directory '.$to;
02460                     }
02461                     $this->__copydirr($from,$to,$chmod,$verbose);
02462                 }
02463             }
02464         }
02465         closedir($handle);
02466 
02467         if ($verbose) {
02468             foreach ($errors as $err) {
02469                 $this->stdout('Error: '.$err);
02470             }
02471             foreach ($messages as $msg) {
02472                 $this->stdout($msg);
02473             }
02474         }
02475         return true;
02476     }
02477 
02478     function __addAdminRoute($name) {
02479         $file = file_get_contents(CONFIGS.'core.php');
02480         if (preg_match('%([/\\t\\x20]*define\\(\'CAKE_ADMIN\',[\\t\\x20\'a-z]*\\);)%', $file, $match)) {
02481             $result = str_replace($match[0], 'define(\'CAKE_ADMIN\', \''.$name.'\');', $file);
02482 
02483             if (file_put_contents(CONFIGS.'core.php', $result)) {
02484                 return true;
02485             } else {
02486                 return false;
02487             }
02488         } else {
02489             return false;
02490         }
02491     }
02492 /**
02493  * Outputs an ASCII art banner to standard output.
02494  *
02495  */
02496     function welcome()
02497     {
02498         $this->stdout('');
02499         $this->stdout(' ___  __  _  _  ___  __  _  _  __      __   __  _  _  ___ ');
02500         $this->stdout('|    |__| |_/  |__  |__] |__| |__]    |__] |__| |_/  |__ ');
02501         $this->stdout('|___ |  | | \_ |___ |    |  | |       |__] |  | | \_ |___ ');
02502         $this->hr();
02503         $this->stdout('');
02504     }
02505 /**
02506  * Writes a file with a default home page to the project.
02507  *
02508  * @param string $dir
02509  * @param string $app
02510  */
02511     function __defaultHome($dir, $app) {
02512         $path = $dir.DS.'views'.DS.'pages'.DS;
02513         include(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'views'.DS.'home.thtml');
02514         $this->__createFile($path.'home.thtml', $output);
02515     }
02516 /**
02517  * creates the proper pluralize controller for the url
02518  *
02519  * @param string $name must be a controller name in pluralized form
02520  * @return string $name
02521  */
02522     function __controllerPath($name) {
02523         return low(Inflector::underscore($name));
02524     }
02525 /**
02526  * creates the proper pluralize controller class name.
02527  *
02528  * @param string $name
02529  * @return string $name
02530  */
02531     function __controllerName($name) {
02532         return Inflector::pluralize(Inflector::camelize($name));
02533     }
02534 /**
02535  * creates the proper singular model name.
02536  *
02537  * @param string $name
02538  * @return string $name
02539  */
02540     function __modelName($name) {
02541         return Inflector::camelize(Inflector::singularize($name));
02542     }
02543 /**
02544  * creates the proper singular model key for associations.
02545  *
02546  * @param string $name
02547  * @return string $name
02548  */
02549     function __modelKey($name) {
02550         return Inflector::underscore(Inflector::singularize($name)).'_id';
02551     }
02552 /**
02553  * creates the proper model name from a foreign key.
02554  *
02555  * @param string $key
02556  * @return string $name
02557  */
02558     function __modelNameFromKey($key) {
02559         $name = str_replace('_id', '',$key);
02560         return $this->__modelName($name);
02561     }
02562 /**
02563  * creates the singular name for use in views.
02564  *
02565  * @param string $name
02566  * @return string $name
02567  */
02568     function __singularName($name) {
02569         return Inflector::variable(Inflector::singularize($name));
02570     }
02571 /**
02572  * creates the plural name for views.
02573  *
02574  * @param string $name
02575  * @return string $name
02576  */
02577     function __pluralName($name) {
02578         return Inflector::variable(Inflector::pluralize($name));
02579     }
02580 /**
02581  * creates the singular human name used in views
02582  *
02583  * @param string $name
02584  * @return string $name
02585  */
02586     function __singularHumanName($name) {
02587         return Inflector::humanize(Inflector::underscore(Inflector::singularize($name)));
02588     }
02589 /**
02590  * creates the plural humna name used in views
02591  *
02592  * @param string $name
02593  * @return string $name
02594  */
02595     function __pluralHumanName($name) {
02596         return Inflector::humanize(Inflector::underscore(Inflector::pluralize($name)));
02597     }
02598 /**
02599  * outputs the a list of possible models or controllers from database
02600  *
02601  * @param string $useDbConfig
02602  * @param string $type = Models or Controllers
02603  * @return output
02604  */
02605     function __doList($useDbConfig = 'default', $type = 'Models') {
02606         $db =& ConnectionManager::getDataSource($useDbConfig);
02607         $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
02608         if ($usePrefix) {
02609             $tables = array();
02610             foreach ($db->listSources() as $table) {
02611                 if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
02612                     $tables[] = substr($table, strlen($usePrefix));
02613                 }
02614             }
02615         } else {
02616             $tables = $db->listSources();
02617         }
02618         $this->__tables = $tables;
02619         $this->stdout('Possible '.$type.' based on your current database:');
02620         $this->__controllerNames = array();
02621         $this->__modelNames = array();
02622         $count = count($tables);
02623         for ($i = 0; $i < $count; $i++) {
02624             if (low($type) == 'controllers') {
02625                 $this->__controllerNames[] = $this->__controllerName($this->__modelName($tables[$i]));
02626                 $this->stdout($i + 1 . ". " . $this->__controllerNames[$i]);
02627             } else {
02628                 $this->__modelNames[] = $this->__modelName($tables[$i]);
02629                 $this->stdout($i + 1 . ". " . $this->__modelNames[$i]);
02630             }
02631         }
02632     }
02633 
02634 }
02635 ?>