1 | <?php |
||
2 | /** |
||
3 | * @link http://www.yiiframework.com/ |
||
4 | * @copyright Copyright (c) 2008 Yii Software LLC |
||
5 | * @license http://www.yiiframework.com/license/ |
||
6 | */ |
||
7 | |||
8 | namespace yii\console; |
||
9 | |||
10 | use Yii; |
||
11 | use yii\base\InvalidRouteException; |
||
12 | |||
13 | // define STDIN, STDOUT and STDERR if the PHP SAPI did not define them (e.g. creating console application in web env) |
||
14 | // https://secure.php.net/manual/en/features.commandline.io-streams.php |
||
15 | 3 | defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); |
|
16 | 3 | defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w')); |
|
17 | 3 | defined('STDERR') or define('STDERR', fopen('php://stderr', 'w')); |
|
18 | |||
19 | /** |
||
20 | * Application represents a console application. |
||
21 | * |
||
22 | * Application extends from [[\yii\base\Application]] by providing functionalities that are |
||
23 | * specific to console requests. In particular, it deals with console requests |
||
24 | * through a command-based approach: |
||
25 | * |
||
26 | * - A console application consists of one or several possible user commands; |
||
27 | * - Each user command is implemented as a class extending [[\yii\console\Controller]]; |
||
28 | * - User specifies which command to run on the command line; |
||
29 | * - The command processes the user request with the specified parameters. |
||
30 | * |
||
31 | * The command classes should be under the namespace specified by [[controllerNamespace]]. |
||
32 | * Their naming should follow the same naming convention as controllers. For example, the `help` command |
||
33 | * is implemented using the `HelpController` class. |
||
34 | * |
||
35 | * To run the console application, enter the following on the command line: |
||
36 | * |
||
37 | * ``` |
||
38 | * yii <route> [--param1=value1 --param2 ...] |
||
39 | * ``` |
||
40 | * |
||
41 | * where `<route>` refers to a controller route in the form of `ModuleID/ControllerID/ActionID` |
||
42 | * (e.g. `sitemap/create`), and `param1`, `param2` refers to a set of named parameters that |
||
43 | * will be used to initialize the controller action (e.g. `--since=0` specifies a `since` parameter |
||
44 | * whose value is 0 and a corresponding `$since` parameter is passed to the action method). |
||
45 | * |
||
46 | * A `help` command is provided by default, which lists available commands and shows their usage. |
||
47 | * To use this command, simply type: |
||
48 | * |
||
49 | * ``` |
||
50 | * yii help |
||
51 | * ``` |
||
52 | * |
||
53 | * @property-read ErrorHandler $errorHandler The error handler application component. This property is |
||
54 | * read-only. |
||
55 | * @property-read Request $request The request component. This property is read-only. |
||
56 | * @property-read Response $response The response component. This property is read-only. |
||
57 | * |
||
58 | * @author Qiang Xue <[email protected]> |
||
59 | * @since 2.0 |
||
60 | */ |
||
61 | class Application extends \yii\base\Application |
||
62 | { |
||
63 | /** |
||
64 | * The option name for specifying the application configuration file path. |
||
65 | */ |
||
66 | const OPTION_APPCONFIG = 'appconfig'; |
||
67 | |||
68 | /** |
||
69 | * @var string the default route of this application. Defaults to 'help', |
||
70 | * meaning the `help` command. |
||
71 | */ |
||
72 | public $defaultRoute = 'help'; |
||
73 | /** |
||
74 | * @var bool whether to enable the commands provided by the core framework. |
||
75 | * Defaults to true. |
||
76 | */ |
||
77 | public $enableCoreCommands = true; |
||
78 | /** |
||
79 | * @var Controller the currently active controller instance |
||
80 | */ |
||
81 | public $controller; |
||
82 | |||
83 | |||
84 | /** |
||
85 | * {@inheritdoc} |
||
86 | */ |
||
87 | 4937 | public function __construct($config = []) |
|
88 | { |
||
89 | 4937 | $config = $this->loadConfig($config); |
|
90 | 4937 | parent::__construct($config); |
|
91 | 4937 | } |
|
92 | |||
93 | /** |
||
94 | * Loads the configuration. |
||
95 | * This method will check if the command line option [[OPTION_APPCONFIG]] is specified. |
||
96 | * If so, the corresponding file will be loaded as the application configuration. |
||
97 | * Otherwise, the configuration provided as the parameter will be returned back. |
||
98 | * @param array $config the configuration provided in the constructor. |
||
99 | * @return array the actual configuration to be used by the application. |
||
100 | */ |
||
101 | 4937 | protected function loadConfig($config) |
|
102 | { |
||
103 | 4937 | if (!empty($_SERVER['argv'])) { |
|
104 | 4937 | $option = '--' . self::OPTION_APPCONFIG . '='; |
|
105 | 4937 | foreach ($_SERVER['argv'] as $param) { |
|
106 | 4937 | if (strpos($param, $option) !== false) { |
|
107 | $path = substr($param, strlen($option)); |
||
108 | if (!empty($path) && is_file($file = Yii::getAlias($path))) { |
||
109 | return require $file; |
||
110 | } |
||
111 | |||
112 | 4937 | exit("The configuration file does not exist: $path\n"); |
|
0 ignored issues
–
show
|
|||
113 | } |
||
114 | } |
||
115 | } |
||
116 | |||
117 | 4937 | return $config; |
|
118 | } |
||
119 | |||
120 | /** |
||
121 | * Initialize the application. |
||
122 | */ |
||
123 | 4937 | public function init() |
|
124 | { |
||
125 | 4937 | parent::init(); |
|
126 | 4937 | if ($this->enableCoreCommands) { |
|
127 | 4919 | foreach ($this->coreCommands() as $id => $command) { |
|
128 | 4919 | if (!isset($this->controllerMap[$id])) { |
|
129 | 4919 | $this->controllerMap[$id] = $command; |
|
130 | } |
||
131 | } |
||
132 | } |
||
133 | // ensure we have the 'help' command so that we can list the available commands |
||
134 | 4937 | if (!isset($this->controllerMap['help'])) { |
|
135 | 24 | $this->controllerMap['help'] = 'yii\console\controllers\HelpController'; |
|
136 | } |
||
137 | 4937 | } |
|
138 | |||
139 | /** |
||
140 | * Handles the specified request. |
||
141 | * @param Request $request the request to be handled |
||
142 | * @return Response the resulting response |
||
143 | */ |
||
144 | 1 | public function handleRequest($request) |
|
145 | { |
||
146 | 1 | list($route, $params) = $request->resolve(); |
|
147 | 1 | $this->requestedRoute = $route; |
|
148 | 1 | $result = $this->runAction($route, $params); |
|
149 | 1 | if ($result instanceof Response) { |
|
150 | 1 | return $result; |
|
151 | } |
||
152 | |||
153 | 1 | $response = $this->getResponse(); |
|
154 | 1 | $response->exitStatus = $result; |
|
155 | |||
156 | 1 | return $response; |
|
157 | } |
||
158 | |||
159 | /** |
||
160 | * Runs a controller action specified by a route. |
||
161 | * This method parses the specified route and creates the corresponding child module(s), controller and action |
||
162 | * instances. It then calls [[Controller::runAction()]] to run the action with the given parameters. |
||
163 | * If the route is empty, the method will use [[defaultRoute]]. |
||
164 | * |
||
165 | * For example, to run `public function actionTest($a, $b)` assuming that the controller has options the following |
||
166 | * code should be used: |
||
167 | * |
||
168 | * ```php |
||
169 | * \Yii::$app->runAction('controller/test', ['option' => 'value', $a, $b]); |
||
170 | * ``` |
||
171 | * |
||
172 | * @param string $route the route that specifies the action. |
||
173 | * @param array $params the parameters to be passed to the action |
||
174 | * @return int|Response the result of the action. This can be either an exit code or Response object. |
||
175 | * Exit code 0 means normal, and other values mean abnormal. Exit code of `null` is treated as `0` as well. |
||
176 | * @throws Exception if the route is invalid |
||
177 | */ |
||
178 | 9 | public function runAction($route, $params = []) |
|
179 | { |
||
180 | try { |
||
181 | 9 | $res = parent::runAction($route, $params); |
|
182 | 9 | return is_object($res) ? $res : (int) $res; |
|
183 | } catch (InvalidRouteException $e) { |
||
184 | throw new UnknownCommandException($route, $this, 0, $e); |
||
185 | } |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * Returns the configuration of the built-in commands. |
||
190 | * @return array the configuration of the built-in commands. |
||
191 | */ |
||
192 | 4919 | public function coreCommands() |
|
193 | { |
||
194 | return [ |
||
195 | 4919 | 'asset' => 'yii\console\controllers\AssetController', |
|
196 | 'cache' => 'yii\console\controllers\CacheController', |
||
197 | 'fixture' => 'yii\console\controllers\FixtureController', |
||
198 | 'help' => 'yii\console\controllers\HelpController', |
||
199 | 'message' => 'yii\console\controllers\MessageController', |
||
200 | 'migrate' => 'yii\console\controllers\MigrateController', |
||
201 | 'serve' => 'yii\console\controllers\ServeController', |
||
202 | ]; |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * Returns the error handler component. |
||
207 | * @return ErrorHandler the error handler application component. |
||
208 | */ |
||
209 | public function getErrorHandler() |
||
210 | { |
||
211 | return $this->get('errorHandler'); |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Returns the request component. |
||
216 | * @return Request the request component. |
||
217 | */ |
||
218 | 120 | public function getRequest() |
|
219 | { |
||
220 | 120 | return $this->get('request'); |
|
221 | } |
||
222 | |||
223 | /** |
||
224 | * Returns the response component. |
||
225 | * @return Response the response component. |
||
226 | */ |
||
227 | 3 | public function getResponse() |
|
228 | { |
||
229 | 3 | return $this->get('response'); |
|
230 | } |
||
231 | |||
232 | /** |
||
233 | * {@inheritdoc} |
||
234 | */ |
||
235 | 4937 | public function coreComponents() |
|
236 | { |
||
237 | 4937 | return array_merge(parent::coreComponents(), [ |
|
238 | 4937 | 'request' => ['class' => 'yii\console\Request'], |
|
239 | 'response' => ['class' => 'yii\console\Response'], |
||
240 | 'errorHandler' => ['class' => 'yii\console\ErrorHandler'], |
||
241 | ]); |
||
242 | } |
||
243 | } |
||
244 |
In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.