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