Mercurial > hg > Members > shoshi > webvirt
comparison cake/console/libs/tasks/controller.php @ 0:261e66bd5a0c
hg init
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 24 Jul 2011 21:08:31 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * The ControllerTask handles creating and updating controller files. | |
4 * | |
5 * PHP versions 4 and 5 | |
6 * | |
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | |
8 * Copyright 2005-2010, Cake Software Foundation, Inc. | |
9 * | |
10 * Licensed under The MIT License | |
11 * Redistributions of files must retain the above copyright notice. | |
12 * | |
13 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
14 * @link http://cakephp.org CakePHP(tm) Project | |
15 * @package cake | |
16 * @subpackage cake.cake.console.libs.tasks | |
17 * @since CakePHP(tm) v 1.2 | |
18 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
19 */ | |
20 | |
21 include_once dirname(__FILE__) . DS . 'bake.php'; | |
22 | |
23 /** | |
24 * Task class for creating and updating controller files. | |
25 * | |
26 * @package cake | |
27 * @subpackage cake.cake.console.libs.tasks | |
28 */ | |
29 class ControllerTask extends BakeTask { | |
30 | |
31 /** | |
32 * Tasks to be loaded by this Task | |
33 * | |
34 * @var array | |
35 * @access public | |
36 */ | |
37 var $tasks = array('Model', 'Test', 'Template', 'DbConfig', 'Project'); | |
38 | |
39 /** | |
40 * path to CONTROLLERS directory | |
41 * | |
42 * @var array | |
43 * @access public | |
44 */ | |
45 var $path = CONTROLLERS; | |
46 | |
47 /** | |
48 * Override initialize | |
49 * | |
50 * @access public | |
51 */ | |
52 function initialize() { | |
53 } | |
54 | |
55 /** | |
56 * Execution method always used for tasks | |
57 * | |
58 * @access public | |
59 */ | |
60 function execute() { | |
61 if (empty($this->args)) { | |
62 return $this->__interactive(); | |
63 } | |
64 | |
65 if (isset($this->args[0])) { | |
66 if (!isset($this->connection)) { | |
67 $this->connection = 'default'; | |
68 } | |
69 if (strtolower($this->args[0]) == 'all') { | |
70 return $this->all(); | |
71 } | |
72 | |
73 $controller = $this->_controllerName($this->args[0]); | |
74 $actions = 'scaffold'; | |
75 | |
76 if (!empty($this->args[1]) && ($this->args[1] == 'public' || $this->args[1] == 'scaffold')) { | |
77 $this->out(__('Baking basic crud methods for ', true) . $controller); | |
78 $actions = $this->bakeActions($controller); | |
79 } elseif (!empty($this->args[1]) && $this->args[1] == 'admin') { | |
80 $admin = $this->Project->getPrefix(); | |
81 if ($admin) { | |
82 $this->out(sprintf(__('Adding %s methods', true), $admin)); | |
83 $actions = $this->bakeActions($controller, $admin); | |
84 } | |
85 } | |
86 | |
87 if (!empty($this->args[2]) && $this->args[2] == 'admin') { | |
88 $admin = $this->Project->getPrefix(); | |
89 if ($admin) { | |
90 $this->out(sprintf(__('Adding %s methods', true), $admin)); | |
91 $actions .= "\n" . $this->bakeActions($controller, $admin); | |
92 } | |
93 } | |
94 | |
95 if ($this->bake($controller, $actions)) { | |
96 if ($this->_checkUnitTest()) { | |
97 $this->bakeTest($controller); | |
98 } | |
99 } | |
100 } | |
101 } | |
102 | |
103 /** | |
104 * Bake All the controllers at once. Will only bake controllers for models that exist. | |
105 * | |
106 * @access public | |
107 * @return void | |
108 */ | |
109 function all() { | |
110 $this->interactive = false; | |
111 $this->listAll($this->connection, false); | |
112 ClassRegistry::config('Model', array('ds' => $this->connection)); | |
113 $unitTestExists = $this->_checkUnitTest(); | |
114 foreach ($this->__tables as $table) { | |
115 $model = $this->_modelName($table); | |
116 $controller = $this->_controllerName($model); | |
117 if (App::import('Model', $model)) { | |
118 $actions = $this->bakeActions($controller); | |
119 if ($this->bake($controller, $actions) && $unitTestExists) { | |
120 $this->bakeTest($controller); | |
121 } | |
122 } | |
123 } | |
124 } | |
125 | |
126 /** | |
127 * Interactive | |
128 * | |
129 * @access private | |
130 */ | |
131 function __interactive() { | |
132 $this->interactive = true; | |
133 $this->hr(); | |
134 $this->out(sprintf(__("Bake Controller\nPath: %s", true), $this->path)); | |
135 $this->hr(); | |
136 | |
137 if (empty($this->connection)) { | |
138 $this->connection = $this->DbConfig->getConfig(); | |
139 } | |
140 | |
141 $controllerName = $this->getName(); | |
142 $this->hr(); | |
143 $this->out(sprintf(__('Baking %sController', true), $controllerName)); | |
144 $this->hr(); | |
145 | |
146 $helpers = $components = array(); | |
147 $actions = ''; | |
148 $wannaUseSession = 'y'; | |
149 $wannaBakeAdminCrud = 'n'; | |
150 $useDynamicScaffold = 'n'; | |
151 $wannaBakeCrud = 'y'; | |
152 | |
153 $controllerFile = strtolower(Inflector::underscore($controllerName)); | |
154 | |
155 $question[] = __("Would you like to build your controller interactively?", true); | |
156 if (file_exists($this->path . $controllerFile .'_controller.php')) { | |
157 $question[] = sprintf(__("Warning: Choosing no will overwrite the %sController.", true), $controllerName); | |
158 } | |
159 $doItInteractive = $this->in(implode("\n", $question), array('y','n'), 'y'); | |
160 | |
161 if (strtolower($doItInteractive) == 'y') { | |
162 $this->interactive = true; | |
163 $useDynamicScaffold = $this->in( | |
164 __("Would you like to use dynamic scaffolding?", true), array('y','n'), 'n' | |
165 ); | |
166 | |
167 if (strtolower($useDynamicScaffold) == 'y') { | |
168 $wannaBakeCrud = 'n'; | |
169 $actions = 'scaffold'; | |
170 } else { | |
171 list($wannaBakeCrud, $wannaBakeAdminCrud) = $this->_askAboutMethods(); | |
172 | |
173 $helpers = $this->doHelpers(); | |
174 $components = $this->doComponents(); | |
175 | |
176 $wannaUseSession = $this->in( | |
177 __("Would you like to use Session flash messages?", true), array('y','n'), 'y' | |
178 ); | |
179 } | |
180 } else { | |
181 list($wannaBakeCrud, $wannaBakeAdminCrud) = $this->_askAboutMethods(); | |
182 } | |
183 | |
184 if (strtolower($wannaBakeCrud) == 'y') { | |
185 $actions = $this->bakeActions($controllerName, null, strtolower($wannaUseSession) == 'y'); | |
186 } | |
187 if (strtolower($wannaBakeAdminCrud) == 'y') { | |
188 $admin = $this->Project->getPrefix(); | |
189 $actions .= $this->bakeActions($controllerName, $admin, strtolower($wannaUseSession) == 'y'); | |
190 } | |
191 | |
192 $baked = false; | |
193 if ($this->interactive === true) { | |
194 $this->confirmController($controllerName, $useDynamicScaffold, $helpers, $components); | |
195 $looksGood = $this->in(__('Look okay?', true), array('y','n'), 'y'); | |
196 | |
197 if (strtolower($looksGood) == 'y') { | |
198 $baked = $this->bake($controllerName, $actions, $helpers, $components); | |
199 if ($baked && $this->_checkUnitTest()) { | |
200 $this->bakeTest($controllerName); | |
201 } | |
202 } | |
203 } else { | |
204 $baked = $this->bake($controllerName, $actions, $helpers, $components); | |
205 if ($baked && $this->_checkUnitTest()) { | |
206 $this->bakeTest($controllerName); | |
207 } | |
208 } | |
209 return $baked; | |
210 } | |
211 | |
212 /** | |
213 * Confirm a to be baked controller with the user | |
214 * | |
215 * @return void | |
216 */ | |
217 function confirmController($controllerName, $useDynamicScaffold, $helpers, $components) { | |
218 $this->out(); | |
219 $this->hr(); | |
220 $this->out(__('The following controller will be created:', true)); | |
221 $this->hr(); | |
222 $this->out(sprintf(__("Controller Name:\n\t%s", true), $controllerName)); | |
223 | |
224 if (strtolower($useDynamicScaffold) == 'y') { | |
225 $this->out("var \$scaffold;"); | |
226 } | |
227 | |
228 $properties = array( | |
229 'helpers' => __("Helpers:", true), | |
230 'components' => __('Components:', true), | |
231 ); | |
232 | |
233 foreach ($properties as $var => $title) { | |
234 if (count($$var)) { | |
235 $output = ''; | |
236 $length = count($$var); | |
237 foreach ($$var as $i => $propElement) { | |
238 if ($i != $length -1) { | |
239 $output .= ucfirst($propElement) . ', '; | |
240 } else { | |
241 $output .= ucfirst($propElement); | |
242 } | |
243 } | |
244 $this->out($title . "\n\t" . $output); | |
245 } | |
246 } | |
247 $this->hr(); | |
248 } | |
249 | |
250 /** | |
251 * Interact with the user and ask about which methods (admin or regular they want to bake) | |
252 * | |
253 * @return array Array containing (bakeRegular, bakeAdmin) answers | |
254 */ | |
255 function _askAboutMethods() { | |
256 $wannaBakeCrud = $this->in( | |
257 __("Would you like to create some basic class methods \n(index(), add(), view(), edit())?", true), | |
258 array('y','n'), 'n' | |
259 ); | |
260 $wannaBakeAdminCrud = $this->in( | |
261 __("Would you like to create the basic class methods for admin routing?", true), | |
262 array('y','n'), 'n' | |
263 ); | |
264 return array($wannaBakeCrud, $wannaBakeAdminCrud); | |
265 } | |
266 | |
267 /** | |
268 * Bake scaffold actions | |
269 * | |
270 * @param string $controllerName Controller name | |
271 * @param string $admin Admin route to use | |
272 * @param boolean $wannaUseSession Set to true to use sessions, false otherwise | |
273 * @return string Baked actions | |
274 * @access private | |
275 */ | |
276 function bakeActions($controllerName, $admin = null, $wannaUseSession = true) { | |
277 $currentModelName = $modelImport = $this->_modelName($controllerName); | |
278 $plugin = $this->plugin; | |
279 if ($plugin) { | |
280 $modelImport = $plugin . '.' . $modelImport; | |
281 } | |
282 if (!App::import('Model', $modelImport)) { | |
283 $this->err(__('You must have a model for this class to build basic methods. Please try again.', true)); | |
284 $this->_stop(); | |
285 } | |
286 | |
287 $modelObj =& ClassRegistry::init($currentModelName); | |
288 $controllerPath = $this->_controllerPath($controllerName); | |
289 $pluralName = $this->_pluralName($currentModelName); | |
290 $singularName = Inflector::variable($currentModelName); | |
291 $singularHumanName = $this->_singularHumanName($controllerName); | |
292 $pluralHumanName = $this->_pluralName($controllerName); | |
293 | |
294 $this->Template->set(compact('plugin', 'admin', 'controllerPath', 'pluralName', 'singularName', 'singularHumanName', | |
295 'pluralHumanName', 'modelObj', 'wannaUseSession', 'currentModelName')); | |
296 $actions = $this->Template->generate('actions', 'controller_actions'); | |
297 return $actions; | |
298 } | |
299 | |
300 /** | |
301 * Assembles and writes a Controller file | |
302 * | |
303 * @param string $controllerName Controller name | |
304 * @param string $actions Actions to add, or set the whole controller to use $scaffold (set $actions to 'scaffold') | |
305 * @param array $helpers Helpers to use in controller | |
306 * @param array $components Components to use in controller | |
307 * @param array $uses Models to use in controller | |
308 * @return string Baked controller | |
309 * @access private | |
310 */ | |
311 function bake($controllerName, $actions = '', $helpers = null, $components = null) { | |
312 $isScaffold = ($actions === 'scaffold') ? true : false; | |
313 | |
314 $this->Template->set('plugin', Inflector::camelize($this->plugin)); | |
315 $this->Template->set(compact('controllerName', 'actions', 'helpers', 'components', 'isScaffold')); | |
316 $contents = $this->Template->generate('classes', 'controller'); | |
317 | |
318 $path = $this->getPath(); | |
319 $filename = $path . $this->_controllerPath($controllerName) . '_controller.php'; | |
320 if ($this->createFile($filename, $contents)) { | |
321 return $contents; | |
322 } | |
323 return false; | |
324 } | |
325 | |
326 /** | |
327 * Assembles and writes a unit test file | |
328 * | |
329 * @param string $className Controller class name | |
330 * @return string Baked test | |
331 * @access private | |
332 */ | |
333 function bakeTest($className) { | |
334 $this->Test->plugin = $this->plugin; | |
335 $this->Test->connection = $this->connection; | |
336 $this->Test->interactive = $this->interactive; | |
337 return $this->Test->bake('Controller', $className); | |
338 } | |
339 | |
340 /** | |
341 * Interact with the user and get a list of additional helpers | |
342 * | |
343 * @return array Helpers that the user wants to use. | |
344 */ | |
345 function doHelpers() { | |
346 return $this->_doPropertyChoices( | |
347 __("Would you like this controller to use other helpers\nbesides HtmlHelper and FormHelper?", true), | |
348 __("Please provide a comma separated list of the other\nhelper names you'd like to use.\nExample: 'Ajax, Javascript, Time'", true) | |
349 ); | |
350 } | |
351 | |
352 /** | |
353 * Interact with the user and get a list of additional components | |
354 * | |
355 * @return array Components the user wants to use. | |
356 */ | |
357 function doComponents() { | |
358 return $this->_doPropertyChoices( | |
359 __("Would you like this controller to use any components?", true), | |
360 __("Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, Security, RequestHandler'", true) | |
361 ); | |
362 } | |
363 | |
364 /** | |
365 * Common code for property choice handling. | |
366 * | |
367 * @param string $prompt A yes/no question to precede the list | |
368 * @param sting $example A question for a comma separated list, with examples. | |
369 * @return array Array of values for property. | |
370 */ | |
371 function _doPropertyChoices($prompt, $example) { | |
372 $proceed = $this->in($prompt, array('y','n'), 'n'); | |
373 $property = array(); | |
374 if (strtolower($proceed) == 'y') { | |
375 $propertyList = $this->in($example); | |
376 $propertyListTrimmed = str_replace(' ', '', $propertyList); | |
377 $property = explode(',', $propertyListTrimmed); | |
378 } | |
379 return array_filter($property); | |
380 } | |
381 | |
382 /** | |
383 * Outputs and gets the list of possible controllers from database | |
384 * | |
385 * @param string $useDbConfig Database configuration name | |
386 * @param boolean $interactive Whether you are using listAll interactively and want options output. | |
387 * @return array Set of controllers | |
388 * @access public | |
389 */ | |
390 function listAll($useDbConfig = null) { | |
391 if (is_null($useDbConfig)) { | |
392 $useDbConfig = $this->connection; | |
393 } | |
394 $this->__tables = $this->Model->getAllTables($useDbConfig); | |
395 | |
396 if ($this->interactive == true) { | |
397 $this->out(__('Possible Controllers based on your current database:', true)); | |
398 $this->_controllerNames = array(); | |
399 $count = count($this->__tables); | |
400 for ($i = 0; $i < $count; $i++) { | |
401 $this->_controllerNames[] = $this->_controllerName($this->_modelName($this->__tables[$i])); | |
402 $this->out($i + 1 . ". " . $this->_controllerNames[$i]); | |
403 } | |
404 return $this->_controllerNames; | |
405 } | |
406 return $this->__tables; | |
407 } | |
408 | |
409 /** | |
410 * Forces the user to specify the controller he wants to bake, and returns the selected controller name. | |
411 * | |
412 * @param string $useDbConfig Connection name to get a controller name for. | |
413 * @return string Controller name | |
414 * @access public | |
415 */ | |
416 function getName($useDbConfig = null) { | |
417 $controllers = $this->listAll($useDbConfig); | |
418 $enteredController = ''; | |
419 | |
420 while ($enteredController == '') { | |
421 $enteredController = $this->in(__("Enter a number from the list above,\ntype in the name of another controller, or 'q' to exit", true), null, 'q'); | |
422 | |
423 if ($enteredController === 'q') { | |
424 $this->out(__("Exit", true)); | |
425 $this->_stop(); | |
426 } | |
427 | |
428 if ($enteredController == '' || intval($enteredController) > count($controllers)) { | |
429 $this->err(__("The Controller name you supplied was empty,\nor the number you selected was not an option. Please try again.", true)); | |
430 $enteredController = ''; | |
431 } | |
432 } | |
433 | |
434 if (intval($enteredController) > 0 && intval($enteredController) <= count($controllers) ) { | |
435 $controllerName = $controllers[intval($enteredController) - 1]; | |
436 } else { | |
437 $controllerName = Inflector::camelize($enteredController); | |
438 } | |
439 return $controllerName; | |
440 } | |
441 | |
442 /** | |
443 * Displays help contents | |
444 * | |
445 * @access public | |
446 */ | |
447 function help() { | |
448 $this->hr(); | |
449 $this->out("Usage: cake bake controller <arg1> <arg2>..."); | |
450 $this->hr(); | |
451 $this->out('Arguments:'); | |
452 $this->out(); | |
453 $this->out("<name>"); | |
454 $this->out("\tName of the controller to bake. Can use Plugin.name"); | |
455 $this->out("\tas a shortcut for plugin baking."); | |
456 $this->out(); | |
457 $this->out('Params:'); | |
458 $this->out(); | |
459 $this->out('-connection <config>'); | |
460 $this->out("\tset db config <config>. uses 'default' if none is specified"); | |
461 $this->out(); | |
462 $this->out('Commands:'); | |
463 $this->out(); | |
464 $this->out("controller <name>"); | |
465 $this->out("\tbakes controller with var \$scaffold"); | |
466 $this->out(); | |
467 $this->out("controller <name> public"); | |
468 $this->out("\tbakes controller with basic crud actions"); | |
469 $this->out("\t(index, view, add, edit, delete)"); | |
470 $this->out(); | |
471 $this->out("controller <name> admin"); | |
472 $this->out("\tbakes a controller with basic crud actions for one of the"); | |
473 $this->out("\tConfigure::read('Routing.prefixes') methods."); | |
474 $this->out(); | |
475 $this->out("controller <name> public admin"); | |
476 $this->out("\tbakes a controller with basic crud actions for one"); | |
477 $this->out("\tConfigure::read('Routing.prefixes') and non admin methods."); | |
478 $this->out("\t(index, view, add, edit, delete,"); | |
479 $this->out("\tadmin_index, admin_view, admin_edit, admin_add, admin_delete)"); | |
480 $this->out(); | |
481 $this->out("controller all"); | |
482 $this->out("\tbakes all controllers with CRUD methods."); | |
483 $this->out(); | |
484 $this->_stop(); | |
485 } | |
486 } |