PageRenderTime 60ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/code/ryzom/tools/server/www/webtt/cake/console/libs/tasks/controller.php

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