diff --git a/cake/console/libs/tasks/model.php b/cake/console/libs/tasks/model.php index a982cfb28..7d72dbf21 100644 --- a/cake/console/libs/tasks/model.php +++ b/cake/console/libs/tasks/model.php @@ -78,6 +78,15 @@ class ModelTask extends Shell { **/ var $__validations = array(); +/** + * startup method + * + * @return void + **/ + function startup() { + App::import('Core', 'Model'); + } + /** * Execution method always used for tasks * @@ -127,13 +136,8 @@ class ModelTask extends Shell { * @param string $className Name of class you want model to be. * @return object Model instance **/ - function _getModelObject($className) { - if (App::import('Model', $className)) { - $object = new $className(); - } else { - App::import('Model'); - $object = new Model(array('name' => $className, 'ds' => $this->connection)); - } + function &_getModelObject($className) { + $object = new Model(array('name' => $className, 'ds' => $this->connection)); return $object; } /** @@ -159,7 +163,6 @@ class ModelTask extends Shell { $fullTableName = $db->fullTableName($useTable); if (in_array($useTable, $this->__tables)) { - App::import('Model'); $tempModel = new Model(array('name' => $currentModelName, 'table' => $useTable, 'ds' => $this->connection)); $fields = $tempModel->schema(); if (!array_key_exists('id', $fields)) { @@ -387,7 +390,6 @@ class ModelTask extends Shell { if (!is_object($model)) { return false; } - App::import('Model'); $this->out(__('One moment while the associations are detected.', true)); $fields = $model->schema(); @@ -415,38 +417,7 @@ class ModelTask extends Shell { } 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++) { - $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]); - } else { - if ($model->name === $associations[$type][$i]['alias']) { - if ($type === 'belongsTo') { - $alias = 'Parent' . $associations[$type][$i]['alias']; - } - if ($type === 'hasOne' || $type === 'hasMany') { - $alias = 'Child' . $associations[$type][$i]['alias']; - } - - $alternateAlias = $this->in(sprintf(__('This is a self join. Use %s as the alias', true), $alias), array('y', 'n'), 'y'); - - if ('n' == low($alternateAlias) || 'no' == low($alternateAlias)) { - $associations[$type][$i]['alias'] = $this->in(__('Specify an alternate alias.', true)); - } else { - $associations[$type][$i]['alias'] = $alias; - } - } - } - } - $associations[$type] = array_merge($associations[$type]); - } - } + $associations = $this->confirmAssociations($model, $associations); } $wannaDoMoreAssoc = $this->in(__('Would you like to define some additional model associations?', true), array('y','n'), 'n'); @@ -534,13 +505,19 @@ class ModelTask extends Shell { $fields = $model->schema(); foreach ($fields as $fieldName => $field) { $offset = strpos($fieldName, '_id'); - if ($fieldName != $model->primaryKey && $offset !== false) { + if ($fieldName != $model->primaryKey && $fieldName != 'parent_id' && $offset !== false) { $tmpModelName = $this->_modelNameFromKey($fieldName); $associations['belongsTo'][] = array( 'alias' => $tmpModelName, 'className' => $tmpModelName, 'foreignKey' => $fieldName, ); + } elseif ($fieldName == 'parent_id') { + $associations['belongsTo'][] = array( + 'alias' => 'Parent' . $model->name, + 'className' => $model->name, + 'foreignKey' => $fieldName, + ); } } return $associations; @@ -561,16 +538,29 @@ class ModelTask extends Shell { $pattern = '/_' . preg_quote($model->table, '/') . '|' . preg_quote($model->table, '/') . '_/'; $possibleJoinTable = preg_match($pattern , $otherTable); + if ($possibleJoinTable == true) { + continue; + } foreach ($modelFieldsTemp as $fieldName => $field) { - if ($fieldName != $model->primaryKey && $fieldName == $foreignKey && $possibleJoinTable == false) { + $assoc = false; + if ($fieldName != $model->primaryKey && $fieldName == $foreignKey) { $assoc = array( 'alias' => $tempOtherModel->name, 'className' => $tempOtherModel->name, 'foreignKey' => $fieldName ); + } elseif ($otherTable == $model->table && $fieldName == 'parent_id') { + $assoc = array( + 'alias' => 'Child' . $model->name, + 'className' => $model->name, + 'foreignKey' => $fieldName + ); + } + if ($assoc) { $associations['hasOne'][] = $assoc; $associations['hasMany'][] = $assoc; } + } } return $associations; @@ -615,6 +605,33 @@ class ModelTask extends Shell { } return $associations; } +/** + * Interact with the user and confirm associations. + * + * @param array $model Temporary Model instance. + * @param array $associations Array of associations to be confirmed. + * @return array Array of confirmed associations + **/ + function confirmAssociations(&$model, $associations) { + foreach ($associations as $type => $settings) { + if (!empty($associations[$type])) { + $count = count($associations[$type]); + $response = 'y'; + for ($i = 0; $i < $count; $i++) { + $prompt = "{$model->name} {$type} {$associations[$type][$i]['alias']}"; + $response = $this->in("{$prompt}?", array('y','n'), 'y'); + + if ('n' == low($response)) { + unset($associations[$type][$i]); + } elseif ($type == 'hasMany') { + unset($associations['hasOne'][$i]); + } + } + $associations[$type] = array_merge($associations[$type]); + } + } + return $associations; + } /** * Assembles and writes a Model file. diff --git a/cake/tests/cases/console/libs/tasks/model.test.php b/cake/tests/cases/console/libs/tasks/model.test.php index c5f74d89b..065d76afa 100644 --- a/cake/tests/cases/console/libs/tasks/model.test.php +++ b/cake/tests/cases/console/libs/tasks/model.test.php @@ -39,6 +39,7 @@ if (!class_exists('ShellDispatcher')) { if (!class_exists('ModelTask')) { require CAKE . 'console' . DS . 'libs' . DS . 'tasks' . DS . 'model.php'; + require CAKE . 'console' . DS . 'libs' . DS . 'tasks' . DS . 'fixture.php'; } Mock::generatePartial( @@ -54,6 +55,10 @@ Mock::generatePartial( Mock::generate( 'Model', 'MockModelTaskModel' ); + +Mock::generate( + 'FixtureTask', 'MockModelTaskFixtureTask' +); /** * ModelTaskTest class * @@ -66,7 +71,7 @@ class ModelTaskTest extends CakeTestCase { * * @var array **/ - var $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag'); + var $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag', 'core.category_thread'); /** * setUp method @@ -99,20 +104,22 @@ class ModelTaskTest extends CakeTestCase { function testListAll() { $this->Task->expectAt(1, 'out', array('1. Article')); $this->Task->expectAt(2, 'out', array('2. ArticlesTag')); - $this->Task->expectAt(3, 'out', array('3. Comment')); - $this->Task->expectAt(4, 'out', array('4. Tag')); + $this->Task->expectAt(3, 'out', array('3. CategoryThread')); + $this->Task->expectAt(4, 'out', array('4. Comment')); + $this->Task->expectAt(5, 'out', array('5. Tag')); $result = $this->Task->listAll('test_suite'); - $expected = array('articles', 'articles_tags', 'comments', 'tags'); + $expected = array('articles', 'articles_tags', 'category_threads', 'comments', 'tags'); $this->assertEqual($result, $expected); - $this->Task->expectAt(6, 'out', array('1. Article')); - $this->Task->expectAt(7, 'out', array('2. ArticlesTag')); - $this->Task->expectAt(8, 'out', array('3. Comment')); - $this->Task->expectAt(9, 'out', array('4. Tag')); + $this->Task->expectAt(7, 'out', array('1. Article')); + $this->Task->expectAt(8, 'out', array('2. ArticlesTag')); + $this->Task->expectAt(9, 'out', array('3. CategoryThread')); + $this->Task->expectAt(10, 'out', array('4. Comment')); + $this->Task->expectAt(11, 'out', array('5. Tag')); $this->Task->connection = 'test_suite'; $result = $this->Task->listAll(); - $expected = array('articles', 'articles_tags', 'comments', 'tags'); + $expected = array('articles', 'articles_tags', 'category_threads', 'comments', 'tags'); $this->assertEqual($result, $expected); } @@ -133,7 +140,7 @@ class ModelTaskTest extends CakeTestCase { $expected = 'Article'; $this->assertEqual($result, $expected); - $this->Task->setReturnValueAt(2, 'in', 3); + $this->Task->setReturnValueAt(2, 'in', 4); $result = $this->Task->getName('test_suite'); $expected = 'Comment'; $this->assertEqual($result, $expected); @@ -319,6 +326,20 @@ class ModelTaskTest extends CakeTestCase { ) ); $this->assertEqual($result, $expected); + + + $model = new Model(array('ds' => 'test_suite', 'name' => 'CategoryThread')); + $result = $this->Task->findBelongsTo($model, array()); + $expected = array( + 'belongsTo' => array( + array( + 'alias' => 'ParentCategoryThread', + 'className' => 'CategoryThread', + 'foreignKey' => 'parent_id', + ), + ) + ); + $this->assertEqual($result, $expected); } /** @@ -348,6 +369,27 @@ class ModelTaskTest extends CakeTestCase { ), ); $this->assertEqual($result, $expected); + + + $model = new Model(array('ds' => 'test_suite', 'name' => 'CategoryThread')); + $result = $this->Task->findHasOneAndMany($model, array()); + $expected = array( + 'hasOne' => array( + array( + 'alias' => 'ChildCategoryThread', + 'className' => 'CategoryThread', + 'foreignKey' => 'parent_id', + ), + ), + 'hasMany' => array( + array( + 'alias' => 'ChildCategoryThread', + 'className' => 'CategoryThread', + 'foreignKey' => 'parent_id', + ), + ) + ); + $this->assertEqual($result, $expected); } /** @@ -373,5 +415,17 @@ class ModelTaskTest extends CakeTestCase { ); $this->assertEqual($result, $expected); } + +/** + * Ensure that the fixutre object is correctly called. + * + * @return void + **/ + function testFixture() { + $this->Task->Fixture =& new MockModelTaskFixtureTask(); + $this->Task->Fixture->expectAt(0, 'bake', array('Article', 'articles')); + $this->Task->fixture('Article', 'articles'); + } + } ?> \ No newline at end of file