Completed
Push — json-response ( 29b22d )
by Carsten
15:03
created

Controller::asXml()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
crap 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\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
Documentation Bug introduced by
The method renderAjax does not exist on object<yii\base\View>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
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;
75 1
        $response->data = $data;
76 1
        return $response;
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;
102 1
        $response->data = $data;
103 1
        return $response;
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 24
    public function bindActionParams($action, $params)
118
    {
119 24
        if ($action instanceof InlineAction) {
120 24
            $method = new \ReflectionMethod($this, $action->actionMethod);
121 24
        } else {
122
            $method = new \ReflectionMethod($action, 'run');
123
        }
124
125 24
        $args = [];
126 24
        $missing = [];
127 24
        $actionParams = [];
128 24
        foreach ($method->getParameters() as $param) {
129 1
            $name = $param->getName();
130 1
            if (array_key_exists($name, $params)) {
131 1
                if ($param->isArray()) {
132
                    $args[] = $actionParams[$name] = (array) $params[$name];
133 1
                } elseif (!is_array($params[$name])) {
134 1
                    $args[] = $actionParams[$name] = $params[$name];
135 1
                } else {
136
                    throw new BadRequestHttpException(Yii::t('yii', 'Invalid data received for parameter "{param}".', [
137
                        'param' => $name,
138
                    ]));
139
                }
140 1
                unset($params[$name]);
141 1
            } elseif ($param->isDefaultValueAvailable()) {
142 1
                $args[] = $actionParams[$name] = $param->getDefaultValue();
143 1
            } else {
144
                $missing[] = $name;
145
            }
146 24
        }
147
148 24
        if (!empty($missing)) {
149
            throw new BadRequestHttpException(Yii::t('yii', 'Missing required parameters: {params}', [
150
                'params' => implode(', ', $missing),
151
            ]));
152
        }
153
154 24
        $this->actionParams = $actionParams;
155
156 24
        return $args;
157
    }
158
159
    /**
160
     * @inheritdoc
161
     */
162 23
    public function beforeAction($action)
163
    {
164 23
        if (parent::beforeAction($action)) {
165 23
            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !Yii::$app->getRequest()->validateCsrfToken()) {
166
                throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));
167
            }
168 23
            return true;
169
        }
170
        
171
        return false;
172
    }
173
174
    /**
175
     * Redirects the browser to the specified URL.
176
     * This method is a shortcut to [[Response::redirect()]].
177
     *
178
     * You can use it in an action by returning the [[Response]] directly:
179
     *
180
     * ```php
181
     * // stop executing this action and redirect to login page
182
     * return $this->redirect(['login']);
183
     * ```
184
     *
185
     * @param string|array $url the URL to be redirected to. This can be in one of the following formats:
186
     *
187
     * - a string representing a URL (e.g. "http://example.com")
188
     * - a string representing a URL alias (e.g. "@example.com")
189
     * - an array in the format of `[$route, ...name-value pairs...]` (e.g. `['site/index', 'ref' => 1]`)
190
     *   [[Url::to()]] will be used to convert the array into a URL.
191
     *
192
     * Any relative URL will be converted into an absolute one by prepending it with the host info
193
     * of the current request.
194
     *
195
     * @param int $statusCode the HTTP status code. Defaults to 302.
196
     * See <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>
197
     * for details about HTTP status code
198
     * @return Response the current response object
199
     */
200
    public function redirect($url, $statusCode = 302)
201
    {
202
        return Yii::$app->getResponse()->redirect(Url::to($url), $statusCode);
203
    }
204
205
    /**
206
     * Redirects the browser to the home page.
207
     *
208
     * You can use this method in an action by returning the [[Response]] directly:
209
     *
210
     * ```php
211
     * // stop executing this action and redirect to home page
212
     * return $this->goHome();
213
     * ```
214
     *
215
     * @return Response the current response object
216
     */
217
    public function goHome()
218
    {
219
        return Yii::$app->getResponse()->redirect(Yii::$app->getHomeUrl());
0 ignored issues
show
Bug introduced by
The method getHomeUrl does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
220
    }
221
222
    /**
223
     * Redirects the browser to the last visited page.
224
     *
225
     * You can use this method in an action by returning the [[Response]] directly:
226
     *
227
     * ```php
228
     * // stop executing this action and redirect to last visited page
229
     * return $this->goBack();
230
     * ```
231
     *
232
     * For this function to work you have to [[User::setReturnUrl()|set the return URL]] in appropriate places before.
233
     *
234
     * @param string|array $defaultUrl the default return URL in case it was not set previously.
235
     * If this is null and the return URL was not set previously, [[Application::homeUrl]] will be redirected to.
236
     * Please refer to [[User::setReturnUrl()]] on accepted format of the URL.
237
     * @return Response the current response object
238
     * @see User::getReturnUrl()
239
     */
240
    public function goBack($defaultUrl = null)
241
    {
242
        return Yii::$app->getResponse()->redirect(Yii::$app->getUser()->getReturnUrl($defaultUrl));
0 ignored issues
show
Bug introduced by
The method getUser does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
243
    }
244
245
    /**
246
     * Refreshes the current page.
247
     * This method is a shortcut to [[Response::refresh()]].
248
     *
249
     * You can use it in an action by returning the [[Response]] directly:
250
     *
251
     * ```php
252
     * // stop executing this action and refresh the current page
253
     * return $this->refresh();
254
     * ```
255
     *
256
     * @param string $anchor the anchor that should be appended to the redirection URL.
257
     * Defaults to empty. Make sure the anchor starts with '#' if you want to specify it.
258
     * @return Response the response object itself
259
     */
260
    public function refresh($anchor = '')
261
    {
262
        return Yii::$app->getResponse()->redirect(Yii::$app->getRequest()->getUrl() . $anchor);
263
    }
264
}
265