00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 class ControllerTask extends Shell {
00034
00035
00036
00037
00038
00039
00040 var $plugin = null;
00041
00042
00043
00044
00045
00046
00047 var $tasks = array('Project');
00048
00049
00050
00051
00052
00053
00054 var $path = CONTROLLERS;
00055
00056
00057
00058
00059
00060 function initialize() {
00061 }
00062
00063
00064
00065
00066
00067 function execute() {
00068 if (empty($this->args)) {
00069 $this->__interactive();
00070 }
00071
00072 if (isset($this->args[0])) {
00073 $controller = Inflector::camelize($this->args[0]);
00074 $actions = null;
00075 if (isset($this->args[1]) && $this->args[1] == 'scaffold') {
00076 $this->out('Baking scaffold for ' . $controller);
00077 $actions = $this->bakeActions($controller);
00078 } else {
00079 $actions = 'scaffold';
00080 }
00081 if ((isset($this->args[1]) && $this->args[1] == 'admin') || (isset($this->args[2]) && $this->args[2] == 'admin')) {
00082 if ($admin = $this->getAdmin()) {
00083 $this->out('Adding ' . Configure::read('Routing.admin') .' methods');
00084 if ($actions == 'scaffold') {
00085 $actions = $this->bakeActions($controller, $admin);
00086 } else {
00087 $actions .= $this->bakeActions($controller, $admin);
00088 }
00089 }
00090 }
00091 if ($this->bake($controller, $actions)) {
00092 if ($this->_checkUnitTest()) {
00093 $this->bakeTest($controller);
00094 }
00095 }
00096 }
00097 }
00098
00099
00100
00101
00102
00103 function __interactive($controllerName = false) {
00104 if (!$controllerName) {
00105 $this->interactive = true;
00106 $this->hr();
00107 $this->out(sprintf("Bake Controller\nPath: %s", $this->path));
00108 $this->hr();
00109 $actions = '';
00110 $uses = array();
00111 $helpers = array();
00112 $components = array();
00113 $wannaUseSession = 'y';
00114 $wannaDoAdmin = 'n';
00115 $wannaUseScaffold = 'n';
00116 $wannaDoScaffolding = 'y';
00117 $controllerName = $this->getName();
00118 }
00119 $this->hr();
00120 $this->out("Baking {$controllerName}Controller");
00121 $this->hr();
00122
00123 $controllerFile = strtolower(Inflector::underscore($controllerName));
00124
00125 $question[] = __("Would you like to build your controller interactively?", true);
00126 if (file_exists($this->path . $controllerFile .'_controller.php')) {
00127 $question[] = sprintf(__("Warning: Choosing no will overwrite the %sController.", true), $controllerName);
00128 }
00129 $doItInteractive = $this->in(join("\n", $question), array('y','n'), 'y');
00130
00131 if (strtolower($doItInteractive) == 'y' || strtolower($doItInteractive) == 'yes') {
00132 $this->interactive = true;
00133
00134 $wannaUseScaffold = $this->in(__("Would you like to use scaffolding?", true), array('y','n'), 'n');
00135
00136 if (strtolower($wannaUseScaffold) == 'n' || strtolower($wannaUseScaffold) == 'no') {
00137
00138 $wannaDoScaffolding = $this->in(__("Would you like to include some basic class methods (index(), add(), view(), edit())?", true), array('y','n'), 'n');
00139
00140 if (strtolower($wannaDoScaffolding) == 'y' || strtolower($wannaDoScaffolding) == 'yes') {
00141 $wannaDoAdmin = $this->in(__("Would you like to create the methods for admin routing?", true), array('y','n'), 'n');
00142 }
00143
00144 $wannaDoHelpers = $this->in(__("Would you like this controller to use other helpers besides HtmlHelper and FormHelper?", true), array('y','n'), 'n');
00145
00146 if (strtolower($wannaDoHelpers) == 'y' || strtolower($wannaDoHelpers) == 'yes') {
00147 $helpersList = $this->in(__("Please provide a comma separated list of the other helper names you'd like to use.\nExample: 'Ajax, Javascript, Time'", true));
00148 $helpersListTrimmed = str_replace(' ', '', $helpersList);
00149 $helpers = explode(',', $helpersListTrimmed);
00150 }
00151 $wannaDoComponents = $this->in(__("Would you like this controller to use any components?", true), array('y','n'), 'n');
00152
00153 if (strtolower($wannaDoComponents) == 'y' || strtolower($wannaDoComponents) == 'yes') {
00154 $componentsList = $this->in(__("Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, Security, RequestHandler'", true));
00155 $componentsListTrimmed = str_replace(' ', '', $componentsList);
00156 $components = explode(',', $componentsListTrimmed);
00157 }
00158
00159 $wannaUseSession = $this->in(__("Would you like to use Sessions?", true), array('y','n'), 'y');
00160 } else {
00161 $wannaDoScaffolding = 'n';
00162 }
00163 } else {
00164 $wannaDoScaffolding = $this->in(__("Would you like to include some basic class methods (index(), add(), view(), edit())?", true), array('y','n'), 'y');
00165
00166 if (strtolower($wannaDoScaffolding) == 'y' || strtolower($wannaDoScaffolding) == 'yes') {
00167 $wannaDoAdmin = $this->in(__("Would you like to create the methods for admin routing?", true), array('y','n'), 'y');
00168 }
00169 }
00170 $admin = false;
00171
00172 if ((strtolower($wannaDoAdmin) == 'y' || strtolower($wannaDoAdmin) == 'yes')) {
00173 $admin = $this->getAdmin();
00174 }
00175
00176 if (strtolower($wannaDoScaffolding) == 'y' || strtolower($wannaDoScaffolding) == 'yes') {
00177 $actions = $this->bakeActions($controllerName, null, in_array(strtolower($wannaUseSession), array('y', 'yes')));
00178 if ($admin) {
00179 $actions .= $this->bakeActions($controllerName, $admin, in_array(strtolower($wannaUseSession), array('y', 'yes')));
00180 }
00181 }
00182
00183 if ($this->interactive === true) {
00184 $this->out('');
00185 $this->hr();
00186 $this->out('The following controller will be created:');
00187 $this->hr();
00188 $this->out("Controller Name: $controllerName");
00189
00190 if (strtolower($wannaUseScaffold) == 'y' || strtolower($wannaUseScaffold) == 'yes') {
00191 $this->out(" var \$scaffold;");
00192 $actions = 'scaffold';
00193 }
00194
00195 if (count($helpers)) {
00196 $this->out("Helpers: ", false);
00197
00198 foreach ($helpers as $help) {
00199 if ($help != $helpers[count($helpers) - 1]) {
00200 $this->out(ucfirst($help) . ", ", false);
00201 } else {
00202 $this->out(ucfirst($help));
00203 }
00204 }
00205 }
00206
00207 if (count($components)) {
00208 $this->out("Components: ", false);
00209
00210 foreach ($components as $comp) {
00211 if ($comp != $components[count($components) - 1]) {
00212 $this->out(ucfirst($comp) . ", ", false);
00213 } else {
00214 $this->out(ucfirst($comp));
00215 }
00216 }
00217 }
00218 $this->hr();
00219 $looksGood = $this->in(__('Look okay?', true), array('y','n'), 'y');
00220
00221 if (strtolower($looksGood) == 'y' || strtolower($looksGood) == 'yes') {
00222 $baked = $this->bake($controllerName, $actions, $helpers, $components, $uses);
00223 if ($baked && $this->_checkUnitTest()) {
00224 $this->bakeTest($controllerName);
00225 }
00226 } else {
00227 $this->__interactive($controllerName);
00228 }
00229 } else {
00230 $baked = $this->bake($controllerName, $actions, $helpers, $components, $uses);
00231 if ($baked && $this->_checkUnitTest()) {
00232 $this->bakeTest($controllerName);
00233 }
00234 }
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 function bakeActions($controllerName, $admin = null, $wannaUseSession = true) {
00246 $currentModelName = $modelImport = $this->_modelName($controllerName);
00247 if ($this->plugin) {
00248 $modelImport = $this->plugin . '.' . $modelImport;
00249 }
00250 if (!App::import('Model', $modelImport)) {
00251 $this->err(__('You must have a model for this class to build scaffold methods. Please try again.', true));
00252 exit;
00253 }
00254 $actions = null;
00255 $modelObj =& new $currentModelName();
00256 $controllerPath = $this->_controllerPath($controllerName);
00257 $pluralName = $this->_pluralName($currentModelName);
00258 $singularName = Inflector::variable($currentModelName);
00259 $singularHumanName = Inflector::humanize($currentModelName);
00260 $pluralHumanName = Inflector::humanize($controllerName);
00261 $actions .= "\n";
00262 $actions .= "\tfunction {$admin}index() {\n";
00263 $actions .= "\t\t\$this->{$currentModelName}->recursive = 0;\n";
00264 $actions .= "\t\t\$this->set('{$pluralName}', \$this->paginate());\n";
00265 $actions .= "\t}\n";
00266 $actions .= "\n";
00267 $actions .= "\tfunction {$admin}view(\$id = null) {\n";
00268 $actions .= "\t\tif (!\$id) {\n";
00269 if ($wannaUseSession) {
00270 $actions .= "\t\t\t\$this->Session->setFlash(__('Invalid {$singularHumanName}.', true));\n";
00271 $actions .= "\t\t\t\$this->redirect(array('action'=>'index'));\n";
00272 } else {
00273 $actions .= "\t\t\t\$this->flash(__('Invalid {$singularHumanName}', true), array('action'=>'index'));\n";
00274 }
00275 $actions .= "\t\t}\n";
00276 $actions .= "\t\t\$this->set('" . $singularName . "', \$this->{$currentModelName}->read(null, \$id));\n";
00277 $actions .= "\t}\n";
00278 $actions .= "\n";
00279
00280
00281 $compact = array();
00282 $actions .= "\tfunction {$admin}add() {\n";
00283 $actions .= "\t\tif (!empty(\$this->data)) {\n";
00284 $actions .= "\t\t\t\$this->{$currentModelName}->create();\n";
00285 $actions .= "\t\t\tif (\$this->{$currentModelName}->save(\$this->data)) {\n";
00286 if ($wannaUseSession) {
00287 $actions .= "\t\t\t\t\$this->Session->setFlash(__('The " . $singularHumanName . " has been saved', true));\n";
00288 $actions .= "\t\t\t\t\$this->redirect(array('action'=>'index'));\n";
00289 } else {
00290 $actions .= "\t\t\t\t\$this->flash(__('{$currentModelName} saved.', true), array('action'=>'index'));\n";
00291 }
00292 $actions .= "\t\t\t} else {\n";
00293 if ($wannaUseSession) {
00294 $actions .= "\t\t\t\t\$this->Session->setFlash(__('The {$singularHumanName} could not be saved. Please, try again.', true));\n";
00295 }
00296 $actions .= "\t\t\t}\n";
00297 $actions .= "\t\t}\n";
00298 foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
00299 if (!empty($associationName)) {
00300 $habtmModelName = $this->_modelName($associationName);
00301 $habtmSingularName = $this->_singularName($associationName);
00302 $habtmPluralName = $this->_pluralName($associationName);
00303 $actions .= "\t\t\${$habtmPluralName} = \$this->{$currentModelName}->{$habtmModelName}->find('list');\n";
00304 $compact[] = "'{$habtmPluralName}'";
00305 }
00306 }
00307 foreach ($modelObj->belongsTo as $associationName => $relation) {
00308 if (!empty($associationName)) {
00309 $belongsToModelName = $this->_modelName($associationName);
00310 $belongsToPluralName = $this->_pluralName($associationName);
00311 $actions .= "\t\t\${$belongsToPluralName} = \$this->{$currentModelName}->{$belongsToModelName}->find('list');\n";
00312 $compact[] = "'{$belongsToPluralName}'";
00313 }
00314 }
00315 if (!empty($compact)) {
00316 $actions .= "\t\t\$this->set(compact(" . join(', ', $compact) . "));\n";
00317 }
00318 $actions .= "\t}\n";
00319 $actions .= "\n";
00320
00321
00322 $compact = array();
00323 $actions .= "\tfunction {$admin}edit(\$id = null) {\n";
00324 $actions .= "\t\tif (!\$id && empty(\$this->data)) {\n";
00325 if ($wannaUseSession) {
00326 $actions .= "\t\t\t\$this->Session->setFlash(__('Invalid {$singularHumanName}', true));\n";
00327 $actions .= "\t\t\t\$this->redirect(array('action'=>'index'));\n";
00328 } else {
00329 $actions .= "\t\t\t\$this->flash(__('Invalid {$singularHumanName}', true), array('action'=>'index'));\n";
00330 }
00331 $actions .= "\t\t}\n";
00332 $actions .= "\t\tif (!empty(\$this->data)) {\n";
00333 $actions .= "\t\t\tif (\$this->{$currentModelName}->save(\$this->data)) {\n";
00334 if ($wannaUseSession) {
00335 $actions .= "\t\t\t\t\$this->Session->setFlash(__('The " . $singularHumanName . " has been saved', true));\n";
00336 $actions .= "\t\t\t\t\$this->redirect(array('action'=>'index'));\n";
00337 } else {
00338 $actions .= "\t\t\t\t\$this->flash(__('The " . $singularHumanName . " has been saved.', true), array('action'=>'index'));\n";
00339 }
00340 $actions .= "\t\t\t} else {\n";
00341 if ($wannaUseSession) {
00342 $actions .= "\t\t\t\t\$this->Session->setFlash(__('The {$singularHumanName} could not be saved. Please, try again.', true));\n";
00343 }
00344 $actions .= "\t\t\t}\n";
00345 $actions .= "\t\t}\n";
00346 $actions .= "\t\tif (empty(\$this->data)) {\n";
00347 $actions .= "\t\t\t\$this->data = \$this->{$currentModelName}->read(null, \$id);\n";
00348 $actions .= "\t\t}\n";
00349
00350 foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
00351 if (!empty($associationName)) {
00352 $habtmModelName = $this->_modelName($associationName);
00353 $habtmSingularName = $this->_singularName($associationName);
00354 $habtmPluralName = $this->_pluralName($associationName);
00355 $actions .= "\t\t\${$habtmPluralName} = \$this->{$currentModelName}->{$habtmModelName}->find('list');\n";
00356 $compact[] = "'{$habtmPluralName}'";
00357 }
00358 }
00359 foreach ($modelObj->belongsTo as $associationName => $relation) {
00360 if (!empty($associationName)) {
00361 $belongsToModelName = $this->_modelName($associationName);
00362 $belongsToPluralName = $this->_pluralName($associationName);
00363 $actions .= "\t\t\${$belongsToPluralName} = \$this->{$currentModelName}->{$belongsToModelName}->find('list');\n";
00364 $compact[] = "'{$belongsToPluralName}'";
00365 }
00366 }
00367 if (!empty($compact)) {
00368 $actions .= "\t\t\$this->set(compact(" . join(',', $compact) . "));\n";
00369 }
00370 $actions .= "\t}\n";
00371 $actions .= "\n";
00372 $actions .= "\tfunction {$admin}delete(\$id = null) {\n";
00373 $actions .= "\t\tif (!\$id) {\n";
00374 if ($wannaUseSession) {
00375 $actions .= "\t\t\t\$this->Session->setFlash(__('Invalid id for {$singularHumanName}', true));\n";
00376 $actions .= "\t\t\t\$this->redirect(array('action'=>'index'));\n";
00377 } else {
00378 $actions .= "\t\t\t\$this->flash(__('Invalid {$singularHumanName}', true), array('action'=>'index'));\n";
00379 }
00380 $actions .= "\t\t}\n";
00381 $actions .= "\t\tif (\$this->{$currentModelName}->del(\$id)) {\n";
00382 if ($wannaUseSession) {
00383 $actions .= "\t\t\t\$this->Session->setFlash(__('{$singularHumanName} deleted', true));\n";
00384 $actions .= "\t\t\t\$this->redirect(array('action'=>'index'));\n";
00385 } else {
00386 $actions .= "\t\t\t\$this->flash(__('{$singularHumanName} deleted', true), array('action'=>'index'));\n";
00387 }
00388 $actions .= "\t\t}\n";
00389 $actions .= "\t}\n";
00390 $actions .= "\n";
00391 return $actions;
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 function bake($controllerName, $actions = '', $helpers = null, $components = null, $uses = null) {
00407 $out = "<?php\n";
00408 $out .= "class $controllerName" . "Controller extends {$this->plugin}AppController {\n\n";
00409 $out .= "\tvar \$name = '$controllerName';\n";
00410
00411 if (strtolower($actions) == 'scaffold') {
00412 $out .= "\tvar \$scaffold;\n";
00413 } else {
00414 if (count($uses)) {
00415 $out .= "\tvar \$uses = array('" . $this->_modelName($controllerName) . "', ";
00416
00417 foreach ($uses as $use) {
00418 if ($use != $uses[count($uses) - 1]) {
00419 $out .= "'" . $this->_modelName($use) . "', ";
00420 } else {
00421 $out .= "'" . $this->_modelName($use) . "'";
00422 }
00423 }
00424 $out .= ");\n";
00425 }
00426
00427 $out .= "\tvar \$helpers = array('Html', 'Form'";
00428 if (count($helpers)) {
00429 foreach ($helpers as $help) {
00430 $out .= ", '" . Inflector::camelize($help) . "'";
00431 }
00432 }
00433 $out .= ");\n";
00434
00435 if (count($components)) {
00436 $out .= "\tvar \$components = array(";
00437
00438 foreach ($components as $comp) {
00439 if ($comp != $components[count($components) - 1]) {
00440 $out .= "'" . Inflector::camelize($comp) . "', ";
00441 } else {
00442 $out .= "'" . Inflector::camelize($comp) . "'";
00443 }
00444 }
00445 $out .= ");\n";
00446 }
00447 $out .= $actions;
00448 }
00449 $out .= "}\n";
00450 $out .= "?>";
00451 $filename = $this->path . $this->_controllerPath($controllerName) . '_controller.php';
00452 return $this->createFile($filename, $out);
00453 }
00454
00455
00456
00457
00458
00459
00460
00461 function bakeTest($className) {
00462 $import = $className;
00463 if ($this->plugin) {
00464 $import = $this->plugin . '.' . $className;
00465 }
00466 $out = "App::import('Controller', '$import');\n\n";
00467 $out .= "class Test{$className} extends {$className}Controller {\n";
00468 $out .= "\tvar \$autoRender = false;\n}\n\n";
00469 $out .= "class {$className}ControllerTest extends CakeTestCase {\n";
00470 $out .= "\tvar \${$className} = null;\n\n";
00471 $out .= "\tfunction startTest() {\n\t\t\$this->{$className} = new Test{$className}();";
00472 $out .= "\n\t\t\$this->{$className}->constructClasses();\n\t}\n\n";
00473 $out .= "\tfunction test{$className}ControllerInstance() {\n";
00474 $out .= "\t\t\$this->assertTrue(is_a(\$this->{$className}, '{$className}Controller'));\n\t}\n\n";
00475 $out .= "\tfunction endTest() {\n\t\tunset(\$this->{$className});\n\t}\n}\n";
00476
00477 $path = CONTROLLER_TESTS;
00478 if (isset($this->plugin)) {
00479 $pluginPath = 'plugins' . DS . Inflector::underscore($this->plugin) . DS;
00480 $path = APP . $pluginPath . 'tests' . DS . 'cases' . DS . 'controllers' . DS;
00481 }
00482
00483 $filename = Inflector::underscore($className).'_controller.test.php';
00484 $this->out("\nBaking unit test for $className...");
00485
00486 $header = '$Id';
00487 $content = "<?php \n/* SVN FILE: $header$ */\n/* " . $className . "Controller Test cases generated on: " . date('Y-m-d H:i:s') . " : ". time() . "*/\n{$out}?>";
00488 return $this->createFile($path . $filename, $content);
00489 }
00490
00491
00492
00493
00494
00495
00496
00497 function listAll($useDbConfig = 'default') {
00498 $db =& ConnectionManager::getDataSource($useDbConfig);
00499 $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
00500 if ($usePrefix) {
00501 $tables = array();
00502 foreach ($db->listSources() as $table) {
00503 if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
00504 $tables[] = substr($table, strlen($usePrefix));
00505 }
00506 }
00507 } else {
00508 $tables = $db->listSources();
00509 }
00510
00511 if (empty($tables)) {
00512 $this->err(__('Your database does not have any tables.', true));
00513 $this->_stop();
00514 }
00515
00516 $this->__tables = $tables;
00517 $this->out('Possible Controllers based on your current database:');
00518 $this->_controllerNames = array();
00519 $count = count($tables);
00520 for ($i = 0; $i < $count; $i++) {
00521 $this->_controllerNames[] = $this->_controllerName($this->_modelName($tables[$i]));
00522 $this->out($i + 1 . ". " . $this->_controllerNames[$i]);
00523 }
00524 return $this->_controllerNames;
00525 }
00526
00527
00528
00529
00530
00531
00532
00533 function getName() {
00534 $useDbConfig = 'default';
00535 $controllers = $this->listAll($useDbConfig, 'Controllers');
00536 $enteredController = '';
00537
00538 while ($enteredController == '') {
00539 $enteredController = $this->in(__("Enter a number from the list above, type in the name of another controller, or 'q' to exit", true), null, 'q');
00540
00541 if ($enteredController === 'q') {
00542 $this->out(__("Exit", true));
00543 $this->_stop();
00544 }
00545
00546 if ($enteredController == '' || intval($enteredController) > count($controllers)) {
00547 $this->out(__('Error:', true));
00548 $this->out(__("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.", true));
00549 $enteredController = '';
00550 }
00551 }
00552
00553 if (intval($enteredController) > 0 && intval($enteredController) <= count($controllers) ) {
00554 $controllerName = $controllers[intval($enteredController) - 1];
00555 } else {
00556 $controllerName = Inflector::camelize($enteredController);
00557 }
00558
00559 return $controllerName;
00560 }
00561
00562
00563
00564
00565
00566 function help() {
00567 $this->hr();
00568 $this->out("Usage: cake bake controller <arg1> <arg2>...");
00569 $this->hr();
00570 $this->out('Commands:');
00571 $this->out("\n\tcontroller <name>\n\t\tbakes controller with var \$scaffold");
00572 $this->out("\n\tcontroller <name> scaffold\n\t\tbakes controller with scaffold actions.\n\t\t(index, view, add, edit, delete)");
00573 $this->out("\n\tcontroller <name> scaffold admin\n\t\tbakes a controller with scaffold actions for both public and Configure::read('Routing.admin')");
00574 $this->out("\n\tcontroller <name> admin\n\t\tbakes a controller with scaffold actions only for Configure::read('Routing.admin')");
00575 $this->out("");
00576 $this->_stop();
00577 }
00578 }
00579 ?>