Passed
Push — php74-fixes-without-tests ( 2b3515...7f31b3 )
by Alexander
54:23 queued 18:06
created

Controller::bindActionParams()   D

Complexity

Conditions 18
Paths 102

Size

Total Lines 61
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 19.6115

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 44
nc 102
nop 2
dl 0
loc 61
ccs 34
cts 41
cp 0.8293
crap 19.6115
rs 4.85
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\InlineAction;
12
use yii\helpers\Url;
13
14
/**
15
 * Controller is the base class of web controllers.
16
 *
17
 * For more details and usage information on Controller, see the [guide article on controllers](guide:structure-controllers).
18
 *
19
 * @author Qiang Xue <[email protected]>
20
 * @since 2.0
21
 */
22
class Controller extends \yii\base\Controller
23
{
24
    /**
25
     * @var bool whether to enable CSRF validation for the actions in this controller.
26
     * CSRF validation is enabled only when both this property and [[\yii\web\Request::enableCsrfValidation]] are true.
27
     */
28
    public $enableCsrfValidation = true;
29
    /**
30
     * @var array the parameters bound to the current action.
31
     */
32
    public $actionParams = [];
33
34
35
    /**
36
     * Renders a view in response to an AJAX request.
37
     *
38
     * This method is similar to [[renderPartial()]] except that it will inject into
39
     * the rendering result with JS/CSS scripts and files which are registered with the view.
40
     * For this reason, you should use this method instead of [[renderPartial()]] to render
41
     * a view to respond to an AJAX request.
42
     *
43
     * @param string $view the view name. Please refer to [[render()]] on how to specify a view name.
44
     * @param array $params the parameters (name-value pairs) that should be made available in the view.
45
     * @return string the rendering result.
46
     */
47
    public function renderAjax($view, $params = [])
48
    {
49
        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

49
        return $this->getView()->/** @scrutinizer ignore-call */ renderAjax($view, $params, $this);
Loading history...
50
    }
51
52
    /**
53
     * Send data formatted as JSON.
54
     *
55
     * This method is a shortcut for sending data formatted as JSON. It will return
56
     * the [[Application::getResponse()|response]] application component after configuring
57
     * the [[Response::$format|format]] and setting the [[Response::$data|data]] that should
58
     * be formatted. A common usage will be:
59
     *
60
     * ```php
61
     * return $this->asJson($data);
62
     * ```
63
     *
64
     * @param mixed $data the data that should be formatted.
65
     * @return Response a response that is configured to send `$data` formatted as JSON.
66
     * @since 2.0.11
67
     * @see Response::$format
68
     * @see Response::FORMAT_JSON
69
     * @see JsonResponseFormatter
70
     */
71 1
    public function asJson($data)
72
    {
73 1
        $response = Yii::$app->getResponse();
74 1
        $response->format = Response::FORMAT_JSON;
0 ignored issues
show
Bug Best Practice introduced by
The property format does not exist on yii\console\Response. Since you implemented __set, consider adding a @property annotation.
Loading history...
75 1
        $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 $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response also could return the type yii\console\Response 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
        $response = Yii::$app->getResponse();
101 1
        $response->format = Response::FORMAT_XML;
0 ignored issues
show
Bug Best Practice introduced by
The property format does not exist on yii\console\Response. Since you implemented __set, consider adding a @property annotation.
Loading history...
102 1
        $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...
103 1
        return $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response also could return the type yii\console\Response which is incompatible with the documented return type yii\web\Response.
Loading history...
104
    }
105
106
    /**
107
     * Binds the parameters to the action.
108
     * This method is invoked by [[\yii\base\Action]] when it begins to run with the given parameters.
109
     * This method will check the parameter names that the action requires and return
110
     * the provided parameters according to the requirement. If there is any missing parameter,
111
     * an exception will be thrown.
112
     * @param \yii\base\Action $action the action to be bound with parameters
113
     * @param array $params the parameters to be bound to the action
114
     * @return array the valid parameters that the action can run with.
115
     * @throws BadRequestHttpException if there are missing or invalid parameters.
116
     */
117 69
    public function bindActionParams($action, $params)
118
    {
119 69
        if ($action instanceof InlineAction) {
120 61
            $method = new \ReflectionMethod($this, $action->actionMethod);
121
        } else {
122 8
            $method = new \ReflectionMethod($action, 'run');
123
        }
124
125 69
        $args = [];
126 69
        $missing = [];
127 69
        $actionParams = [];
128 69
        foreach ($method->getParameters() as $param) {
129 2
            $name = $param->getName();
130 2
            if (array_key_exists($name, $params)) {
131 2
                $isValid = true;
132 2
                if ($param->isArray()) {
133
                    $params[$name] = (array)$params[$name];
134 2
                } elseif (is_array($params[$name])) {
135
                    $isValid = false;
136
                } elseif (
137 2
                    PHP_VERSION_ID >= 70000 &&
138 2
                    ($type = $param->getType()) !== null &&
139 2
                    $type->isBuiltin() &&
140 2
                    ($params[$name] !== null || !$type->allowsNull())
141
                ) {
142 1
                    $name = PHP_VERSION_ID >= 74000 ? $type->getName() : (string)$type;
143 1
                    switch ($name) {
144 1
                        case 'int':
145 1
                            $params[$name] = filter_var($params[$name], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
146
                            break;
147
                        case 'float':
148
                            $params[$name] = filter_var($params[$name], FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE);
149
                            break;
150 1
                    }
151 1
                    if ($params[$name] === null) {
152
                        $isValid = false;
153
                    }
154 2
                }
155 1
                if (!$isValid) {
156 1
                    throw new BadRequestHttpException(Yii::t('yii', 'Invalid data received for parameter "{param}".', [
157
                        'param' => $name,
158
                    ]));
159 2
                }
160 2
                $args[] = $actionParams[$name] = $params[$name];
161 1
                unset($params[$name]);
162 1
            } elseif ($param->isDefaultValueAvailable()) {
163
                $args[] = $actionParams[$name] = $param->getDefaultValue();
164 2
            } else {
165
                $missing[] = $name;
166
            }
167
        }
168 69
169
        if (!empty($missing)) {
170
            throw new BadRequestHttpException(Yii::t('yii', 'Missing required parameters: {params}', [
171
                'params' => implode(', ', $missing),
172
            ]));
173
        }
174 69
175
        $this->actionParams = $actionParams;
176 69
177
        return $args;
178
    }
179
180
    /**
181
     * {@inheritdoc}
182 69
     */
183
    public function beforeAction($action)
184 69
    {
185 67
        if (parent::beforeAction($action)) {
186
            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !Yii::$app->getRequest()->validateCsrfToken()) {
0 ignored issues
show
Bug introduced by
The method validateCsrfToken() does not exist on yii\console\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

186
            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !Yii::$app->getRequest()->/** @scrutinizer ignore-call */ validateCsrfToken()) {
Loading history...
187
                throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));
188
            }
189 67
190
            return true;
191
        }
