ControllerTask.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 1.2.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Console\Command\Task;
  16. use Cake\Console\Shell;
  17. use Cake\Core\App;
  18. use Cake\Core\Configure;
  19. use Cake\ORM\TableRegistry;
  20. use Cake\Utility\Inflector;
  21. /**
  22. * Task class for creating and updating controller files.
  23. *
  24. */
  25. class ControllerTask extends BakeTask {
  26. /**
  27. * Tasks to be loaded by this Task
  28. *
  29. * @var array
  30. */
  31. public $tasks = ['Model', 'Test', 'Template'];
  32. /**
  33. * Path fragment for generated code.
  34. *
  35. * @var string
  36. */
  37. public $pathFragment = 'Controller/';
  38. /**
  39. * Execution method always used for tasks
  40. *
  41. * @return void
  42. */
  43. public function execute() {
  44. parent::execute();
  45. if (!isset($this->connection)) {
  46. $this->connection = 'default';
  47. }
  48. if (empty($this->args)) {
  49. $this->out(__d('cake_console', 'Possible controllers based on your current database:'));
  50. foreach ($this->listAll() as $table) {
  51. $this->out('- ' . $this->_controllerName($table));
  52. }
  53. return true;
  54. }
  55. if (strtolower($this->args[0]) === 'all') {
  56. return $this->all();
  57. }
  58. $controller = $this->_controllerName($this->args[0]);
  59. $this->bake($controller);
  60. }
  61. /**
  62. * Bake All the controllers at once. Will only bake controllers for models that exist.
  63. *
  64. * @return void
  65. */
  66. public function all() {
  67. $controllersCreated = 0;
  68. foreach ($this->listAll() as $table) {
  69. $controller = $this->_controllerName($table);
  70. $this->bake($controller);
  71. $this->bakeTest($controller);
  72. $controllersCreated++;
  73. }
  74. }
  75. /**
  76. * Bake scaffold actions
  77. *
  78. * @param string $controllerName Controller name
  79. * @return string Baked actions
  80. */
  81. public function bakeActions($controllerName) {
  82. if (!empty($this->params['no-actions'])) {
  83. return '';
  84. }
  85. $currentModelName = $controllerName;
  86. $plugin = $this->plugin;
  87. if ($plugin) {
  88. $plugin .= '.';
  89. }
  90. $modelObj = TableRegistry::get($currentModelName);
  91. $controllerPath = $this->_controllerPath($controllerName);
  92. $pluralName = $this->_pluralName($currentModelName);
  93. $singularName = Inflector::variable(Inflector::singularize($currentModelName));
  94. $singularHumanName = $this->_singularHumanName($controllerName);
  95. $pluralHumanName = $this->_pluralName($controllerName);
  96. $this->Template->set(compact(
  97. 'plugin', 'admin', 'controllerPath', 'pluralName', 'singularName',
  98. 'singularHumanName', 'pluralHumanName', 'modelObj', 'currentModelName'
  99. ));
  100. $actions = $this->Template->generate('actions', 'controller_actions');
  101. return $actions;
  102. }
  103. /**
  104. * Assembles and writes a Controller file
  105. *
  106. * @param string $controllerName Controller name already pluralized and correctly cased.
  107. * @return string Baked controller
  108. */
  109. public function bake($controllerName) {
  110. $this->out("\n" . __d('cake_console', 'Baking controller class for %s...', $controllerName), 1, Shell::QUIET);
  111. $actions = $this->bakeActions($controllerName);
  112. $helpers = $this->getHelpers();
  113. $components = $this->getComponents();
  114. $prefix = '';
  115. if (isset($this->params['prefix'])) {
  116. $prefix = '\\' . $this->params['prefix'];
  117. }
  118. $namespace = Configure::read('App.namespace');
  119. if ($this->plugin) {
  120. $namespace = $this->plugin;
  121. }
  122. $data = compact(
  123. 'prefix',
  124. 'actions',
  125. 'helpers',
  126. 'components',
  127. 'namespace'
  128. );
  129. $data['name'] = $controllerName;
  130. $out = $this->bakeController($controllerName, $data);
  131. $this->bakeTest($controllerName);
  132. return $out;
  133. }
  134. /**
  135. * Generate the controller code
  136. *
  137. * @param string $controllerName The name of the controller.
  138. * @param array $data The data to turn into code.
  139. * @return string The generated controller file.
  140. */
  141. public function bakeController($controllerName, $data) {
  142. $data += [
  143. 'name' => null,
  144. 'namespace' => null,
  145. 'prefix' => null,
  146. 'actions' => null,
  147. 'helpers' => null,
  148. 'components' => null,
  149. 'plugin' => null,
  150. 'pluginPath' => null,
  151. ];
  152. $this->Template->set($data);
  153. $contents = $this->Template->generate('classes', 'controller');
  154. $path = $this->getPath();
  155. $filename = $path . $controllerName . 'Controller.php';
  156. $this->createFile($filename, $contents);
  157. return $contents;
  158. }
  159. /**
  160. * Gets the path for output. Checks the plugin property
  161. * and returns the correct path.
  162. *
  163. * @return string Path to output.
  164. */
  165. public function getPath() {
  166. $path = parent::getPath();
  167. if (!empty($this->params['prefix'])) {
  168. $path .= Inflector::camelize($this->params['prefix']) . DS;
  169. }
  170. return $path;
  171. }
  172. /**
  173. * Assembles and writes a unit test file
  174. *
  175. * @param string $className Controller class name
  176. * @return string Baked test
  177. */
  178. public function bakeTest($className) {
  179. if (!empty($this->params['no-test'])) {
  180. return;
  181. }
  182. $this->Test->plugin = $this->plugin;
  183. $this->Test->connection = $this->connection;
  184. if (!empty($this->params['prefix'])) {
  185. $className = $this->params['prefix'] . '\\' . $className;
  186. }
  187. return $this->Test->bake('Controller', $className);
  188. }
  189. /**
  190. * Get the list of components for the controller.
  191. *
  192. * @return array
  193. */
  194. public function getComponents() {
  195. $components = [];
  196. if (!empty($this->params['components'])) {
  197. $components = explode(',', $this->params['components']);
  198. $components = array_values(array_filter(array_map('trim', $components)));
  199. }
  200. return $components;
  201. }
  202. /**
  203. * Get the list of helpers for the controller.
  204. *
  205. * @return array
  206. */
  207. public function getHelpers() {
  208. $helpers = [];
  209. if (!empty($this->params['helpers'])) {
  210. $helpers = explode(',', $this->params['helpers']);
  211. $helpers = array_values(array_filter(array_map('trim', $helpers)));
  212. }
  213. return $helpers;
  214. }
  215. /**
  216. * Outputs and gets the list of possible controllers from database
  217. *
  218. * @param string $useDbConfig Database configuration name
  219. * @return array Set of controllers
  220. */
  221. public function listAll() {
  222. $this->Model->connection = $this->connection;
  223. return $this->Model->listAll();
  224. }
  225. /**
  226. * Gets the option parser instance and configures it.
  227. *
  228. * @return \Cake\Console\ConsoleOptionParser
  229. */
  230. public function getOptionParser() {
  231. $parser = parent::getOptionParser();
  232. $parser->description(
  233. __d('cake_console', 'Bake a controller for a model. Using options you can bake public, admin or both.')
  234. )->addArgument('name', [
  235. 'help' => __d('cake_console', 'Name of the controller to bake. Can use Plugin.name to bake controllers into plugins.')
  236. ])->addOption('plugin', [
  237. 'short' => 'p',
  238. 'help' => __d('cake_console', 'Plugin to bake the controller into.')
  239. ])->addOption('connection', [
  240. 'short' => 'c',
  241. 'help' => __d('cake_console', 'The connection the controller\'s model is on.')
  242. ])->addOption('theme', [
  243. 'short' => 't',
  244. 'help' => __d('cake_console', 'Theme to use when baking code.')
  245. ])->addOption('components', [
  246. 'help' => __d('cake_console', 'The comma separated list of components to use.')
  247. ])->addOption('helpers', [
  248. 'help' => __d('cake_console', 'The comma separated list of helpers to use.')
  249. ])->addOption('prefix', [
  250. 'help' => __d('cake_console', 'The namespace/routing prefix to use.')
  251. ])->addOption('no-test', [
  252. 'boolean' => true,
  253. 'help' => __d('cake_console', 'Do not generate a test skeleton.')
  254. ])->addOption('no-actions', [
  255. 'boolean' => true,
  256. 'help' => __d('cake_console', 'Do not generate basic CRUD action methods.')
  257. ])->addOption('force', [
  258. 'short' => 'f',
  259. 'boolean' => true,
  260. 'help' => __d('cake_console', 'Force overwriting existing files without prompting.')
  261. ])->addSubcommand('all', [
  262. 'help' => __d('cake_console', 'Bake all controllers with CRUD methods.')
  263. ]);
  264. return $parser;
  265. }
  266. }