Cake/Console/Command/BakeShell.php

1 <?php
2 /**
3 * Command-line code generation utility to automate programmer chores.
4 *
5 * Bake is CakePHP's code generation script, which can help you kickstart
6 * application development by writing fully functional skeleton controllers,
7 * models, and views. Going further, Bake can also write Unit Tests for you.
8 *
9 * PHP 5
10 *
11 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
12 * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
13 *
14 * Licensed under The MIT License
15 * Redistributions of files must retain the above copyright notice.
16 *
17 * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
18 * @link http://cakephp.org CakePHP(tm) Project
19 * @since CakePHP(tm) v 1.2.0.5012
20 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
21 */
22  
23 App::uses('AppShell', 'Console/Command');
24 App::uses('Model', 'Model');
25  
26 /**
27 * Command-line code generation utility to automate programmer chores.
28 *
29 * Bake is CakePHP's code generation script, which can help you kickstart
30 * application development by writing fully functional skeleton controllers,
31 * models, and views. Going further, Bake can also write Unit Tests for you.
32 *
33 * @package Cake.Console.Command
34 * @link http://book.cakephp.org/2.0/en/console-and-shells/code-generation-with-bake.html
35 */
36 class BakeShell extends AppShell {
37  
38 /**
39 * Contains tasks to load and instantiate
40 *
41 * @var array
42 */
43 public $tasks = array('Project', 'DbConfig', 'Model', 'Controller', 'View', 'Plugin', 'Fixture', 'Test');
44  
45 /**
46 * The connection being used.
47 *
48 * @var string
49 */
50 public $connection = 'default';
51  
52 /**
53 * Assign $this->connection to the active task if a connection param is set.
54 *
55 * @return void
56 */
57 public function startup() {
58 parent::startup();
59 Configure::write('debug', 2);
60 Configure::write('Cache.disable', 1);
61  
62 $task = Inflector::classify($this->command);
63 if (isset($this->{$task}) && !in_array($task, array('Project', 'DbConfig'))) {
64 if (isset($this->params['connection'])) {
65 $this->{$task}->connection = $this->params['connection'];
66 }
67 }
68 }
69  
70 /**
71 * Override main() to handle action
72 *
73 * @return mixed
74 */
75 public function main() {
76 if (!is_dir($this->DbConfig->path)) {
77 $path = $this->Project->execute();
78 if (!empty($path)) {
79 $this->DbConfig->path = $path . 'Config' . DS;
80 } else {
81 return false;
82 }
83 }
84  
85 if (!config('database')) {
86 $this->out(__d('cake_console', 'Your database configuration was not found. Take a moment to create one.'));
87 $this->args = null;
88 return $this->DbConfig->execute();
89 }
90 $this->out(__d('cake_console', 'Interactive Bake Shell'));
91 $this->hr();
92 $this->out(__d('cake_console', '[D]atabase Configuration'));
93 $this->out(__d('cake_console', '[M]odel'));
94 $this->out(__d('cake_console', '[V]iew'));
95 $this->out(__d('cake_console', '[C]ontroller'));
96 $this->out(__d('cake_console', '[P]roject'));
97 $this->out(__d('cake_console', '[F]ixture'));
98 $this->out(__d('cake_console', '[T]est case'));
99 $this->out(__d('cake_console', '[Q]uit'));
100  
101 $classToBake = strtoupper($this->in(__d('cake_console', 'What would you like to Bake?'), array('D', 'M', 'V', 'C', 'P', 'F', 'T', 'Q')));
102 switch ($classToBake) {
103 case 'D':
104 $this->DbConfig->execute();
105 break;
106 case 'M':
107 $this->Model->execute();
108 break;
109 case 'V':
110 $this->View->execute();
111 break;
112 case 'C':
113 $this->Controller->execute();
114 break;
115 case 'P':
116 $this->Project->execute();
117 break;
118 case 'F':
119 $this->Fixture->execute();
120 break;
121 case 'T':
122 $this->Test->execute();
123 break;
124 case 'Q':
125 exit(0);
126 break;
127 default:
128 $this->out(__d('cake_console', 'You have made an invalid selection. Please choose a type of class to Bake by entering D, M, V, F, T, or C.'));
129 }
130 $this->hr();
131 $this->main();
132 }
133  
134 /**
135 * Quickly bake the MVC
136 *
137 * @return void
138 */
139 public function all() {
140 $this->out('Bake All');
141 $this->hr();
142  
143 if (!isset($this->params['connection']) && empty($this->connection)) {
144 $this->connection = $this->DbConfig->getConfig();
145 }
146  
147 if (empty($this->args)) {
148 $this->Model->interactive = true;
149 $name = $this->Model->getName($this->connection);
150 }
151  
152 foreach (array('Model', 'Controller', 'View') as $task) {
153 $this->{$task}->connection = $this->connection;
154 $this->{$task}->interactive = false;
155 }
156  
157 if (!empty($this->args[0])) {
158 $name = $this->args[0];
159 }
160  
161 $modelExists = false;
162 $model = $this->_modelName($name);
163  
164 App::uses('AppModel', 'Model');
165 App::uses($model, 'Model');
166 if (class_exists($model)) {
167 $object = new $model();
168 $modelExists = true;
169 } else {
170 $object = new Model(array('name' => $name, 'ds' => $this->connection));
171 }
172  
173 $modelBaked = $this->Model->bake($object, false);
174  
175 if ($modelBaked && $modelExists === false) {
176 if ($this->_checkUnitTest()) {
177 $this->Model->bakeFixture($model);
178 $this->Model->bakeTest($model);
179 }
180 $modelExists = true;
181 }
182  
183 if ($modelExists === true) {
184 $controller = $this->_controllerName($name);
185 if ($this->Controller->bake($controller, $this->Controller->bakeActions($controller))) {
186 if ($this->_checkUnitTest()) {
187 $this->Controller->bakeTest($controller);
188 }
189 }
190 App::uses($controller . 'Controller', 'Controller');
191 if (class_exists($controller . 'Controller')) {
192 $this->View->args = array($name);
193 $this->View->execute();
194 }
195 $this->out('', 1, Shell::QUIET);
196 $this->out(__d('cake_console', '<success>Bake All complete</success>'), 1, Shell::QUIET);
197 array_shift($this->args);
198 } else {
199 $this->error(__d('cake_console', 'Bake All could not continue without a valid model'));
200 }
201 return $this->_stop();
202 }
203  
204 /**
205 * get the option parser.
206 *
207 * @return void
208 */
209 public function getOptionParser() {
210 $parser = parent::getOptionParser();
211 return $parser->description(__d('cake_console',
212 'The Bake script generates controllers, views and models for your application.' .
213 ' If run with no command line arguments, Bake guides the user through the class creation process.' .
214 ' You can customize the generation process by telling Bake where different parts of your application are using command line arguments.'
215 ))->addSubcommand('all', array(
216 'help' => __d('cake_console', 'Bake a complete MVC. optional <name> of a Model'),
217 ))->addSubcommand('project', array(
218 'help' => __d('cake_console', 'Bake a new app folder in the path supplied or in current directory if no path is specified'),
219 'parser' => $this->Project->getOptionParser()
220 ))->addSubcommand('plugin', array(
221 'help' => __d('cake_console', 'Bake a new plugin folder in the path supplied or in current directory if no path is specified.'),
222 'parser' => $this->Plugin->getOptionParser()
223 ))->addSubcommand('db_config', array(
224 'help' => __d('cake_console', 'Bake a database.php file in config directory.'),
225 'parser' => $this->DbConfig->getOptionParser()
226 ))->addSubcommand('model', array(
227 'help' => __d('cake_console', 'Bake a model.'),
228 'parser' => $this->Model->getOptionParser()
229 ))->addSubcommand('view', array(
230 'help' => __d('cake_console', 'Bake views for controllers.'),
231 'parser' => $this->View->getOptionParser()
232 ))->addSubcommand('controller', array(
233 'help' => __d('cake_console', 'Bake a controller.'),
234 'parser' => $this->Controller->getOptionParser()
235 ))->addSubcommand('fixture', array(
236 'help' => __d('cake_console', 'Bake a fixture.'),
237 'parser' => $this->Fixture->getOptionParser()
238 ))->addSubcommand('test', array(
239 'help' => __d('cake_console', 'Bake a unit test.'),
240 'parser' => $this->Test->getOptionParser()
241 ))->addOption('connection', array(
242 'help' => __d('cake_console', 'Database connection to use in conjunction with `bake all`.'),
243 'short' => 'c',
244 'default' => 'default'
245 ));
246 }
247  
248 }
249  
250