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\web; |
||||||
9 | |||||||
10 | use Yii; |
||||||
11 | use yii\base\Exception; |
||||||
12 | use yii\base\InlineAction; |
||||||
13 | use yii\helpers\Url; |
||||||
14 | |||||||
15 | /** |
||||||
16 | * Controller is the base class of web controllers. |
||||||
17 | * |
||||||
18 | * For more details and usage information on Controller, see the [guide article on controllers](guide:structure-controllers). |
||||||
19 | * |
||||||
20 | * @property Request $request |
||||||
21 | * @property Response $response |
||||||
22 | * |
||||||
23 | * @author Qiang Xue <[email protected]> |
||||||
24 | * @since 2.0 |
||||||
25 | */ |
||||||
26 | class Controller extends \yii\base\Controller |
||||||
27 | { |
||||||
28 | /** |
||||||
29 | * @var bool whether to enable CSRF validation for the actions in this controller. |
||||||
30 | * CSRF validation is enabled only when both this property and [[\yii\web\Request::enableCsrfValidation]] are true. |
||||||
31 | */ |
||||||
32 | public $enableCsrfValidation = true; |
||||||
33 | /** |
||||||
34 | * @var array the parameters bound to the current action. |
||||||
35 | */ |
||||||
36 | public $actionParams = []; |
||||||
37 | |||||||
38 | |||||||
39 | /** |
||||||
40 | * Renders a view in response to an AJAX request. |
||||||
41 | * |
||||||
42 | * This method is similar to [[renderPartial()]] except that it will inject into |
||||||
43 | * the rendering result with JS/CSS scripts and files which are registered with the view. |
||||||
44 | * For this reason, you should use this method instead of [[renderPartial()]] to render |
||||||
45 | * a view to respond to an AJAX request. |
||||||
46 | * |
||||||
47 | * @param string $view the view name. Please refer to [[render()]] on how to specify a view name. |
||||||
48 | * @param array $params the parameters (name-value pairs) that should be made available in the view. |
||||||
49 | * @return string the rendering result. |
||||||
50 | */ |
||||||
51 | public function renderAjax($view, $params = []) |
||||||
52 | { |
||||||
53 | return $this->getView()->renderAjax($view, $params, $this); |
||||||
54 | } |
||||||
55 | |||||||
56 | /** |
||||||
57 | * Send data formatted as JSON. |
||||||
58 | * |
||||||
59 | * This method is a shortcut for sending data formatted as JSON. It will return |
||||||
60 | * the [[Application::getResponse()|response]] application component after configuring |
||||||
61 | * the [[Response::$format|format]] and setting the [[Response::$data|data]] that should |
||||||
62 | * be formatted. A common usage will be: |
||||||
63 | * |
||||||
64 | * ```php |
||||||
65 | * return $this->asJson($data); |
||||||
66 | * ``` |
||||||
67 | * |
||||||
68 | * @param mixed $data the data that should be formatted. |
||||||
69 | * @return Response a response that is configured to send `$data` formatted as JSON. |
||||||
70 | * @since 2.0.11 |
||||||
71 | * @see Response::$format |
||||||
72 | * @see Response::FORMAT_JSON |
||||||
73 | * @see JsonResponseFormatter |
||||||
74 | */ |
||||||
75 | 1 | public function asJson($data) |
|||||
76 | { |
||||||
77 | 1 | $this->response->format = Response::FORMAT_JSON; |
|||||
78 | 1 | $this->response->data = $data; |
|||||
79 | 1 | return $this->response; |
|||||
80 | } |
||||||
81 | |||||||
82 | /** |
||||||
83 | * Send data formatted as XML. |
||||||
84 | * |
||||||
85 | * This method is a shortcut for sending data formatted as XML. It will return |
||||||
86 | * the [[Application::getResponse()|response]] application component after configuring |
||||||
87 | * the [[Response::$format|format]] and setting the [[Response::$data|data]] that should |
||||||
88 | * be formatted. A common usage will be: |
||||||
89 | * |
||||||
90 | * ```php |
||||||
91 | * return $this->asXml($data); |
||||||
92 | * ``` |
||||||
93 | * |
||||||
94 | * @param mixed $data the data that should be formatted. |
||||||
95 | * @return Response a response that is configured to send `$data` formatted as XML. |
||||||
96 | * @since 2.0.11 |
||||||
97 | * @see Response::$format |
||||||
98 | * @see Response::FORMAT_XML |
||||||
99 | * @see XmlResponseFormatter |
||||||
100 | */ |
||||||
101 | 1 | public function asXml($data) |
|||||
102 | { |
||||||
103 | 1 | $this->response->format = Response::FORMAT_XML; |
|||||
104 | 1 | $this->response->data = $data; |
|||||
105 | 1 | return $this->response; |
|||||
106 | } |
||||||
107 | |||||||
108 | /** |
||||||
109 | * Binds the parameters to the action. |
||||||
110 | * This method is invoked by [[\yii\base\Action]] when it begins to run with the given parameters. |
||||||
111 | * This method will check the parameter names that the action requires and return |
||||||
112 | * the provided parameters according to the requirement. If there is any missing parameter, |
||||||
113 | * an exception will be thrown. |
||||||
114 | * @param \yii\base\Action $action the action to be bound with parameters |
||||||
115 | * @param array $params the parameters to be bound to the action |
||||||
116 | * @return array the valid parameters that the action can run with. |
||||||
117 | * @throws BadRequestHttpException if there are missing or invalid parameters. |
||||||
118 | */ |
||||||
119 | 81 | public function bindActionParams($action, $params) |
|||||
120 | { |
||||||
121 | 81 | if ($action instanceof InlineAction) { |
|||||
122 | 72 | $method = new \ReflectionMethod($this, $action->actionMethod); |
|||||
123 | } else { |
||||||
124 | 9 | $method = new \ReflectionMethod($action, 'run'); |
|||||
125 | } |
||||||
126 | |||||||
127 | 81 | $args = []; |
|||||
128 | 81 | $missing = []; |
|||||
129 | 81 | $actionParams = []; |
|||||
130 | 81 | $requestedParams = []; |
|||||
131 | 81 | foreach ($method->getParameters() as $param) { |
|||||
132 | 8 | $name = $param->getName(); |
|||||
133 | 8 | if (array_key_exists($name, $params)) { |
|||||
134 | 5 | $isValid = true; |
|||||
135 | 5 | if (PHP_VERSION_ID >= 80000) { |
|||||
136 | $isArray = ($type = $param->getType()) instanceof \ReflectionNamedType && $type->getName() === 'array'; |
||||||
137 | } else { |
||||||
138 | 5 | $isArray = $param->isArray(); |
|||||
139 | } |
||||||
140 | 5 | if ($isArray) { |
|||||
141 | $params[$name] = (array)$params[$name]; |
||||||
142 | 5 | } elseif (is_array($params[$name])) { |
|||||
143 | $isValid = false; |
||||||
144 | } elseif ( |
||||||
145 | 5 | PHP_VERSION_ID >= 70000 |
|||||
146 | 5 | && ($type = $param->getType()) !== null |
|||||
147 | 5 | && $type->isBuiltin() |
|||||
148 | 5 | && ($params[$name] !== null || !$type->allowsNull()) |
|||||
149 | ) { |
||||||
150 | 1 | $typeName = PHP_VERSION_ID >= 70100 ? $type->getName() : (string)$type; |
|||||
151 | |||||||
152 | 1 | if ($params[$name] === '' && $type->allowsNull()) { |
|||||
153 | 1 | if ($typeName !== 'string') { // for old string behavior compatibility |
|||||
154 | 1 | $params[$name] = null; |
|||||
155 | } |
||||||
156 | } else { |
||||||
157 | switch ($typeName) { |
||||||
158 | 1 | case 'int': |
|||||
159 | 1 | $params[$name] = filter_var($params[$name], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); |
|||||
160 | 1 | break; |
|||||
161 | 1 | case 'float': |
|||||
162 | $params[$name] = filter_var($params[$name], FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE); |
||||||
163 | break; |
||||||
164 | 1 | case 'bool': |
|||||
165 | 1 | $params[$name] = filter_var($params[$name], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); |
|||||
166 | 1 | break; |
|||||
167 | } |
||||||
168 | 1 | if ($params[$name] === null) { |
|||||
169 | 1 | $isValid = false; |
|||||
170 | } |
||||||
171 | } |
||||||
172 | } |
||||||
173 | 5 | if (!$isValid) { |
|||||
174 | 1 | throw new BadRequestHttpException( |
|||||
175 | 1 | Yii::t('yii', 'Invalid data received for parameter "{param}".', ['param' => $name]) |
|||||
176 | ); |
||||||
177 | } |
||||||
178 | 5 | $args[] = $actionParams[$name] = $params[$name]; |
|||||
179 | 5 | unset($params[$name]); |
|||||
180 | 7 | } elseif (PHP_VERSION_ID >= 70100 && ($type = $param->getType()) !== null && !$type->isBuiltin()) { |
|||||
181 | try { |
||||||
182 | 6 | $this->bindInjectedParams($type, $name, $args, $requestedParams); |
|||||
183 | 3 | } catch (HttpException $e) { |
|||||
184 | 1 | throw $e; |
|||||
185 | 2 | } catch (Exception $e) { |
|||||
186 | 5 | throw new ServerErrorHttpException($e->getMessage(), 0, $e); |
|||||
187 | } |
||||||
188 | 1 | } elseif ($param->isDefaultValueAvailable()) { |
|||||
189 | 1 | $args[] = $actionParams[$name] = $param->getDefaultValue(); |
|||||
190 | } else { |
||||||
191 | 7 | $missing[] = $name; |
|||||
192 | } |
||||||
193 | } |
||||||
194 | |||||||
195 | 78 | if (!empty($missing)) { |
|||||
196 | throw new BadRequestHttpException( |
||||||
197 | Yii::t('yii', 'Missing required parameters: {params}', ['params' => implode(', ', $missing)]) |
||||||
198 | ); |
||||||
199 | } |
||||||
200 | |||||||
201 | 78 | $this->actionParams = $actionParams; |
|||||
202 | |||||||
203 | // We use a different array here, specifically one that doesn't contain service instances but descriptions instead. |
||||||
204 | 78 | if (Yii::$app->requestedParams === null) { |
|||||
205 | 78 | Yii::$app->requestedParams = array_merge($actionParams, $requestedParams); |
|||||
206 | } |
||||||
207 | |||||||
208 | 78 | return $args; |
|||||
209 | } |
||||||
210 | |||||||
211 | /** |
||||||
212 | * {@inheritdoc} |
||||||
213 | */ |
||||||
214 | 75 | public function beforeAction($action) |
|||||
215 | { |
||||||
216 | 75 | if (parent::beforeAction($action)) { |
|||||
217 | 73 | if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !$this->request->validateCsrfToken()) { |
|||||
218 | throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.')); |
||||||
219 | } |
||||||
220 | |||||||
221 | 73 | return true; |
|||||
222 | } |
||||||
223 | |||||||
224 | return false; |
||||||
225 | } |
||||||
226 | |||||||
227 | /** |
||||||
228 | * Redirects the browser to the specified URL. |
||||||
229 | * This method is a shortcut to [[Response::redirect()]]. |
||||||
230 | * |
||||||
231 | * You can use it in an action by returning the [[Response]] directly: |
||||||
232 | * |
||||||
233 | * ```php |
||||||
234 | * // stop executing this action and redirect to login page |
||||||
235 | * return $this->redirect(['login']); |
||||||
236 | * ``` |
||||||
237 | * |
||||||
238 | * @param string|array $url the URL to be redirected to. This can be in one of the following formats: |
||||||
239 | * |
||||||
240 | * - a string representing a URL (e.g. "http://example.com") |
||||||
241 | * - a string representing a URL alias (e.g. "@example.com") |
||||||
242 | * - an array in the format of `[$route, ...name-value pairs...]` (e.g. `['site/index', 'ref' => 1]`) |
||||||
243 | * [[Url::to()]] will be used to convert the array into a URL. |
||||||
244 | * |
||||||
245 | * Any relative URL that starts with a single forward slash "/" will be converted |
||||||
246 | * into an absolute one by prepending it with the host info of the current request. |
||||||
247 | * |
||||||
248 | * @param int $statusCode the HTTP status code. Defaults to 302. |
||||||
249 | * See <https://tools.ietf.org/html/rfc2616#section-10> |
||||||
250 | * for details about HTTP status code |
||||||
251 | * @return Response the current response object |
||||||
252 | */ |
||||||
253 | 1 | public function redirect($url, $statusCode = 302) |
|||||
254 | { |
||||||
255 | // calling Url::to() here because Response::redirect() modifies route before calling Url::to() |
||||||
256 | 1 | return $this->response->redirect(Url::to($url), $statusCode); |
|||||
257 | } |
||||||
258 | |||||||
259 | /** |
||||||
260 | * Redirects the browser to the home page. |
||||||
261 | * |
||||||
262 | * You can use this method in an action by returning the [[Response]] directly: |
||||||
263 | * |
||||||
264 | * ```php |
||||||
265 | * // stop executing this action and redirect to home page |
||||||
266 | * return $this->goHome(); |
||||||
267 | * ``` |
||||||
268 | * |
||||||
269 | * @return Response the current response object |
||||||
270 | */ |
||||||
271 | public function goHome() |
||||||
272 | { |
||||||
273 | return $this->response->redirect(Yii::$app->getHomeUrl()); |
||||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
The method
getHomeUrl() does not exist on yii\base\Application . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
274 | } |
||||||
275 | |||||||
276 | /** |
||||||
277 | * Redirects the browser to the last visited page. |
||||||
278 | * |
||||||
279 | * You can use this method in an action by returning the [[Response]] directly: |
||||||
280 | * |
||||||
281 | * ```php |
||||||
282 | * // stop executing this action and redirect to last visited page |
||||||
283 | * return $this->goBack(); |
||||||
284 | * ``` |
||||||
285 | * |
||||||
286 | * For this function to work you have to [[User::setReturnUrl()|set the return URL]] in appropriate places before. |
||||||
287 | * |
||||||
288 | * @param string|array $defaultUrl the default return URL in case it was not set previously. |
||||||
289 | * If this is null and the return URL was not set previously, [[Application::homeUrl]] will be redirected to. |
||||||
290 | * Please refer to [[User::setReturnUrl()]] on accepted format of the URL. |
||||||
291 | * @return Response the current response object |
||||||
292 | * @see User::getReturnUrl() |
||||||
293 | */ |
||||||
294 | public function goBack($defaultUrl = null) |
||||||
295 | { |
||||||
296 | return $this->response->redirect(Yii::$app->getUser()->getReturnUrl($defaultUrl)); |
||||||
0 ignored issues
–
show
The method
getUser() does not exist on yii\console\Application . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
The method
getUser() does not exist on yii\base\Application . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
297 | } |
||||||
298 | |||||||
299 | /** |
||||||
300 | * Refreshes the current page. |
||||||
301 | * This method is a shortcut to [[Response::refresh()]]. |
||||||
302 | * |
||||||
303 | * You can use it in an action by returning the [[Response]] directly: |
||||||
304 | * |
||||||
305 | * ```php |
||||||
306 | * // stop executing this action and refresh the current page |
||||||
307 | * return $this->refresh(); |
||||||
308 | * ``` |
||||||
309 | * |
||||||
310 | * @param string $anchor the anchor that should be appended to the redirection URL. |
||||||
311 | * Defaults to empty. Make sure the anchor starts with '#' if you want to specify it. |
||||||
312 | * @return Response the response object itself |
||||||
313 | */ |
||||||
314 | public function refresh($anchor = '') |
||||||
315 | { |
||||||
316 | return $this->response->redirect($this->request->getUrl() . $anchor); |
||||||
317 | } |
||||||
318 | } |
||||||
319 |