192
193
        return false;
194
    }
195
196
    /**
197
     * Redirects the browser to the specified URL.
198
     * This method is a shortcut to [[Response::redirect()]].
199
     *
200
     * You can use it in an action by returning the [[Response]] directly:
201
     *
202
     * ```php
203
     * // stop executing this action and redirect to login page
204
     * return $this->redirect(['login']);
205
     * ```
206
     *
207
     * @param string|array $url the URL to be redirected to. This can be in one of the following formats:
208
     *
209
     * - a string representing a URL (e.g. "http://example.com")
210
     * - a string representing a URL alias (e.g. "@example.com")
211
     * - an array in the format of `[$route, ...name-value pairs...]` (e.g. `['site/index', 'ref' => 1]`)
212
     *   [[Url::to()]] will be used to convert the array into a URL.
213
     *
214
     * Any relative URL that starts with a single forward slash "/" will be converted
215
     * into an absolute one by prepending it with the host info of the current request.
216
     *
217
     * @param int $statusCode the HTTP status code. Defaults to 302.
218
     * See <https://tools.ietf.org/html/rfc2616#section-10>
219
     * for details about HTTP status code
220
     * @return Response the current response object
221 1
     */
222
    public function redirect($url, $statusCode = 302)
223
    {
224 1
        // calling Url::to() here because Response::redirect() modifies route before calling Url::to()
225
        return Yii::$app->getResponse()->redirect(Url::to($url), $statusCode);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Yii::app->getResp...:to($url), $statusCode) also could return the type yii\console\Response which is incompatible with the documented return type yii\web\Response.
