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