Passed
Push — feature/fix-non-seekable-strea... ( e26a6f...fbfc82 )
by Tobias
35:49 queued 32:19
created

Controller   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 282
Duplicated Lines 0 %

Test Coverage

Coverage 78.21%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 78
c 2
b 1
f 0
dl 0
loc 282
ccs 61
cts 78
cp 0.7821
rs 9.36
wmc 38

9 Methods

Rating   Name   Duplication   Size   Complexity  
A goHome() 0 3 1
A redirect() 0 4 1
A beforeAction() 0 11 5
F bindActionParams() 0 81 26
A refresh() 0 3 1
A asJson() 0 5 1
A goBack() 0 3 1
A asXml() 0 5 1
A renderAjax() 0 3 1
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
 * @author Qiang Xue <[email protected]>
21
 * @since 2.0
22
 */
23
class Controller extends \yii\base\Controller
24
{
25
    /**
26
     * @var bool whether to enable CSRF validation for the actions in this controller.
27
     * CSRF validation is enabled only when both this property and [[\yii\web\Request::enableCsrfValidation]] are true.
28
     */
29
    public $enableCsrfValidation = true;
30
    /**
31
     * @var array the parameters bound to the current action.
32
     */
33
    public $actionParams = [];
34
35
36
    /**
37
     * Renders a view in response to an AJAX request.
38
     *
39
     * This method is similar to [[renderPartial()]] except that it will inject into
40
     * the rendering result with JS/CSS scripts and files which are registered with the view.
41
     * For this reason, you should use this method instead of [[renderPartial()]] to render
42
     * a view to respond to an AJAX request.
43
     *
44
     * @param string $view the view name. Please refer to [[render()]] on how to specify a view name.
45
     * @param array $params the parameters (name-value pairs) that should be made available in the view.
46
     * @return string the rendering result.
47
     */
48
    public function renderAjax($view, $params = [])
49
    {
50
        return $this->getView()->renderAjax($view, $params, $this);
0 ignored issues
show
Bug introduced by
The method renderAjax() does not exist on yii\base\View. 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 ignore-call  annotation

50
        return $this->getView()->/** @scrutinizer ignore-call */ renderAjax($view, $params, $this);
Loading history...
51
    }
52
53
    /**
54
     * Send data formatted as JSON.
55
     *
56
     * This method is a shortcut for sending data formatted as JSON. It will return
57
     * the [[Application::getResponse()|response]] application component after configuring
58
     * the [[Response::$format|format]] and setting the [[Response::$data|data]] that should
59
     * be formatted. A common usage will be:
60
     *
61
     * ```php
62
     * return $this->asJson($data);
63
     * ```
64
     *
65
     * @param mixed $data the data that should be formatted.
66
     * @return Response a response that is configured to send `$data` formatted as JSON.
67
     * @since 2.0.11
68
     * @see Response::$format
69
     * @see Response::FORMAT_JSON
70
     * @see JsonResponseFormatter
71
     */
72 1
    public function asJson($data)
73
    {
74 1
        $this->response->format = Response::FORMAT_JSON;
0 ignored issues
show
Bug Best Practice introduced by
The property format does not exist on yii\base\Response. Since you implemented __set, consider adding a @property annotation.
Loading history...
75 1
        $this->response->data = $data;
0 ignored issues
show
Bug Best Practice introduced by
The property data does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
76 1
        return $this->response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->response returns the type array|string which is incompatible with the documented return type yii\web\Response.
Loading history...
77
    }
78
79
    /**
80
     * Send data formatted as XML.
81
     *
82
     * This method is a shortcut for sending data formatted as XML. It will return
83
     * the [[Application::getResponse()|response]] application component after configuring
84
     * the [[Response::$format|format]] and setting the [[Response::$data|data]] that should
85
     * be formatted. A common usage will be:
86
     *
87
     * ```php
88
     * return $this->asXml($data);
89
     * ```
90
     *
91
     * @param mixed $data the data that should be formatted.
92
     * @return Response a response that is configured to send `$data` formatted as XML.
93
     * @since 2.0.11
94
     * @see Response::$format
95
     * @see Response::FORMAT_XML
96
     * @see XmlResponseFormatter
97
     */
98 1
    public function asXml($data)
99
    {
100 1
        $this->response->format = Response::FORMAT_XML;
0 ignored issues
show
Bug Best Practice introduced by
The property format does not exist on yii\base\Response. Since you implemented __set, consider adding a @property annotation.
Loading history...
101 1
        $this->response->data = $data;
0 ignored issues
show
Bug Best Practice introduced by
The property data does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
102 1
        return $this->response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->response returns the type array|string which is incompatible with the documented return type yii\web\Response.
Loading history...
103
    }
104
105
    /**
106
     * Binds the parameters to the action.
107
     * This method is invoked by [[\yii\base\Action]] when it begins to run with the given parameters.
108
     * This method will check the parameter names that the action requires and return
109
     * the provided parameters according to the requirement. If there is any missing parameter,
110
     * an exception will be thrown.
111
     * @param \yii\base\Action $action the action to be bound with parameters
112
     * @param array $params the parameters to be bound to the action
113
     * @return array the valid parameters that the action can run with.
114
     * @throws BadRequestHttpException if there are missing or invalid parameters.
115
     */
116 79
    public function bindActionParams($action, $params)
117
    {
118 79
        if ($action instanceof InlineAction) {
119 71
            $method = new \ReflectionMethod($this, $action->actionMethod);
120
        } else {
121 8
            $method = new \ReflectionMethod($action, 'run');
122
        }
123
124 79
        $args = [];
125 79
        $missing = [];
126 79
        $actionParams = [];
127 79
        $requestedParams = [];
128 79
        foreach ($method->getParameters() as $param) {
129 7
            $name = $param->getName();
130 7
            if (array_key_exists($name, $params)) {
131 5
                $isValid = true;
132 5
                if (PHP_VERSION_ID >= 80000) {
133
                    $isArray = ($type = $param->getType()) instanceof \ReflectionNamedType && $type->getName() === 'array';
134
                } else {
135 5
                    $isArray = $param->isArray();
136
                }
137 5
                if ($isArray) {
138
                    $params[$name] = (array)$params[$name];
139 5
                } elseif (is_array($params[$name])) {
140
                    $isValid = false;
141
                } elseif (
142 5
                    PHP_VERSION_ID >= 70000 &&
143 5
                    ($type = $param->getType()) !== null &&
144 5
                    $type->isBuiltin() &&
145 5
                    ($params[$name] !== null || !$type->allowsNull())
146
                ) {
147 1
                    $typeName = PHP_VERSION_ID >= 70100 ? $type->getName() : (string)$type;
148
                    switch ($typeName) {
149 1
                        case 'int':
150 1
                            $params[$name] = filter_var($params[$name], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
151 1
                            break;
152 1
                        case 'float':
153
                            $params[$name] = filter_var($params[$name], FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE);
154
                            break;
155 1
                        case 'bool':
156 1
                            $params[$name] = filter_var($params[$name], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
157 1
                            break;
158
                    }
159 1
                    if ($params[$name] === null) {
160 1
                        $isValid = false;
161
                    }
162
                }
163 5
                if (!$isValid) {
164 1
                    throw new BadRequestHttpException(Yii::t('yii', 'Invalid data received for parameter "{param}".', [
165 1
                        'param' => $name,
166
                    ]));
167
                }
168 5
                $args[] = $actionParams[$name] = $params[$name];
169 5
                unset($params[$name]);
170 6
            } elseif (PHP_VERSION_ID >= 70100 && ($type = $param->getType()) !== null && !$type->isBuiltin()) {
171
                try {
172 5
                    $this->bindInjectedParams($type, $name, $args, $requestedParams);
173 2
                } catch (Exception $e) {
174 5
                    throw new ServerErrorHttpException($e->getMessage(), 0, $e);
175
                }
176 1
            } elseif ($param->isDefaultValueAvailable()) {
177 1
                $args[] = $actionParams[$name] = $param->getDefaultValue();
178
            } else {
179 7
                $missing[] = $name;
180
            }
181
        }
182
183 77
        if (!empty($missing)) {
184
            throw new BadRequestHttpException(Yii::t('yii', 'Missing required parameters: {params}', [
185
                'params' => implode(', ', $missing),
186
            ]));
187
        }
188
189 77
        $this->actionParams = $actionParams;
190
191
        // We use a different array here, specifically one that doesn't contain service instances but descriptions instead.
192 77
        if (\Yii::$app->requestedParams === null) {
193 77
            \Yii::$app->requestedParams = array_merge($actionParams, $requestedParams);
194
        }
195
196 77
        return $args;
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202 74
    public function beforeAction($action)
203
    {
204 74
        if (parent::beforeAction($action)) {
205 72
            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !$this->request->validateCsrfToken()) {
0 ignored issues
show
Bug introduced by
The method validateCsrfToken() does not exist on yii\base\Request. 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 ignore-call  annotation

205
            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !$this->request->/** @scrutinizer ignore-call */ validateCsrfToken()) {
Loading history...
206
                throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));
207
            }
208
209 72
            return true;
210
        }
211
212
        return false;
213
    }
214
215
    /**
216
     * Redirects the browser to the specified URL.
217
     * This method is a shortcut to [[Response::redirect()]].
218
     *
219
     * You can use it in an action by returning the [[Response]] directly:
220
     *
221
     * ```php
222
     * // stop executing this action and redirect to login page
223
     * return $this->redirect(['login']);
224
     * ```
225
     *
226
     * @param string|array $url the URL to be redirected to. This can be in one of the following formats:
227
     *
228
     * - a string representing a URL (e.g. "http://example.com")
229
     * - a string representing a URL alias (e.g. "@example.com")
230
     * - an array in the format of `[$route, ...name-value pairs...]` (e.g. `['site/index', 'ref' => 1]`)
231
     *   [[Url::to()]] will be used to convert the array into a URL.
232
     *
233
     * Any relative URL that starts with a single forward slash "/" will be converted
234
     * into an absolute one by prepending it with the host info of the current request.
235
     *
236
     * @param int $statusCode the HTTP status code. Defaults to 302.
237
     * See <https://tools.ietf.org/html/rfc2616#section-10>
238
     * for details about HTTP status code
239
     * @return Response the current response object
240
     */
241 1
    public function redirect($url, $statusCode = 302)
242
    {
243
        // calling Url::to() here because Response::redirect() modifies route before calling Url::to()
244 1
        return $this->response->redirect(Url::to($url), $statusCode);
0 ignored issues
show
Bug introduced by
The method redirect() does not exist on yii\base\Response. 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 ignore-call  annotation

244
        return $this->response->/** @scrutinizer ignore-call */ redirect(Url::to($url), $statusCode);
Loading history...
245
    }
246
247
    /**
248
     * Redirects the browser to the home page.
249
     *
250
     * You can use this method in an action by returning the [[Response]] directly:
251
     *
252
     * ```php
253
     * // stop executing this action and redirect to home page
254
     * return $this->goHome();
255
     * ```
256
     *
257
     * @return Response the current response object
258
     */
259
    public function goHome()
260
    {
261
        return $this->response->redirect(Yii::$app->getHomeUrl());
0 ignored issues
show
Bug introduced by
The method getHomeUrl() 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 ignore-call  annotation

261
        return $this->response->redirect(Yii::$app->/** @scrutinizer ignore-call */ getHomeUrl());
Loading history...
262
    }
263
264
    /**
265
     * Redirects the browser to the last visited page.
266
     *
267
     * You can use this method in an action by returning the [[Response]] directly:
268
     *
269
     * ```php
270
     * // stop executing this action and redirect to last visited page
271
     * return $this->goBack();
272
     * ```
273
     *
274
     * For this function to work you have to [[User::setReturnUrl()|set the return URL]] in appropriate places before.
275
     *
276
     * @param string|array $defaultUrl the default return URL in case it was not set previously.
277
     * If this is null and the return URL was not set previously, [[Application::homeUrl]] will be redirected to.
278
     * Please refer to [[User::setReturnUrl()]] on accepted format of the URL.
279
     * @return Response the current response object
280
     * @see User::getReturnUrl()
281
     */
282
    public function goBack($defaultUrl = null)
283
    {
284
        return $this->response->redirect(Yii::$app->getUser()->getReturnUrl($defaultUrl));
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

284
        return $this->response->redirect(Yii::$app->/** @scrutinizer ignore-call */ getUser()->getReturnUrl($defaultUrl));
Loading history...
285
    }
286
287
    /**
288
     * Refreshes the current page.
289
     * This method is a shortcut to [[Response::refresh()]].
290
     *
291
     * You can use it in an action by returning the [[Response]] directly:
292
     *
293
     * ```php
294
     * // stop executing this action and refresh the current page
295
     * return $this->refresh();
296
     * ```
297
     *
298
     * @param string $anchor the anchor that should be appended to the redirection URL.
299
     * Defaults to empty. Make sure the anchor starts with '#' if you want to specify it.
300
     * @return Response the response object itself
301
     */
302
    public function refresh($anchor = '')
303
    {
304
        return $this->response->redirect($this->request->getUrl() . $anchor);
0 ignored issues
show
Bug introduced by
The method getUrl() does not exist on yii\base\Request. 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 ignore-call  annotation

304
        return $this->response->redirect($this->request->/** @scrutinizer ignore-call */ getUrl() . $anchor);
Loading history...
305
    }
306
}
307