Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 381 lines (348 sloc) 9.889 kb
e7f3c31 @gwoo going lithium
gwoo authored
1 <?php
2 /**
3 * Lithium: the most rad php framework
4 *
4f1a9c0 @nateabele Updating copyright year.
nateabele authored
5 * @copyright Copyright 2011, Union of RAD (http://union-of-rad.org)
e7f3c31 @gwoo going lithium
gwoo authored
6 * @license http://opensource.org/licenses/bsd-license.php The BSD License
7 */
8
9 namespace lithium\console;
10
690f4c3 @nateabele Fixing formatting in console classes. Adding test coverage for `Extra…
nateabele authored
11 use Exception;
12 use lithium\console\command\Help;
e7f3c31 @gwoo going lithium
gwoo authored
13
14 /**
67d7554 @gwoo Removing `run` method from `console\Command` to make subclassing more…
gwoo authored
15 * All Commands to be run from the Lithium console must extend this class.
16 * The `run` method is automatically called if it exists. Otherwise, if a method does not exist
17 * the `Help` command will be run.
18 *
19 * {{{
20 * $ li3 example
21 * $ li3 example --format=json
22 * }}}
23 *
e7f3c31 @gwoo going lithium
gwoo authored
24 */
25 class Command extends \lithium\core\Object {
cf1cf83 @gwoo some more work on help in console
gwoo authored
26
2764bb0 @gwoo starting to update help menu in \console
gwoo authored
27 /**
28 * If -h or --help param exists a help screen will be returned.
2cba57b @gwoo moving help to a separate command. for example
gwoo authored
29 * Similar to running `li3 help COMMAND`.
2764bb0 @gwoo starting to update help menu in \console
gwoo authored
30 *
31 * @var boolean
32 */
33 public $help = false;
e7f3c31 @gwoo going lithium
gwoo authored
34
35 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
36 * A Request object.
e7f3c31 @gwoo going lithium
gwoo authored
37 *
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
38 * @see lithium\console\Request
fd4221f @gwoo updating classes to use new _instance() method in `\core\Object` and …
gwoo authored
39 * @var object
e7f3c31 @gwoo going lithium
gwoo authored
40 */
41 public $request;
42
43 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
44 * A Response object.
e7f3c31 @gwoo going lithium
gwoo authored
45 *
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
46 * @see lithium\console\Response
fd4221f @gwoo updating classes to use new _instance() method in `\core\Object` and …
gwoo authored
47 * @var object
e7f3c31 @gwoo going lithium
gwoo authored
48 */
49 public $response;
50
51 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
52 * Dynamic dependencies.
e7f3c31 @gwoo going lithium
gwoo authored
53 *
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
54 * @var array
e7f3c31 @gwoo going lithium
gwoo authored
55 */
56 protected $_classes = array(
690f4c3 @nateabele Fixing formatting in console classes. Adding test coverage for `Extra…
nateabele authored
57 'response' => 'lithium\console\Response'
e7f3c31 @gwoo going lithium
gwoo authored
58 );
9fc85ec @davidpersson Updating console return value handling.
davidpersson authored
59
ce5802e @gwoo some cleanup to \console\Command and \console\Response
gwoo authored
60 /**
9562780 @niel Typo, spelling, and punctuation fixes.
niel authored
61 * Auto configuration.
ce5802e @gwoo some cleanup to \console\Command and \console\Response
gwoo authored
62 *
63 * @var array
64 */
65 protected $_autoConfig = array('classes' => 'merge');
9fc85ec @davidpersson Updating console return value handling.
davidpersson authored
66
e7f3c31 @gwoo going lithium
gwoo authored
67 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
68 * Constructor.
69 * @param array $config
e7f3c31 @gwoo going lithium
gwoo authored
70 */
639c02f @nateabele Fixing issues with refactor of `\console\Command`.
nateabele authored
71 public function __construct(array $config = array()) {
72 $defaults = array('request' => null, 'response' => array(), 'classes' => $this->_classes);
73 parent::__construct($config + $defaults);
e7f3c31 @gwoo going lithium
gwoo authored
74 }
75
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
76 /**
77 * Initializer. Populates the `response` property with a new instance of the `Response`
9562780 @niel Typo, spelling, and punctuation fixes.
niel authored
78 * class passing it configuration and assigns the values from named parameters of the
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
79 * request (if applicable) to properties of the command.
80 *
81 * @return void
82 */
ce5802e @gwoo some cleanup to \console\Command and \console\Response
gwoo authored
83 protected function _init() {
84 parent::_init();
85 $this->request = $this->_config['request'];
639c02f @nateabele Fixing issues with refactor of `\console\Command`.
nateabele authored
86 $resp = $this->_config['response'];
87 $this->response = is_object($resp) ? $resp : $this->_instance('response', $resp);
43aa3d1 @nateabele Minor refactorings and formatting fixes for the `Command` class.
nateabele authored
88
639c02f @nateabele Fixing issues with refactor of `\console\Command`.
nateabele authored
89 if (!is_object($this->request) || !$this->request->params) {
90 return;
91 }
92 $default = array('command' => null, 'action' => null, 'args' => null);
93 $params = array_diff_key((array) $this->request->params, $default);
7839e51 @davidpersson Moving assignment of named parameters into `Command::_init()`.
davidpersson authored
94
639c02f @nateabele Fixing issues with refactor of `\console\Command`.
nateabele authored
95 foreach ($params as $key => $param) {
96 $this->{$key} = $param;
7839e51 @davidpersson Moving assignment of named parameters into `Command::_init()`.
davidpersson authored
97 }
e7f3c31 @gwoo going lithium
gwoo authored
98 }
0a65d07 @gwoo refactoring \console\Command
gwoo authored
99
25e0f6b Adding method docs.
psychic authored
100 /**
43aa3d1 @nateabele Minor refactorings and formatting fixes for the `Command` class.
nateabele authored
101 * Called by the `Dispatcher` class to invoke an action.
e7f3c31 @gwoo going lithium
gwoo authored
102 *
fd4221f @gwoo updating classes to use new _instance() method in `\core\Object` and …
gwoo authored
103 * @see lithium\console\Dispatcher
104 * @see lithium\console\Response
cad1fcc @gwoo working on \command\Help
gwoo authored
105 * @param string $action name of the method to run
106 * @param array $args the args from the request
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
107 * @param array $options
108 * @return object The response object associated with this command.
9562780 @niel Typo, spelling, and punctuation fixes.
niel authored
109 * @todo Implement filters.
e7f3c31 @gwoo going lithium
gwoo authored
110 */
2764bb0 @gwoo starting to update help menu in \console
gwoo authored
111 public function __invoke($action, $args = array(), $options = array()) {
e7f3c31 @gwoo going lithium
gwoo authored
112 try {
2764bb0 @gwoo starting to update help menu in \console
gwoo authored
113 $this->response->status = 1;
cf1cf83 @gwoo some more work on help in console
gwoo authored
114 $result = $this->invokeMethod($action, $args);
e516c8a @nateabele Preventing `\console\Command` from silently throwing away errors.
nateabele authored
115
9fc85ec @davidpersson Updating console return value handling.
davidpersson authored
116 if (is_int($result)) {
117 $this->response->status = $result;
118 } elseif ($result || $result === null) {
119 $this->response->status = 0;
120 }
e7f3c31 @gwoo going lithium
gwoo authored
121 } catch (Exception $e) {
e516c8a @nateabele Preventing `\console\Command` from silently throwing away errors.
nateabele authored
122 $this->error($e->getMessage());
e7f3c31 @gwoo going lithium
gwoo authored
123 }
9fc85ec @davidpersson Updating console return value handling.
davidpersson authored
124 return $this->response;
e7f3c31 @gwoo going lithium
gwoo authored
125 }
126
127 /**
e8a5484 @davidpersson Providing default run method implementation.
davidpersson authored
128 *
129 * The invoked Help command will take over request and response objects of
130 * the originally invoked command. Thus the response of the Help command
131 * becomes the response of the original one.
132 *
133 * @return boolean
134 */
67d7554 @gwoo Removing `run` method from `console\Command` to make subclassing more…
gwoo authored
135 protected function _help() {
136 $help = new Help(array(
137 'request' => $this->request,
138 'response' => $this->response,
139 'classes' => $this->_classes
140 ));
141 return $help->run(get_class($this));
e8a5484 @davidpersson Providing default run method implementation.
davidpersson authored
142 }
143
144 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
145 * Writes string to output stream.
e7f3c31 @gwoo going lithium
gwoo authored
146 *
0a65d07 @gwoo refactoring \console\Command
gwoo authored
147 * @param string $output
148 * @param integer|string|array $options
149 * integer as the number of new lines.
150 * string as the style
151 * array as :
152 * - nl : number of new lines to add at the end
153 * - style : the style name to wrap around the
c25e039 @Howard3 Cleaning up PHPDoc @return tags with multiple return types defined.
Howard3 authored
154 * @return integer
e7f3c31 @gwoo going lithium
gwoo authored
155 */
0a65d07 @gwoo refactoring \console\Command
gwoo authored
156 public function out($output = null, $options = array('nl' => 1)) {
8c70af1 @nateabele Tweaking console help formatting.
nateabele authored
157 $options = is_int($options) ? array('nl' => $options) : $options;
0a65d07 @gwoo refactoring \console\Command
gwoo authored
158 return $this->_response('output', $output, $options);
e7f3c31 @gwoo going lithium
gwoo authored
159 }
160
161 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
162 * Writes string to error stream.
e7f3c31 @gwoo going lithium
gwoo authored
163 *
0a65d07 @gwoo refactoring \console\Command
gwoo authored
164 * @param string $error
165 * @param integer|string|array $options
166 * integer as the number of new lines.
167 * string as the style
168 * array as :
169 * - nl : number of new lines to add at the end
170 * - style : the style name to wrap around the
c25e039 @Howard3 Cleaning up PHPDoc @return tags with multiple return types defined.
Howard3 authored
171 * @return integer
e7f3c31 @gwoo going lithium
gwoo authored
172 */
0a65d07 @gwoo refactoring \console\Command
gwoo authored
173 public function error($error = null, $options = array('nl' => 1)) {
174 return $this->_response('error', $error, $options);
e7f3c31 @gwoo going lithium
gwoo authored
175 }
176
177 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
178 * Handles input. Will continue to loop until `$options['quit']` or
9a40bf9 @farhadi Fixing bug in `Command::in()` when both `default` and `choices` optio…
farhadi authored
179 * result is part of `$options['choices']`.
e7f3c31 @gwoo going lithium
gwoo authored
180 *
181 * @param string $prompt
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
182 * @param array $options
c25e039 @Howard3 Cleaning up PHPDoc @return tags with multiple return types defined.
Howard3 authored
183 * @return string Returns the result of the input data. If the input is equal to the `quit`
184 * option boolean `false` is returned
e7f3c31 @gwoo going lithium
gwoo authored
185 */
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
186 public function in($prompt = null, array $options = array()) {
e7f3c31 @gwoo going lithium
gwoo authored
187 $defaults = array('choices' => null, 'default' => null, 'quit' => 'q');
188 $options += $defaults;
189 $choices = null;
1902698 @nateabele Misc. cleanup and refactoring in `\console\Command`.
nateabele authored
190
e7f3c31 @gwoo going lithium
gwoo authored
191 if (is_array($options['choices'])) {
192 $choices = '(' . implode('/', $options['choices']) . ')';
193 }
1902698 @nateabele Misc. cleanup and refactoring in `\console\Command`.
nateabele authored
194 $default = $options['default'] ? "[{$options['default']}] " : '';
fd4221f @gwoo updating classes to use new _instance() method in `\core\Object` and …
gwoo authored
195
9a40bf9 @farhadi Fixing bug in `Command::in()` when both `default` and `choices` optio…
farhadi authored
196 do {
197 $this->out("{$prompt} {$choices} \n {$default}> ", false);
e7f3c31 @gwoo going lithium
gwoo authored
198 $result = trim($this->request->input());
199 } while (
9a40bf9 @farhadi Fixing bug in `Command::in()` when both `default` and `choices` optio…
farhadi authored
200 !empty($options['choices']) && !in_array($result, $options['choices'], true)
201 && (empty($options['quit']) || $result !== $options['quit'])
202 && ($options['default'] == null || $result !== '')
e7f3c31 @gwoo going lithium
gwoo authored
203 );
204
cccbfc5 @Howard3 Command:
Howard3 authored
205 if ($result == $options['quit']) {
206 return false;
207 }
208
9a40bf9 @farhadi Fixing bug in `Command::in()` when both `default` and `choices` optio…
farhadi authored
209 if ($options['default'] !== null && $result == '') {
1902698 @nateabele Misc. cleanup and refactoring in `\console\Command`.
nateabele authored
210 return $options['default'];
e7f3c31 @gwoo going lithium
gwoo authored
211 }
212 return $result;
213 }
214
215 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
216 * Add text with horizontal line before and after stream.
e7f3c31 @gwoo going lithium
gwoo authored
217 *
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
218 * @param string $text
219 * @param integer $line
220 * @return void
e7f3c31 @gwoo going lithium
gwoo authored
221 */
222 public function header($text, $line = 80) {
223 $this->hr($line);
3c1b8ae @davidpersson Reducing styles for headings to one and changing color codes.
davidpersson authored
224 $this->out($text, 1, 'heading');
e7f3c31 @gwoo going lithium
gwoo authored
225 $this->hr($line);
226 }
227
228 /**
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
229 * Writes rows of columns.
e7f3c31 @gwoo going lithium
gwoo authored
230 *
6b40f72 @daschl Console: Adding possiblity to colorize columns output. API CHANGE: wh…
daschl authored
231 * This method expects asceding integer values as the keys, which map to the
232 * appropriate columns. Currently, there is no special "header" option, but you
233 * can define them for your own.
234 *
235 * Example Usage:
236 *
237 * {{{
238 * $output = array(
239 * array('Name', 'Age'),
240 * array('----', '---'),
241 * );
242 * foreach($users as $user) {
243 * $output[] = array($user->name, $user->age);
244 * }
245 * $this->columns($output);
246 * }}}
247 *
248 * Would render something similar to:
249 *
250 * {{{
251 * Name Age
252 * ---- ---
253 * Jane Doe 22
254 * Foo Bar 18
255 * }}}
256 *
257 * This method also calculates the needed space between the columns. All option
258 * params given also get passed down to the `out()` method, which allow custom
259 * formatting. Passing something like `$this->columns($output, array('style' => 'red)`
260 * would print the table in red.
261 *
67d7554 @gwoo Removing `run` method from `console\Command` to make subclassing more…
gwoo authored
262 * @see \lithium\console\Response::styles()
6b40f72 @daschl Console: Adding possiblity to colorize columns output. API CHANGE: wh…
daschl authored
263 * @param array $rows The rows to print, with each column as an array element.
264 * @param array $options Optional params:
265 * - separator : Different column separator, defaults to `\t`
266 * - style : the style name to wrap around the columns output
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
267 * @return void
e7f3c31 @gwoo going lithium
gwoo authored
268 */
6b40f72 @daschl Console: Adding possiblity to colorize columns output. API CHANGE: wh…
daschl authored
269 public function columns($rows, $options = array()) {
270 $defaults = array('separator' => "\t");
271 $config = $options + $defaults;
e7f3c31 @gwoo going lithium
gwoo authored
272 $lengths = array_reduce($rows, function($columns, $row) {
9decac0 @alkemann insert space after type casting parenthesis
alkemann authored
273 foreach ((array) $row as $key => $val) {
e7f3c31 @gwoo going lithium
gwoo authored
274 if (!isset($columns[$key]) || strlen($val) > $columns[$key]) {
275 $columns[$key] = strlen($val);
276 }
277 }
278 return $columns;
279 });
6b40f72 @daschl Console: Adding possiblity to colorize columns output. API CHANGE: wh…
daschl authored
280 $rows = array_reduce($rows, function($rows, $row) use ($lengths, $config) {
e7f3c31 @gwoo going lithium
gwoo authored
281 $text = '';
9decac0 @alkemann insert space after type casting parenthesis
alkemann authored
282 foreach ((array) $row as $key => $val) {
6b40f72 @daschl Console: Adding possiblity to colorize columns output. API CHANGE: wh…
daschl authored
283 $text = $text . str_pad($val, $lengths[$key]) . $config['separator'];
e7f3c31 @gwoo going lithium
gwoo authored
284 }
285 $rows[] = $text;
286 return $rows;
287 });
6b40f72 @daschl Console: Adding possiblity to colorize columns output. API CHANGE: wh…
daschl authored
288 $this->out($rows, $config);
e7f3c31 @gwoo going lithium
gwoo authored
289 }
290
291 /**
9562780 @niel Typo, spelling, and punctuation fixes.
niel authored
292 * Add newlines ("\n") to output stream.
e7f3c31 @gwoo going lithium
gwoo authored
293 *
294 * @param integer $number
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
295 * @return integer
e7f3c31 @gwoo going lithium
gwoo authored
296 */
297 public function nl($number = 1) {
8c70af1 @nateabele Tweaking console help formatting.
nateabele authored
298 return str_repeat("\n", $number);
e7f3c31 @gwoo going lithium
gwoo authored
299 }
300
301 /**
302 * Add horizontal line to output stream
303 *
304 * @param integer $length
305 * @param integer $newlines
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
306 * @return integer
e7f3c31 @gwoo going lithium
gwoo authored
307 */
308 public function hr($length = 80, $newlines = 1) {
309 return $this->out(str_repeat('-', $length), $newlines);
310 }
311
312 /**
744e3aa @davidpersson Adding `Command::clear()`, removing auto clear from `li3`.
davidpersson authored
313 * Clears the entire screen.
314 *
315 * @return void
316 */
317 public function clear() {
77967d7 @davidpersson Uppercasing OS name for some flavours of Windows.
davidpersson authored
318 passthru(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? 'cls' : 'clear');
744e3aa @davidpersson Adding `Command::clear()`, removing auto clear from `li3`.
davidpersson authored
319 }
320
321 /**
9562780 @niel Typo, spelling, and punctuation fixes.
niel authored
322 * Stop execution, by exiting the script.
e7f3c31 @gwoo going lithium
gwoo authored
323 *
324 * @param integer $status
325 * @param boolean $message
e9933d1 @davidpersson Updating `Command` class docblocks.
davidpersson authored
326 * @return void
e7f3c31 @gwoo going lithium
gwoo authored
327 */
328 public function stop($status = 0, $message = null) {
1902698 @nateabele Misc. cleanup and refactoring in `\console\Command`.
nateabele authored
329 if ($message) {
330 ($status == 0) ? $this->out($message) : $this->error($message);
e7f3c31 @gwoo going lithium
gwoo authored
331 }
332 exit($status);
333 }
0a65d07 @gwoo refactoring \console\Command
gwoo authored
334
335 /**
336 * Handles the response that is sent to the stream.
337 *
338 * @param string $type the stream either output or error
339 * @param string $string the message to render
340 * @param integer|string|array $options
341 * integer as the number of new lines.
342 * string as the style
343 * array as :
344 * - nl : number of new lines to add at the end
345 * - style : the style name to wrap around the
346 * @return void
347 */
348 protected function _response($type, $string, $options) {
917e4e5 @gwoo some more work on refactor of \console\Command
gwoo authored
349 $defaults = array('nl' => 1, 'style' => null);
1902698 @nateabele Misc. cleanup and refactoring in `\console\Command`.
nateabele authored
350
917e4e5 @gwoo some more work on refactor of \console\Command
gwoo authored
351 if (!is_array($options)) {
352 if (!$options || is_int($options)) {
353 $options = array('nl' => $options);
354 } else if (is_string($options)) {
355 $options = array('style' => $options);
356 } else {
357 $options = array();
358 }
359 }
360 $options += $defaults;
361
0a65d07 @gwoo refactoring \console\Command
gwoo authored
362 if (is_array($string)) {
363 $method = ($type == 'error' ? $type : 'out');
364 foreach ($string as $out) {
917e4e5 @gwoo some more work on refactor of \console\Command
gwoo authored
365 $this->{$method}($out, $options);
0a65d07 @gwoo refactoring \console\Command
gwoo authored
366 }
367 return;
368 }
369 extract($options);
370
7a4cc87 @daschl QA fixes for the console namespace.
daschl authored
371 if ($style !== null) {
0a65d07 @gwoo refactoring \console\Command
gwoo authored
372 $string = "{:{$style}}{$string}{:end}";
373 }
374 if ($nl) {
375 $string = $string . $this->nl($nl);
376 }
377 return $this->response->{$type}($string);
378 }
e7f3c31 @gwoo going lithium
gwoo authored
379 }
380
fc47922 @masom Removes newlines added by nano
masom authored
381 ?>
Something went wrong with that request. Please try again.