Passed
Push — master ( 627d65...e69171 )
by Alexander
23:08
created

IndexAction::run()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 4.5185

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
ccs 1
cts 7
cp 0.1429
crap 4.5185
rs 10
c 0
b 0
f 0
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\rest;
9
10
use Yii;
11
use yii\data\ActiveDataProvider;
12
use yii\data\DataFilter;
13
use yii\data\Pagination;
14
use yii\data\Sort;
15
use yii\helpers\ArrayHelper;
16
17
/**
18
 * IndexAction implements the API endpoint for listing multiple models.
19
 *
20
 * For more details and usage information on IndexAction, see the [guide article on rest controllers](guide:rest-controllers).
21
 *
22
 * @author Qiang Xue <[email protected]>
23
 * @since 2.0
24
 */
25
class IndexAction extends Action
26
{
27
    /**
28
     * @var callable a PHP callable that will be called to prepare a data provider that
29
     * should return a collection of the models. If not set, [[prepareDataProvider()]] will be used instead.
30
     * The signature of the callable should be:
31
     *
32
     * ```php
33
     * function (IndexAction $action) {
34
     *     // $action is the action object currently running
35
     * }
36
     * ```
37
     *
38
     * The callable should return an instance of [[ActiveDataProvider]].
39
     *
40
     * If [[dataFilter]] is set the result of [[DataFilter::build()]] will be passed to the callable as a second parameter.
41
     * In this case the signature of the callable should be the following:
42
     *
43
     * ```php
44
     * function (IndexAction $action, mixed $filter) {
45
     *     // $action is the action object currently running
46
     *     // $filter the built filter condition
47
     * }
48
     * ```
49
     */
50
    public $prepareDataProvider;
51
    /**
52
     * @var callable a PHP callable that will be called to prepare query in prepareDataProvider.
53
     * Should return $query.
54
     * For example:
55
     *
56
     * ```php
57
     * function ($query, $requestParams) {
58
     *     $query->andFilterWhere(['id' => 1]);
59
     *     ...
60
     *     return $query;
61
     * }
62
     * ```
63
     *
64
     * @since 2.0.42
65
     */
66
    public $prepareSearchQuery;
67
    /**
68
     * @var DataFilter|null data filter to be used for the search filter composition.
69
     * You must setup this field explicitly in order to enable filter processing.
70
     * For example:
71
     *
72
     * ```php
73
     * [
74
     *     'class' => 'yii\data\ActiveDataFilter',
75
     *     'searchModel' => function () {
76
     *         return (new \yii\base\DynamicModel(['id' => null, 'name' => null, 'price' => null]))
77
     *             ->addRule('id', 'integer')
78
     *             ->addRule('name', 'trim')
79
     *             ->addRule('name', 'string')
80
     *             ->addRule('price', 'number');
81
     *     },
82
     * ]
83
     * ```
84
     *
85
     * @see DataFilter
86
     *
87
     * @since 2.0.13
88
     */
89
    public $dataFilter;
90
91
92 1
    /**
93
     * @var array|Pagination|false The pagination to be used by [[prepareDataProvider()]].
94 1
     * If this is `false`, it means pagination is disabled.
95
     * Note: if a Pagination object is passed, it's `params` will be set to the request parameters.
96
     * @see Pagination
97
     * @since 2.0.45
98 1
     */
99
    public $pagination = [];
100
101
    /**
102
     * @var array|Sort|false The sorting to be used by [[prepareDataProvider()]].
103
     * If this is `false`, it means sorting is disabled.
104
     * Note: if a Sort object is passed, it's `params` will be set to the request parameters.
105 1
     * @see Sort
106
     * @since 2.0.45
107 1
     */
108 1
    public $sort = [];
109 1
110
    /**
111
     * @return ActiveDataProvider
112 1
     */
113 1
    public function run()
114
    {
115
        if ($this->checkAccess) {
116
            call_user_func($this->checkAccess, $this->id);
117
        }
118
119
        return $this->prepareDataProvider();
120
    }
121
122
    /**
123 1
     * Prepares the data provider that should return the requested collection of the models.
124
     * @return ActiveDataProvider
125
     */
126
    protected function prepareDataProvider()
127
    {
128 1
        $requestParams = Yii::$app->getRequest()->getBodyParams();
0 ignored issues
show
Bug introduced by
The method getBodyParams() 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

128
        $requestParams = Yii::$app->getRequest()->/** @scrutinizer ignore-call */ getBodyParams();
Loading history...
129
        if (empty($requestParams)) {
130 1
            $requestParams = Yii::$app->getRequest()->getQueryParams();
0 ignored issues
show
Bug introduced by
The method getQueryParams() 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

130
            $requestParams = Yii::$app->getRequest()->/** @scrutinizer ignore-call */ getQueryParams();
Loading history...
131 1
        }
132
133
        $filter = null;
134 1
        if ($this->dataFilter !== null) {
135 1
            $this->dataFilter = Yii::createObject($this->dataFilter);
0 ignored issues
show
Bug introduced by
$this->dataFilter of type yii\data\DataFilter is incompatible with the type array|callable|string expected by parameter $type of yii\BaseYii::createObject(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

135
            $this->dataFilter = Yii::createObject(/** @scrutinizer ignore-type */ $this->dataFilter);
Loading history...
136
            if ($this->dataFilter->load($requestParams)) {
137
                $filter = $this->dataFilter->build();
138 1
                if ($filter === false) {
139 1
                    return $this->dataFilter;
140 1
                }
141
            }
142 1
        }
143
144
        if ($this->prepareDataProvider !== null) {
145 1
            return call_user_func($this->prepareDataProvider, $this, $filter);
146
        }
147
148
        /* @var $modelClass \yii\db\BaseActiveRecord */
149
        $modelClass = $this->modelClass;
150
151
        $query = $modelClass::find();
152
        if (!empty($filter)) {
153
            $query->andWhere($filter);
154
        }
155
        if (is_callable($this->prepareSearchQuery)) {
156
            $query = call_user_func($this->prepareSearchQuery, $query, $requestParams);
157
        }
158
159
        if (is_array($this->pagination)) {
160
            $pagination = ArrayHelper::merge(
161
                [
162
                    'params' => $requestParams,
163
                ],
164
                $this->pagination
165
            );
166
        } else {
167
            $pagination = $this->pagination;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->pagination can also be of type boolean. However, the property $pagination is declared as type array|false|yii\data\Pagination. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
168
            if ($this->pagination instanceof Pagination) {
169
                $pagination->params = $requestParams;
0 ignored issues
show
Documentation Bug introduced by
It seems like $requestParams can also be of type object. However, the property $params is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
170
            }
171
        }
172
173
        if (is_array($this->sort)) {
174
            $sort = ArrayHelper::merge(
175
                [
176
                    'params' => $requestParams,
177
                ],
178
                $this->sort
179
            );
180
        } else {
181
            $sort = $this->sort;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->sort can also be of type boolean. However, the property $sort is declared as type array|false|yii\data\Sort. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
182
            if ($this->sort instanceof Sort) {
183
                $sort->params = $requestParams;
0 ignored issues
show
Documentation Bug introduced by
It seems like $requestParams can also be of type object. However, the property $params is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
184
            }
185
        }
186
187
        return Yii::createObject([
188
            'class' => ActiveDataProvider::className(),
0 ignored issues
show
Deprecated Code introduced by
The function yii\base\BaseObject::className() has been deprecated: since 2.0.14. On PHP >=5.5, use `::class` instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

188
            'class' => /** @scrutinizer ignore-deprecated */ ActiveDataProvider::className(),

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
189
            'query' => $query,
190
            'pagination' => $pagination,
191
            'sort' => $sort,
192
        ]);
193
    }
194
}
195