PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/cake/console/libs/tasks/controller.php

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