adding 'cake bake all' see cake bake help for more info, also refactored tasks (api changes) and class registry, closes #1470, closes #3612, closes #2697, closes #3412

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6198 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
gwoo 2007-12-22 19:24:56 +00:00
parent d03e8d680f
commit 0a703ef8c0
6 changed files with 493 additions and 323 deletions

View file

@ -53,7 +53,7 @@ class BakeShell extends Shell {
if (isset($this->{$task})) {
$path = Inflector::underscore(Inflector::pluralize($this->command));
$this->{$task}->path = $this->params['working'] . DS . $path . DS;
if(!is_dir($this->{$task}->path)) {
if (!is_dir($this->{$task}->path)) {
$this->err(sprintf(__("%s directory could not be found.\nBe sure you have created %s", true), $task, $this->{$task}->path));
exit();
}
@ -110,6 +110,73 @@ class BakeShell extends Shell {
$this->hr();
$this->main();
}
/**
* Quickly bake the MVC
*
* @access public
*/
function all() {
$ds = 'default';
$this->hr();
$this->out('Bake All');
$this->hr();
if (isset($this->params['connection'])) {
$ds = $this->params['connection'];
}
if (empty($this->args)) {
$name = $this->Model->getName($ds);
}
if (!empty($this->args[0])) {
$name = $this->args[0];
$this->Model->listAll($ds, false);
}
$modelExists = false;
$model = $this->_modelName($name);
if (App::import('Model', $model)) {
$object = new $model();
$modelExists = true;
} else {
App::import('Model');
$object = new Model(array('name' => $name, 'ds' => $ds));
}
$modelBaked = $this->Model->bake($object, false);
if ($modelBaked && $modelExists === false) {
$this->out(sprintf(__('%s Model was baked.', true), $model));
if ($this->_checkUnitTest()) {
$this->Model->bakeTest($model);
}
$modelExists = true;
}
if ($modelExists === true) {
$controller = $this->_controllerName($name);
if ($this->Controller->bake($controller, $this->Controller->bakeActions($controller))) {
$this->out(sprintf(__('%s Controller was baked.', true), $name));
if ($this->_checkUnitTest()) {
$this->Controller->bakeTest($controller);
}
}
if (App::import('Controller', $controller)) {
$this->View->args = array($controller);
$this->View->execute();
}
$this->out(__('Bake All complete'));
} else {
$this->err(__('Bake All could not continue without a valid model', true));
}
if (empty($this->args)) {
$this->all();
}
exit();
}
/**
* Displays help contents
*
@ -129,6 +196,7 @@ class BakeShell extends Shell {
$this->out("\t-app <path> Absolute/Relative path to your app folder.\n");
$this->out('Commands:');
$this->out("\n\tbake help\n\t\tshows this help message.");
$this->out("\n\tbake all <name>\n\t\tbakes complete MVC. optional <name> of a Model");
$this->out("\n\tbake project <path>\n\t\tbakes a new app folder in the path supplied\n\t\tor in current directory if no path is specified");
$this->out("\n\tbake db_config\n\t\tbakes a database.php file in config directory.");
$this->out("\n\tbake model\n\t\tbakes a model. run 'bake model help' for more info");

View file

@ -255,45 +255,37 @@ class Shell extends Object {
}
foreach ($tasks as $taskName) {
$loaded = false;
foreach ($this->Dispatch->shellPaths as $path) {
$taskPath = $path . 'tasks' . DS . Inflector::underscore($taskName).'.php';
if (file_exists($taskPath)) {
$loaded = true;
break;
$taskKey = Inflector::underscore($taskName);
$taskClass = Inflector::camelize($taskName.'Task');
if (!class_exists($taskClass)) {
foreach ($this->Dispatch->shellPaths as $path) {
$taskPath = $path . 'tasks' . DS . Inflector::underscore($taskName).'.php';
if (file_exists($taskPath)) {
require_once $taskPath;
break;
}
}
}
if (ClassRegistry::isKeySet($taskKey)) {
$this->taskNames[] = $taskName;
if (!PHP5) {
$this->{$taskName} =& ClassRegistry::getObject($taskKey);
ClassRegistry::map($taskName, $taskKey);
} else {
$this->{$taskName} = ClassRegistry::getObject($taskKey);
ClassRegistry::map($taskName, $taskKey);
}
} else {
$this->taskNames[] = $taskName;
if (!PHP5) {
$this->{$taskName} =& new $taskClass($this->Dispatch);
} else {
$this->{$taskName} = new $taskClass($this->Dispatch);
}
}
if ($loaded) {
$taskKey = Inflector::underscore($taskName);
$taskClass = Inflector::camelize($taskName.'Task');
if (!class_exists($taskClass)) {
require_once $taskPath;
}
if (ClassRegistry::isKeySet($taskKey)) {
$this->taskNames[] = $taskName;
if (!PHP5) {
$this->{$taskName} =& ClassRegistry::getObject($taskKey);
ClassRegistry::map($taskName, $taskKey);
} else {
$this->{$taskName} = ClassRegistry::getObject($taskKey);
ClassRegistry::map($taskName, $taskKey);
}
} else {
$this->taskNames[] = $taskName;
if (!PHP5) {
$this->{$taskName} =& new $taskClass($this->Dispatch);
} else {
$this->{$taskName} = new $taskClass($this->Dispatch);
}
}
if (!isset($this->{$taskName})) {
$this->err("Task '".$taskName."' could not be loaded");
exit();
}
} else {
$this->err("Task '".$taskName."' could not be found");
if (!isset($this->{$taskName})) {
$this->err("Task '".$taskName."' could not be loaded");
exit();
}
}

View file

@ -69,7 +69,7 @@ class ControllerTask extends Shell {
$actions = null;
if (isset($this->args[1]) && $this->args[1] == 'scaffold') {
$this->out('Baking scaffold for ' . $controller);
$actions = $this->__bakeActions($controller);
$actions = $this->bakeActions($controller);
} else {
$actions = 'scaffold';
}
@ -77,15 +77,15 @@ class ControllerTask extends Shell {
if ($admin = $this->getAdmin()) {
$this->out('Adding ' . Configure::read('Routing.admin') .' methods');
if ($actions == 'scaffold') {
$actions = $this->__bakeActions($controller, $admin);
$actions = $this->bakeActions($controller, $admin);
} else {
$actions .= $this->__bakeActions($controller, $admin);
$actions .= $this->bakeActions($controller, $admin);
}
}
}
if ($this->__bake($controller, $actions)) {
if ($this->bake($controller, $actions)) {
if ($this->_checkUnitTest()) {
$this->__bakeTest($controller);
$this->bakeTest($controller);
}
}
}
@ -169,9 +169,9 @@ class ControllerTask extends Shell {
}
if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
$actions = $this->__bakeActions($controllerName, null, in_array(low($wannaUseSession), array('y', 'yes')));
$actions = $this->bakeActions($controllerName, null, in_array(low($wannaUseSession), array('y', 'yes')));
if ($admin) {
$actions .= $this->__bakeActions($controllerName, $admin, in_array(low($wannaUseSession), array('y', 'yes')));
$actions .= $this->bakeActions($controllerName, $admin, in_array(low($wannaUseSession), array('y', 'yes')));
}
}
@ -214,17 +214,17 @@ class ControllerTask extends Shell {
$looksGood = $this->in(__('Look okay?', true), array('y','n'), 'y');
if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
$baked = $this->__bake($controllerName, $actions, $helpers, $components, $uses);
$baked = $this->bake($controllerName, $actions, $helpers, $components, $uses);
if ($baked && $this->_checkUnitTest()) {
$this->__bakeTest($controllerName);
$this->bakeTest($controllerName);
}
} else {
$this->__interactive($controllerName);
}
} else {
$baked = $this->__bake($controllerName, $actions, $helpers, $components, $uses);
$baked = $this->bake($controllerName, $actions, $helpers, $components, $uses);
if ($baked && $this->_checkUnitTest()) {
$this->__bakeTest($controllerName);
$this->bakeTest($controllerName);
}
}
}
@ -237,7 +237,7 @@ class ControllerTask extends Shell {
* @return string Baked actions
* @access private
*/
function __bakeActions($controllerName, $admin = null, $wannaUseSession = true) {
function bakeActions($controllerName, $admin = null, $wannaUseSession = true) {
$currentModelName = $this->_modelName($controllerName);
if (!App::import('Model', $currentModelName)) {
$this->err('You must have a model for this class to build scaffold methods. Please try again.');
@ -398,7 +398,7 @@ class ControllerTask extends Shell {
* @return string Baked controller
* @access private
*/
function __bake($controllerName, $actions = '', $helpers = null, $components = null, $uses = null) {
function bake($controllerName, $actions = '', $helpers = null, $components = null, $uses = null) {
$out = "<?php\n";
$out .= "class $controllerName" . "Controller extends AppController {\n\n";
$out .= "\tvar \$name = '$controllerName';\n";
@ -453,7 +453,7 @@ class ControllerTask extends Shell {
* @return string Baked test
* @access private
*/
function __bakeTest($className) {
function bakeTest($className) {
$out = '<?php '."\n\n";
$out .= "App::import('Controller', '$className');\n\n";
$out .= "class {$className}ControllerTestCase extends CakeTestCase {\n";

View file

@ -36,7 +36,7 @@ class ModelTask extends Shell {
/**
* path to MODELS directory
*
* @var array
* @var string
* @access public
*/
var $path = MODELS;
@ -52,9 +52,9 @@ class ModelTask extends Shell {
if (!empty($this->args[0])) {
$model = $this->args[0];
if ($this->__bake($model)) {
if ($this->bake($model)) {
if ($this->_checkUnitTest()) {
$this->__bakeTest($model);
$this->bakeTest($model);
}
}
}
@ -77,15 +77,16 @@ class ModelTask extends Shell {
$useDbConfig = 'default';
$connections = array_keys(get_class_vars('DATABASE_CONFIG'));
if(count($connections) > 1) {
if (count($connections) > 1) {
$useDbConfig = $this->in(__('Use Database Config', true) .':', $connections, 'default');
}
$currentModelName = $this->getName($useDbConfig);
$db =& ConnectionManager::getDataSource($useDbConfig);
$tableIsGood = false;
$useTable = Inflector::tableize($currentModelName);
$fullTableName = $db->fullTableName($useTable, false);
$tableIsGood = false;
if (array_search($useTable, $this->__tables) === false) {
$this->out('');
$this->out(sprintf(__("Given your model named '%s', Cake would expect a database table named %s", true), $currentModelName, $fullTableName));
@ -95,6 +96,7 @@ class ModelTask extends Shell {
if (low($tableIsGood) == 'n' || low($tableIsGood) == 'no') {
$useTable = $this->in(__('What is the name of the table (enter "null" to use NO table)?', true));
}
while ($tableIsGood == false && low($useTable) != 'null') {
if (is_array($this->__tables) && !in_array($useTable, $this->__tables)) {
$fullTableName = $db->fullTableName($useTable, false);
@ -105,228 +107,37 @@ class ModelTask extends Shell {
$tableIsGood = true;
}
}
$wannaDoValidation = $this->in(__('Would you like to supply validation criteria for the fields in your model?', true), array('y','n'), 'y');
if (in_array($useTable, $this->__tables)) {
App::import('Model');
$tempModel = new Model(false, $useTable, $useDbConfig);
$modelFields = $db->describe($tempModel);
$tempModel = new Model(array('name' => $currentModelName, 'table' => $useTable, 'ds' => $useDbConfig));
if (!array_key_exists('id', $modelFields)) {
foreach ($modelFields as $name => $field) {
break;
$fields = $tempModel->schema();
if (!array_key_exists('id', $fields)) {
foreach ($fields as $name => $field) {
if (isset($field['key']) && $field['key'] == 'primary') {
break;
}
}
$primaryKey = $this->in(__('What is the primaryKey?', true), null, $name);
}
}
$validate = array();
if (array_search($useTable, $this->__tables) !== false && (low($wannaDoValidation) == 'y' || low($wannaDoValidation) == 'yes')) {
foreach ($modelFields as $fieldName => $field) {
$this->out('');
$prompt = 'Name: ' . $fieldName . "\n";
$prompt .= 'Type: ' . $field['type'] . "\n";
$prompt .= '---------------------------------------------------------------'."\n";
$prompt .= 'Please select one of the following validation options:'."\n";
$prompt .= '---------------------------------------------------------------'."\n";
$prompt .= "1- VALID_NOT_EMPTY\n";
$prompt .= "2- VALID_EMAIL\n";
$prompt .= "3- VALID_NUMBER\n";
$prompt .= "4- VALID_YEAR\n";
$prompt .= "5- Do not do any validation on this field.\n\n";
$prompt .= "... or enter in a valid regex validation string.\n\n";
if ($field['null'] == 1 || $fieldName == $primaryKey || $fieldName == 'created' || $fieldName == 'modified') {
$validation = $this->in($prompt, null, '5');
} else {
$validation = $this->in($prompt, null, '1');
}
switch ($validation) {
case '1':
$validate[$fieldName] = 'VALID_NOT_EMPTY';
break;
case '2':
$validate[$fieldName] = 'VALID_EMAIL';
break;
case '3':
$validate[$fieldName] = 'VALID_NUMBER';
break;
case '4':
$validate[$fieldName] = 'VALID_YEAR';
break;
case '5':
break;
default:
$validate[$fieldName] = $validation;
break;
}
}
$validate = $this->doValidation($tempModel);
}
$wannaDoAssoc = $this->in(__('Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)?', true), array('y','n'), 'y');
if ((low($wannaDoAssoc) == 'y' || low($wannaDoAssoc) == 'yes')) {
$this->out(__('One moment while the associations are detected.', true));
$possibleKeys = array();
//Look for belongsTo
$i = 0;
foreach ($modelFields as $fieldName => $field) {
$offset = strpos($fieldName, '_id');
if ($fieldName != $primaryKey && $offset !== false) {
$tmpModelName = $this->_modelNameFromKey($fieldName);
$associations['belongsTo'][$i]['alias'] = $tmpModelName;
$associations['belongsTo'][$i]['className'] = $tmpModelName;
$associations['belongsTo'][$i]['foreignKey'] = $fieldName;
$i++;
}
}
//Look for hasOne and hasMany and hasAndBelongsToMany
$i = $j = 0;
foreach ($this->__tables as $otherTable) {
$tempOtherModel = & new Model(false, $otherTable, $useDbConfig);
$modelFieldsTemp = $db->describe($tempOtherModel);
foreach ($modelFieldsTemp as $fieldName => $field) {
if ($field['type'] == 'integer' || $field['type'] == 'string') {
$possibleKeys[$otherTable][] = $fieldName;
}
if ($fieldName != $primaryKey && $fieldName == $this->_modelKey($currentModelName)) {
$tmpModelName = $this->_modelName($otherTable);
$associations['hasOne'][$j]['alias'] = $tmpModelName;
$associations['hasOne'][$j]['className'] = $tmpModelName;
$associations['hasOne'][$j]['foreignKey'] = $fieldName;
$associations['hasMany'][$j]['alias'] = $tmpModelName;
$associations['hasMany'][$j]['className'] = $tmpModelName;
$associations['hasMany'][$j]['foreignKey'] = $fieldName;
$j++;
}
}
$offset = strpos($otherTable, $useTable . '_');
if ($offset !== false) {
$offset = strlen($useTable . '_');
$tmpModelName = $this->_modelName(substr($otherTable, $offset));
$associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
$associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
$associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->_modelKey($currentModelName);
$associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->_modelKey($tmpModelName);
$associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
$i++;
}
$offset = strpos($otherTable, '_' . $useTable);
if ($offset !== false) {
$tmpModelName = $this->_modelName(substr($otherTable, 0, $offset));
$associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
$associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
$associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->_modelKey($currentModelName);
$associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->_modelKey($tmpModelName);
$associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
$i++;
}
}
$this->hr();
if (empty($associations)) {
$this->out(__('None found.', true));
} else {
$this->out(__('Please confirm the following associations:', true));
$this->hr();
foreach ($associations as $type => $settings) {
if (!empty($associations[$type])) {
$count = count($associations[$type]);
$response = 'y';
for ($i = 0; $i < $count; $i++) {
if ($currentModelName === $associations[$type][$i]['alias']) {
$prompt = "{$currentModelName} {$type} {$associations[$type][$i]['alias']}\n";
$prompt .= __("This looks like a self join. Please specify an alternate association alias.", true);
$associations[$type][$i]['alias'] = $this->in($prompt, null, $associations[$type][$i]['alias']);
} else {
$prompt = "{$currentModelName} {$type} {$associations[$type][$i]['alias']}";
$response = $this->in("{$prompt}?", array('y','n'), 'y');
}
if ('n' == low($response) || 'no' == low($response)) {
unset($associations[$type][$i]);
}
}
$associations[$type] = array_merge($associations[$type]);
}
}
}
$wannaDoMoreAssoc = $this->in(__('Would you like to define some additional model associations?', true), array('y','n'), 'n');
while ((low($wannaDoMoreAssoc) == 'y' || low($wannaDoMoreAssoc) == 'yes')) {
$assocs = array(1 => 'belongsTo', 2 => 'hasOne', 3 => 'hasMany', 4 => 'hasAndBelongsToMany');
$bad = true;
while ($bad) {
$this->out(__('What is the association type?', true));
$prompt = "1. belongsTo\n";
$prompt .= "2. hasOne\n";
$prompt .= "3. hasMany\n";
$prompt .= "4. hasAndBelongsToMany\n";
$assocType = intval($this->in($prompt, null, __("Enter a number", true)));
if (intval($assocType) < 1 || intval($assocType) > 4) {
$this->out(__('The selection you entered was invalid. Please enter a number between 1 and 4.', true));
} else {
$bad = false;
}
}
$this->out(__('For the following options be very careful to match your setup exactly. Any spelling mistakes will cause errors.', true));
$this->hr();
$alias = $this->in(__('What is the alias for this association?', true));
$className = $this->in(sprintf(__('What className will %s use?', true), $alias), null, $alias );
$suggestedForeignKey = null;
if ($assocType == '1') {
$showKeys = $possibleKeys[$useTable];
$suggestedForeignKey = $this->_modelKey($alias);
} else {
$otherTable = Inflector::tableize($className);
if (in_array($otherTable, $this->__tables)) {
if ($assocType < '4') {
$showKeys = $possibleKeys[$otherTable];
} else {
$showKeys = null;
}
} else {
$otherTable = $this->in(__('What is the table for this model?', true));
$showKeys = $possibleKeys[$otherTable];
}
$suggestedForeignKey = $this->_modelKey($currentModelName);
}
if (!empty($showKeys)) {
$this->out(__('A helpful List of possible keys', true));
for ($i = 0; $i < count($showKeys); $i++) {
$this->out($i + 1 . ". " . $showKeys[$i]);
}
$foreignKey = $this->in(__('What is the foreignKey?', true), null, __("Enter a number", true));
if (intval($foreignKey) > 0 && intval($foreignKey) <= $i ) {
$foreignKey = $showKeys[intval($foreignKey) - 1];
}
}
if (!isset($foreignKey)) {
$foreignKey = $this->in(__('What is the foreignKey? Specify your own.', true), null, $suggestedForeignKey);
}
if ($assocType == '4') {
$associationForeignKey = $this->in(__('What is the associationForeignKey?', true), null, $this->_modelKey($currentModelName));
$joinTable = $this->in(__('What is the joinTable?', true));
}
$associations[$assocs[$assocType]] = array_values($associations[$assocs[$assocType]]);
$count = count($associations[$assocs[$assocType]]);
$i = ($count > 0) ? $count : 0;
$associations[$assocs[$assocType]][$i]['alias'] = $alias;
$associations[$assocs[$assocType]][$i]['className'] = $className;
$associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
if ($assocType == '4') {
$associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
$associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
}
$wannaDoMoreAssoc = $this->in(__('Define another association?', true), array('y','n'), 'y');
}
$associations = $this->doAssociations($tempModel);
}
$this->out('');
$this->hr();
$this->out(__('The following model will be created:', true));
$this->out(__('The following Model will be created:', true));
$this->hr();
$this->out("Name: " . $currentModelName);
$this->out("DB Config: " . $useDbConfig);
@ -368,27 +179,307 @@ class ModelTask extends Shell {
$looksGood = $this->in(__('Look okay?', true), array('y','n'), 'y');
if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
if ($this->__bake($currentModelName, $useDbConfig, $useTable, $primaryKey, $validate, $associations)) {
if ($this->bake($currentModelName, $associations, $validate, $primaryKey, $useTable, $useDbConfig)) {
if ($this->_checkUnitTest()) {
$this->__bakeTest($currentModelName);
$this->bakeTest($currentModelName);
}
}
} else {
$this->out('Bake Aborted.');
}
}
/**
* Handles associations
*
* @param object $model
* @param boolean $interactive
* @return array $validate
* @access public
*/
function doValidation(&$model, $interactive = true) {
if (!is_object($model)) {
return false;
}
$fields = $model->schema();
if (empty($fields)) {
return false;
}
$validate = array();
$options = array('VALID_NOT_EMPTY', 'VALID_EMAIL', 'VALID_NUMER', 'VALID_YEAR');
if (class_exists('Validation')) {
$parent = get_class_methods(get_parent_class('Validation'));
$options = array_diff(get_class_methods('Validation'), $parent);
$methods = array_flip($options);
}
foreach ($fields as $fieldName => $field) {
$prompt = 'Field: ' . $fieldName . "\n";
$prompt .= 'Type: ' . $field['type'] . "\n";
$prompt .= '---------------------------------------------------------------'."\n";
$prompt .= 'Please select one of the following validation options:'."\n";
$prompt .= '---------------------------------------------------------------'."\n";
$skip = 1;
foreach ($options as $key => $option) {
if ($option{0} != '_') {
$prompt .= "{$key} - {$option}\n";
$skip++;
}
}
$prompt .= "{$skip} - Do not do any validation on this field.\n";
$prompt .= "... or enter in a valid regex validation string.\n";
$guess = $skip;
if ($field['null'] != 1 && $fieldName != $model->primaryKey && !in_array($fieldName, array('created', 'modified', 'updated'))) {
if ($fieldName == 'email') {
$guess = $methods['email'];
} elseif ($field['type'] == 'string') {
$guess = $methods['alphaNumeric'];
} elseif ($field['type'] == 'integer') {
$guess = $methods['numeric'];
} elseif ($field['type'] == 'boolean') {
$guess = $methods['numeric'];
} elseif ($field['type'] == 'datetime') {
$guess = $methods['date'];
}
}
if ($interactive === true) {
$this->out('');
$choice = $this->in($prompt, null, $guess);
} else {
$choice = $guess;
}
if ($choice !== $skip) {
if (is_numeric($choice) && isset($options[$choice])) {
$validate[$fieldName] = $options[$choice];
} else {
$validate[$fieldName] = $validation;
}
}
}
return $validate;
}
/**
* Handles associations
*
* @param object $model
* @param boolean $interactive
* @return array $assocaitons
* @access public
*/
function doAssociations(&$model, $interactive = true) {
if (!is_object($model)) {
return false;
}
$fields = $model->schema();
if (empty($fields)) {
return false;
}
$primaryKey = $model->primaryKey;
$foreignKey = $this->_modelKey($model->name);
$associations = $possibleKeys = array();
//Look for belongsTo
$i = 0;
foreach ($fields as $fieldName => $field) {
$offset = strpos($fieldName, '_id');
if ($fieldName != $model->primaryKey && $offset !== false) {
$tmpModelName = $this->_modelNameFromKey($fieldName);
$associations['belongsTo'][$i]['alias'] = $tmpModelName;
$associations['belongsTo'][$i]['className'] = $tmpModelName;
$associations['belongsTo'][$i]['foreignKey'] = $fieldName;
$i++;
}
}
//Look for hasOne and hasMany and hasAndBelongsToMany
$i = $j = 0;
foreach ($this->__tables as $otherTable) {
App::import('Model');
$tmpModelName = $this->_modelName($otherTable);
$tempOtherModel = & new Model(array('name' => $tmpModelName, 'table' => $otherTable, 'ds' => $model->useDbConfig));
$modelFieldsTemp = $tempOtherModel->schema();
$offset = strpos($otherTable, $model->table . '_');
$otherOffset = strpos($otherTable, '_' . $model->table);
foreach ($modelFieldsTemp as $fieldName => $field) {
if ($field['type'] == 'integer' || $field['type'] == 'string') {
$possibleKeys[$otherTable][] = $fieldName;
}
if ($fieldName != $model->primaryKey && $fieldName == $foreignKey && $offset === false && $otherOffset === false) {
$associations['hasOne'][$j]['alias'] = $tempOtherModel->name;
$associations['hasOne'][$j]['className'] = $tempOtherModel->name;
$associations['hasOne'][$j]['foreignKey'] = $fieldName;
$associations['hasMany'][$j]['alias'] = $tempOtherModel->name;
$associations['hasMany'][$j]['className'] = $tempOtherModel->name;
$associations['hasMany'][$j]['foreignKey'] = $fieldName;
$j++;
}
}
if ($offset !== false) {
$offset = strlen($model->table . '_');
$tmpModelName = $this->_modelName(substr($otherTable, $offset));
$associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
$associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
$associations['hasAndBelongsToMany'][$i]['foreignKey'] = $foreignKey;
$associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->_modelKey($tmpModelName);
$associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
$i++;
}
if ($otherOffset !== false) {
$tmpModelName = $this->_modelName(substr($otherTable, 0, $otherOffset));
$associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
$associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
$associations['hasAndBelongsToMany'][$i]['foreignKey'] = $foreignKey;
$associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->_modelKey($tmpModelName);
$associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
$i++;
}
}
if ($interactive !== true) {
unset($associations['hasOne']);
}
if ($interactive === true) {
$this->hr();
if (empty($associations)) {
$this->out(__('None found.', true));
} else {
$this->out(__('Please confirm the following associations:', true));
$this->hr();
foreach ($associations as $type => $settings) {
if (!empty($associations[$type])) {
$count = count($associations[$type]);
$response = 'y';
for ($i = 0; $i < $count; $i++) {
if ($model->name === $associations[$type][$i]['alias']) {
$prompt = "{$model->name} {$type} {$associations[$type][$i]['alias']}\n";
$prompt .= __("This looks like a self join. Please specify an alternate association alias.", true);
$associations[$type][$i]['alias'] = $this->in($prompt, null, $associations[$type][$i]['alias']);
} else {
$prompt = "{$model->name} {$type} {$associations[$type][$i]['alias']}";
$response = $this->in("{$prompt}?", array('y','n'), 'y');
}
if ('n' == low($response) || 'no' == low($response)) {
unset($associations[$type][$i]);
}
}
$associations[$type] = array_merge($associations[$type]);
}
}
}
$wannaDoMoreAssoc = $this->in(__('Would you like to define some additional model associations?', true), array('y','n'), 'n');
while ((low($wannaDoMoreAssoc) == 'y' || low($wannaDoMoreAssoc) == 'yes')) {
$assocs = array(1 => 'belongsTo', 2 => 'hasOne', 3 => 'hasMany', 4 => 'hasAndBelongsToMany');
$bad = true;
while ($bad) {
$this->out(__('What is the association type?', true));
$prompt = "1. belongsTo\n";
$prompt .= "2. hasOne\n";
$prompt .= "3. hasMany\n";
$prompt .= "4. hasAndBelongsToMany\n";
$assocType = intval($this->in($prompt, null, __("Enter a number", true)));
if (intval($assocType) < 1 || intval($assocType) > 4) {
$this->out(__('The selection you entered was invalid. Please enter a number between 1 and 4.', true));
} else {
$bad = false;
}
}
$this->out(__('For the following options be very careful to match your setup exactly. Any spelling mistakes will cause errors.', true));
$this->hr();
$alias = $this->in(__('What is the alias for this association?', true));
$className = $this->in(sprintf(__('What className will %s use?', true), $alias), null, $alias );
$suggestedForeignKey = null;
if ($assocType == '1') {
$showKeys = $possibleKeys[$model->table];
$suggestedForeignKey = $this->_modelKey($alias);
} else {
$otherTable = Inflector::tableize($className);
if (in_array($otherTable, $this->__tables)) {
if ($assocType < '4') {
$showKeys = $possibleKeys[$otherTable];
} else {
$showKeys = null;
}
} else {
$otherTable = $this->in(__('What is the table for this model?', true));
$showKeys = $possibleKeys[$otherTable];
}
$suggestedForeignKey = $this->_modelKey($model->name);
}
if (!empty($showKeys)) {
$this->out(__('A helpful List of possible keys', true));
for ($i = 0; $i < count($showKeys); $i++) {
$this->out($i + 1 . ". " . $showKeys[$i]);
}
$foreignKey = $this->in(__('What is the foreignKey?', true), null, __("Enter a number", true));
if (intval($foreignKey) > 0 && intval($foreignKey) <= $i ) {
$foreignKey = $showKeys[intval($foreignKey) - 1];
}
}
if (!isset($foreignKey)) {
$foreignKey = $this->in(__('What is the foreignKey? Specify your own.', true), null, $suggestedForeignKey);
}
if ($assocType == '4') {
$associationForeignKey = $this->in(__('What is the associationForeignKey?', true), null, $this->_modelKey($model->name));
$joinTable = $this->in(__('What is the joinTable?', true));
}
$associations[$assocs[$assocType]] = array_values($associations[$assocs[$assocType]]);
$count = count($associations[$assocs[$assocType]]);
$i = ($count > 0) ? $count : 0;
$associations[$assocs[$assocType]][$i]['alias'] = $alias;
$associations[$assocs[$assocType]][$i]['className'] = $className;
$associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
if ($assocType == '4') {
$associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
$associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
}
$wannaDoMoreAssoc = $this->in(__('Define another association?', true), array('y','n'), 'y');
}
}
return $associations;
}
/**
* Assembles and writes a Model file.
*
* @param string $name Model name
* @param object $useDbConfig Database configuration setting to use
* @param string $useTable Table to use
* @param string $primaryKey Primary key to use
* @param mixed $name Model name or object
* @param mixed $associations if array and $name is not an object assume Model associations array otherwise boolean interactive
* @param array $validate Validation rules
* @param array $associations Model bindings
* @param string $primaryKey Primary key to use
* @param string $useTable Table to use
* @param string $useDbConfig Database configuration setting to use
* @access private
*/
function __bake($name, $useDbConfig = 'default', $useTable = null, $primaryKey = 'id', $validate = array(), $associations = array()) {
function bake($name, $associations = array(), $validate = array(), $primaryKey = 'id', $useTable = null, $useDbConfig = 'default') {
if (is_object($name)) {
if (!is_array($associations)) {
$associations = $this->doAssociations($name, $associations);
$validate = $this->doValidation($name, $associations);
}
$primaryKey = $name->primaryKey;
$useTable = $name->table;
$useDbConfig = $name->useDbConfig;
$name = $name->name;
}
$out = "<?php\n";
$out .= "class {$name} extends AppModel {\n\n";
$out .= "\tvar \$name = '{$name}';\n";
@ -405,93 +496,119 @@ class ModelTask extends Shell {
$out .= "\tvar \$primaryKey = '$primaryKey';\n";
}
if (count($validate)) {
$validateCount = count($validate);
if ($validateCount > 1) {
$out .= "\tvar \$validate = array(\n";
$keys = array_keys($validate);
for ($i = 0; $i < count($validate); $i++) {
$out .= "\t\t'" . $keys[$i] . "' => " . $validate[$keys[$i]] . ",\n";
for ($i = 0; $i < $validateCount; $i++) {
$out .= "\t\t'" . $keys[$i] . "' => array('" . $validate[$keys[$i]] . "')";
if ($i + 1 < $validateCount) {
$out .= ",";
}
$out .= "\n";
}
$out .= "\t);\n";
}
$out .= "\n";
if (!empty($associations)) {
if(!empty($associations['belongsTo']) || !empty($associations['$hasOne']) || !empty($associations['hasMany']) || !empty($associations['hasAndBelongsToMany'])) {
if (!empty($associations['belongsTo']) || !empty($associations['$hasOne']) || !empty($associations['hasMany']) || !empty($associations['hasAndBelongsToMany'])) {
$out.= "\t//The Associations below have been created with all possible keys, those that are not needed can be removed\n";
}
if (!empty($associations['belongsTo'])) {
$out .= "\tvar \$belongsTo = array(\n";
$belongsToCount = count($associations['belongsTo']);
for ($i = 0; $i < count($associations['belongsTo']); $i++) {
for ($i = 0; $i < $belongsToCount; $i++) {
$out .= "\t\t\t'{$associations['belongsTo'][$i]['alias']}' => ";
$out .= "array('className' => '{$associations['belongsTo'][$i]['className']}',\n";
$out .= "\t\t\t\t\t\t\t\t'foreignKey' => '{$associations['belongsTo'][$i]['foreignKey']}',\n";
$out .= "\t\t\t\t\t\t\t\t'conditions' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'fields' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'order' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'counterCache' => ''";
$out .= "),\n";
$out .= "\t\t\t\t\t\t\t\t'order' => ''\n";
$out .= "\t\t\t)";
if ($i + 1 < $belongsToCount) {
$out .= ",";
}
$out .= "\n";
}
$out .= "\t);\n\n";
}
if (!empty($associations['hasOne'])) {
$out .= "\tvar \$hasOne = array(\n";
$hasOneCount = count($associations['hasOne']);
for ($i = 0; $i < count($associations['hasOne']); $i++) {
for ($i = 0; $i < $hasOneCount; $i++) {
$out .= "\t\t\t'{$associations['hasOne'][$i]['alias']}' => ";
$out .= "array('className' => '{$associations['hasOne'][$i]['className']}',\n";
$out .= "\t\t\t\t\t\t\t\t'foreignKey' => '{$associations['hasOne'][$i]['foreignKey']}',\n";
$out .= "\t\t\t\t\t\t\t\t'dependent' => false,\n";
$out .= "\t\t\t\t\t\t\t\t'conditions' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'fields' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'order' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'dependent' => ''";
$out .= "),\n";
$out .= "\t\t\t\t\t\t\t\t'order' => ''\n";
$out .= "\t\t\t)";
if ($i + 1 < $hasOneCount) {
$out .= ",";
}
$out .= "\n";
}
$out .= "\t);\n\n";
}
if (!empty($associations['hasMany'])) {
$out .= "\tvar \$hasMany = array(\n";
$hasManyCount = count($associations['hasMany']);
for ($i = 0; $i < count($associations['hasMany']); $i++) {
for ($i = 0; $i < $hasManyCount; $i++) {
$out .= "\t\t\t'{$associations['hasMany'][$i]['alias']}' => ";
$out .= "array('className' => '{$associations['hasMany'][$i]['className']}',\n";
$out .= "\t\t\t\t\t\t\t\t'foreignKey' => '{$associations['hasMany'][$i]['foreignKey']}',\n";
$out .= "\t\t\t\t\t\t\t\t'dependent' => false,\n";
$out .= "\t\t\t\t\t\t\t\t'conditions' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'fields' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'order' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'limit' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'offset' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'dependent' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'exclusive' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'finderQuery' => '',\n";
$out .= "\t\t\t\t\t\t\t\t'counterQuery' => ''";
$out .= "),\n";
$out .= "\t\t\t\t\t\t\t\t'counterQuery' => ''\n";
$out .= "\t\t\t)";
if ($i + 1 < $hasManyCount) {
$out .= ",";
}
$out .= "\n";
}
$out .= "\t);\n\n";
}
if (!empty($associations['hasAndBelongsToMany'])) {
$out .= "\tvar \$hasAndBelongsToMany = array(\n";
$hasAndBelongsToManyCount = count($associations['hasAndBelongsToMany']);
for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
for ($i = 0; $i < $hasAndBelongsToManyCount; $i++) {
$out .= "\t\t\t'{$associations['hasAndBelongsToMany'][$i]['alias']}' => ";
$out .= "array('className' => '{$associations['hasAndBelongsToMany'][$i]['className']}',\n";
$out .= "\t\t\t\t\t\t'joinTable' => '{$associations['hasAndBelongsToMany'][$i]['joinTable']}',\n";
$out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasAndBelongsToMany'][$i]['foreignKey']}',\n";
$out .= "\t\t\t\t\t\t'associationForeignKey' => '{$associations['hasAndBelongsToMany'][$i]['associationForeignKey']}',\n";
$out .= "\t\t\t\t\t\t'unique' => true,\n";
$out .= "\t\t\t\t\t\t'conditions' => '',\n";
$out .= "\t\t\t\t\t\t'fields' => '',\n";
$out .= "\t\t\t\t\t\t'order' => '',\n";
$out .= "\t\t\t\t\t\t'limit' => '',\n";
$out .= "\t\t\t\t\t\t'offset' => '',\n";
$out .= "\t\t\t\t\t\t'unique' => '',\n";
$out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
$out .= "\t\t\t\t\t\t'deleteQuery' => '',\n";
$out .= "\t\t\t\t\t\t'insertQuery' => ''";
$out .= "),\n";
$out .= "\t\t\t\t\t\t'insertQuery' => ''\n";
$out .= "\t\t\t)";
if ($i + 1 < $hasAndBelongsToManyCount) {
$out .= ",";
}
$out .= "\n";
}
$out .= "\t);\n\n";
}
@ -508,7 +625,7 @@ class ModelTask extends Shell {
* @param string $className Model class name
* @access private
*/
function __bakeTest($className) {
function bakeTest($className) {
$out = '<?php '."\n\n";
$out .= "App::import('Model', '$className');\n\n";
$out .= "class {$className}TestCase extends CakeTestCase {\n";
@ -533,7 +650,7 @@ class ModelTask extends Shell {
* @param string $useDbConfig Database configuration name
* @access public
*/
function listAll($useDbConfig = 'default') {
function listAll($useDbConfig = 'default', $interactive = true) {
$db =& ConnectionManager::getDataSource($useDbConfig);
$usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
if ($usePrefix) {
@ -547,12 +664,15 @@ class ModelTask extends Shell {
$tables = $db->listSources();
}
$this->__tables = $tables;
$this->out(__('Possible Models based on your current database:', true));
$this->_modelNames = array();
$count = count($tables);
for ($i = 0; $i < $count; $i++) {
$this->_modelNames[] = $this->_modelName($tables[$i]);
$this->out($i + 1 . ". " . $this->_modelNames[$i]);
if ($interactive === true) {
$this->out(__('Possible Models based on your current database:', true));
$this->_modelNames = array();
$count = count($tables);
for ($i = 0; $i < $count; $i++) {
$this->_modelNames[] = $this->_modelName($tables[$i]);
$this->out($i + 1 . ". " . $this->_modelNames[$i]);
}
}
}
/**

View file

@ -26,28 +26,23 @@
?>
<div class="<?php echo $pluralVar;?> view">
<h2><?php echo "<?php __('{$singularHumanName}');?>";?></h2>
<dl>
<dl><?php echo "<?php \$i = 0; \$class = ' class=\"altrow\"';?>\n";?>
<?php
$i = 0;
foreach ($fields as $field) {
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
$isKey = false;
if(!empty($associations['belongsTo'])) {
foreach ($associations['belongsTo'] as $alias => $details) {
if($field === $details['foreignKey']) {
$isKey = true;
echo "\t\t<dt{$class}><?php __('".Inflector::humanize(Inflector::underscore($alias))."'); ?></dt>\n";
echo "\t\t<dd{$class}>\n\t\t\t<?php echo \$html->link(\${$singularVar}['{$alias}']['{$details['displayField']}'], array('controller'=> '{$details['controller']}', 'action'=>'view', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?>\n\t\t\t&nbsp;\n\t\t</dd>\n";
echo "\t\t<dt<?php if (\$i % 2 == 0) echo \$class;?>><?php __('".Inflector::humanize(Inflector::underscore($alias))."'); ?></dt>\n";
echo "\t\t<dd<?php if (\$i++ % 2 == 0) echo \$class;?>>\n\t\t\t<?php echo \$html->link(\${$singularVar}['{$alias}']['{$details['displayField']}'], array('controller'=> '{$details['controller']}', 'action'=>'view', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?>\n\t\t\t&nbsp;\n\t\t</dd>\n";
break;
}
}
}
if($isKey !== true) {
echo "\t\t<dt{$class}><?php __('".Inflector::humanize($field)."'); ?></dt>\n";
echo "\t\t<dd{$class}>\n\t\t\t<?php echo \${$singularVar}['{$modelClass}']['{$field}']; ?>\n\t\t\t&nbsp;\n\t\t</dd>\n";
echo "\t\t<dt<?php if (\$i % 2 == 0) echo \$class;?>><?php __('".Inflector::humanize($field)."'); ?></dt>\n";
echo "\t\t<dd<?php if (\$i++ % 2 == 0) echo \$class;?>>\n\t\t\t<?php echo \${$singularVar}['{$modelClass}']['{$field}']; ?>\n\t\t\t&nbsp;\n\t\t</dd>\n";
}
}
?>
@ -80,16 +75,11 @@ if(!empty($associations['hasOne'])) :
<div class="related">
<h3><?php echo "<?php __('Related ".Inflector::humanize($details['controller'])."');?>";?></h3>
<?php echo "<?php if (!empty(\${$singularVar}['{$alias}'])):?>\n";?>
<dl>
<dl><?php echo "\t<?php \$i = 0; \$class = ' class=\"altrow\"';?>\n";?>
<?php
$i = 0;
foreach ($details['fields'] as $field) {
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
echo "\t\t<dt{$class}><?php __('".Inflector::humanize($field)."');?></dt>\n";
echo "\t\t<dd{$class}>\n\t<?php echo \${$singularVar}['{$alias}']['{$field}'];?>\n&nbsp;</dd>\n";
echo "\t\t<dt<?php if (\$i % 2 == 0) echo \$class;?>><?php __('".Inflector::humanize($field)."');?></dt>\n";
echo "\t\t<dd<?php if (\$i++ % 2 == 0) echo \$class;?>>\n\t<?php echo \${$singularVar}['{$alias}']['{$field}'];?>\n&nbsp;</dd>\n";
}
?>
</dl>
@ -136,7 +126,7 @@ echo "\t<?php
\$class = ' class=\"altrow\"';
}
?>\n";
echo "\t\t<tr{$class}>\n";
echo "\t\t<tr<?php echo \$class;?>>\n";
foreach ($details['fields'] as $field) {
echo "\t\t\t<td><?php echo \${$otherSingularVar}['{$field}'];?></td>\n";

View file

@ -267,7 +267,7 @@ class View extends Object {
}
parent::__construct();
if($register) {
if ($register) {
ClassRegistry::addObject('view', $this);
}
}
@ -417,7 +417,7 @@ class View extends Object {
$debug = '';
if (Configure::read() > 2 && isset($this->viewVars['cakeDebug'])) {
if (isset($this->viewVars['cakeDebug']) && Configure::read() > 2) {
$debug = View::renderElement('dump', array('controller' => $this->viewVars['cakeDebug']), false);
unset($this->viewVars['cakeDebug']);
}
@ -770,19 +770,19 @@ class View extends Object {
$subDir = $this->subDir . DS;
}
if($name === null) {
if ($name === null) {
$name = $this->action;
}
if(strpos($name, '/') === false && strpos($name, '..') === false) {
if (strpos($name, '/') === false && strpos($name, '..') === false) {
$name = $this->viewPath . DS . $subDir . Inflector::underscore($name);
} elseif (strpos($name, '/') !== false) {
if($name{0} === '/') {
if ($name{0} === '/') {
if (is_file($name)) {
return $name;
}
$name = trim($name, '/');
if(DS !== '/') {
if (DS !== '/') {
$name = implode(DS, explode('/', $name));
}
} else {
@ -818,7 +818,7 @@ class View extends Object {
* @access protected
*/
function _getLayoutFileName($name = null) {
if($name === null) {
if ($name === null) {
$name = $this->layout;
}
$subDir = null;
@ -884,7 +884,7 @@ class View extends Object {
* @access protected
*/
function _paths($plugin = null, $cached = true) {
if($plugin === null && $cached === true && !empty($this->__paths)) {
if ($plugin === null && $cached === true && !empty($this->__paths)) {
return $this->__paths;
}
$paths = array();
@ -904,7 +904,7 @@ class View extends Object {
$paths = array_merge($paths, $viewPaths);
if(empty($this->__paths)) {
if (empty($this->__paths)) {
$this->__paths = $paths;
}