1 | <?php |
||||
2 | /** |
||||
3 | * @link https://www.yiiframework.com/ |
||||
4 | * @copyright Copyright (c) 2008 Yii Software LLC |
||||
5 | * @license https://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|null 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 set up 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 | * @var array|Pagination|false The pagination to be used by [[prepareDataProvider()]]. |
||||
92 | * If this is `false`, it means pagination is disabled. |
||||
93 | * Note: if a Pagination object is passed, it's `params` will be set to the request parameters. |
||||
94 | * @see Pagination |
||||
95 | * @since 2.0.45 |
||||
96 | */ |
||||
97 | public $pagination = []; |
||||
98 | /** |
||||
99 | * @var array|Sort|false The sorting to be used by [[prepareDataProvider()]]. |
||||
100 | * If this is `false`, it means sorting is disabled. |
||||
101 | * Note: if a Sort object is passed, it's `params` will be set to the request parameters. |
||||
102 | * @see Sort |
||||
103 | * @since 2.0.45 |
||||
104 | */ |
||||
105 | public $sort = []; |
||||
106 | |||||
107 | |||||
108 | /** |
||||
109 | * @return ActiveDataProvider |
||||
110 | */ |
||||
111 | 6 | public function run() |
|||
112 | { |
||||
113 | 6 | if ($this->checkAccess) { |
|||
114 | call_user_func($this->checkAccess, $this->id); |
||||
115 | } |
||||
116 | |||||
117 | 6 | return $this->prepareDataProvider(); |
|||
118 | } |
||||
119 | |||||
120 | /** |
||||
121 | * Prepares the data provider that should return the requested collection of the models. |
||||
122 | * @return ActiveDataProvider |
||||
123 | */ |
||||
124 | 6 | protected function prepareDataProvider() |
|||
125 | { |
||||
126 | 6 | $requestParams = Yii::$app->getRequest()->getBodyParams(); |
|||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
127 | 6 | if (empty($requestParams)) { |
|||
128 | 1 | $requestParams = Yii::$app->getRequest()->getQueryParams(); |
|||
0 ignored issues
–
show
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
![]() |
|||||
129 | } |
||||
130 | |||||
131 | 6 | $filter = null; |
|||
132 | 6 | if ($this->dataFilter !== null) { |
|||
133 | $this->dataFilter = Yii::createObject($this->dataFilter); |
||||
0 ignored issues
–
show
$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
![]() |
|||||
134 | if ($this->dataFilter->load($requestParams)) { |
||||
135 | $filter = $this->dataFilter->build(); |
||||
136 | if ($filter === false) { |
||||
137 | return $this->dataFilter; |
||||
138 | } |
||||
139 | } |
||||
140 | } |
||||
141 | |||||
142 | 6 | if ($this->prepareDataProvider !== null) { |
|||
143 | return call_user_func($this->prepareDataProvider, $this, $filter); |
||||
144 | } |
||||
145 | |||||
146 | /** @var \yii\db\BaseActiveRecord $modelClass */ |
||||
147 | 6 | $modelClass = $this->modelClass; |
|||
148 | |||||
149 | 6 | $query = $modelClass::find(); |
|||
150 | 6 | if (!empty($filter)) { |
|||
151 | $query->andWhere($filter); |
||||
152 | } |
||||
153 | 6 | if (is_callable($this->prepareSearchQuery)) { |
|||
154 | 1 | $query = call_user_func($this->prepareSearchQuery, $query, $requestParams); |
|||
155 | } |
||||
156 | |||||
157 | 6 | if (is_array($this->pagination)) { |
|||
158 | 4 | $pagination = ArrayHelper::merge( |
|||
159 | 4 | [ |
|||
160 | 4 | 'params' => $requestParams, |
|||
161 | 4 | ], |
|||
162 | 4 | $this->pagination |
|||
163 | 4 | ); |
|||
164 | } else { |
||||
165 | 2 | $pagination = $this->pagination; |
|||
0 ignored issues
–
show
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 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;
}
![]() |
|||||
166 | 2 | if ($this->pagination instanceof Pagination) { |
|||
167 | 1 | $pagination->params = $requestParams; |
|||
0 ignored issues
–
show
It seems like
$requestParams can also be of type object . However, the property $params is declared as type array|null . 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 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;
}
![]() |
|||||
168 | } |
||||
169 | } |
||||
170 | |||||
171 | 6 | if (is_array($this->sort)) { |
|||
172 | 4 | $sort = ArrayHelper::merge( |
|||
173 | 4 | [ |
|||
174 | 4 | 'params' => $requestParams, |
|||
175 | 4 | ], |
|||
176 | 4 | $this->sort |
|||
177 | 4 | ); |
|||
178 | } else { |
||||
179 | 2 | $sort = $this->sort; |
|||
0 ignored issues
–
show
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 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;
}
![]() |
|||||
180 | 2 | if ($this->sort instanceof Sort) { |
|||
181 | 1 | $sort->params = $requestParams; |
|||
0 ignored issues
–
show
It seems like
$requestParams can also be of type object . However, the property $params is declared as type array|null . 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 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;
}
![]() |
|||||
182 | } |
||||
183 | } |
||||
184 | |||||
185 | 6 | return Yii::createObject([ |
|||
186 | 6 | 'class' => ActiveDataProvider::class, |
|||
187 | 6 | 'query' => $query, |
|||
188 | 6 | 'pagination' => $pagination, |
|||
189 | 6 | 'sort' => $sort, |
|||
190 | 6 | ]); |
|||
191 | } |
||||
192 | } |
||||
193 |