Loading history...
Bug introduced by
The method redirect() does not exist on yii\console\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

225
        return Yii::$app->getResponse()->/** @scrutinizer ignore-call */ redirect(Url::to($url), $statusCode);
Loading history...
226
    }
227
228
    /**
229
     * Redirects the browser to the home page.
230
     *
231
     * You can use this method in an action by returning the [[Response]] directly:
232
     *
233
     * ```php
234
     * // stop executing this action and redirect to home page
235
     * return $this->goHome();
236
     * ```
237
     *
238
     * @return Response the current response object
239
     */
240
    public function goHome()
241
    {
242
        return Yii::$app->getResponse()->redirect(Yii::$app->getHomeUrl());
0 ignored issues
show
Bug Best Practice introduced by
The expression return Yii::app->getResp...Yii::app->getHomeUrl()) also could return the type yii\console\Response which is incompatible with the documented return type yii\web\Response.
Loading history...
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

242
        return Yii::$app->getResponse()->redirect(Yii::$app->/** @scrutinizer ignore-call */ getHomeUrl());
Loading history...
243
    }
244
245
    /**
246
     * Redirects the browser to the last visited page.
247
     *
248
     * You can use this method in an action by returning the [[Response]] directly:
249
     *
250
     * ```php
251
     * // stop executing this action and redirect to last visited page
252
     * return $this->goBack();
253
     * ```
254
     *
255
     * For this function to work you have to [[User::setReturnUrl()|set the return URL]] in appropriate places before.
256
     *
257
     * @param string|array $defaultUrl the default return URL in case it was not set previously.
258
     * If this is null and the return URL was not set previously, [[Application::homeUrl]] will be redirected to.
259
     * Please refer to [[User::setReturnUrl()]] on accepted format of the URL.
260
     * @return Response the current response object
261
     * @see User::getReturnUrl()
262
     */
263
    public function goBack($defaultUrl = null)
264
    {
265
        return Yii::$app->getResponse()->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

265
        return Yii::$app->getResponse()->redirect(Yii::$app->/** @scrutinizer ignore-call */ getUser()->getReturnUrl($defaultUrl));
Loading history...
Bug Best Practice introduced by
The expression return Yii::app->getResp...ReturnUrl($defaultUrl)) also could return the type yii\console\Response which is incompatible with the documented return type yii\web\Response.
Loading history...
266
    }
267
268
    /**
269
     * Refreshes the current page.
270
     * This method is a shortcut to [[Response::refresh()]].
271
     *
272
     * You can use it in an action by returning the [[Response]] directly:
273
     *
274
     * ```php
275
     * // stop executing this action and refresh the current page
276
     * return $this->refresh();
277
     * ```
278
     *
279
     * @param string $anchor the anchor that should be appended to the redirection URL.
280
     * Defaults to empty. Make sure the anchor starts with '#' if you want to specify it.
281
     * @return Response the response object itself
282
     */
283
    public function refresh($anchor = '')
284
    {
285
        return Yii::$app->getResponse()->redirect(Yii::$app->getRequest()->getUrl() . $anchor);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Yii::app->getResp...()->getUrl() . $anchor) also could return the type yii\console\Response which is incompatible with the documented return type yii\web\Response.
Loading history...
Bug introduced by
The method getUrl() does not exist on yii\console\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

285
        return Yii::$app->getResponse()->redirect(Yii::$app->getRequest()->/** @scrutinizer ignore-call */ getUrl() . $anchor);
Loading history...
286
    }
287
}
288