1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @author Anton Tuyakhov <[email protected]> |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
namespace tuyakhov\jsonapi\actions; |
7
|
|
|
|
8
|
|
|
|
9
|
|
|
use tuyakhov\jsonapi\Inflector; |
10
|
|
|
use tuyakhov\jsonapi\Pagination; |
11
|
|
|
use yii\data\ActiveDataProvider; |
12
|
|
|
use yii\data\DataFilter; |
13
|
|
|
use Yii; |
14
|
|
|
|
15
|
|
|
class IndexAction extends Action |
16
|
|
|
{ |
17
|
|
|
/** |
18
|
|
|
* @var callable a PHP callable that will be called to prepare a data provider that |
19
|
|
|
* should return a collection of the models. If not set, [[prepareDataProvider()]] will be used instead. |
20
|
|
|
* The signature of the callable should be: |
21
|
|
|
* |
22
|
|
|
* ```php |
23
|
|
|
* function (IndexAction $action) { |
24
|
|
|
* // $action is the action object currently running |
25
|
|
|
* } |
26
|
|
|
* ``` |
27
|
|
|
* |
28
|
|
|
* The callable should return an instance of [[ActiveDataProvider]]. |
29
|
|
|
* |
30
|
|
|
* If [[dataFilter]] is set the result of [[DataFilter::build()]] will be passed to the callable as a second parameter. |
31
|
|
|
* In this case the signature of the callable should be the following: |
32
|
|
|
* |
33
|
|
|
* ```php |
34
|
|
|
* function (IndexAction $action, mixed $filter) { |
35
|
|
|
* // $action is the action object currently running |
36
|
|
|
* // $filter the built filter condition |
37
|
|
|
* } |
38
|
|
|
* ``` |
39
|
|
|
*/ |
40
|
|
|
public $prepareDataProvider; |
41
|
|
|
/** |
42
|
|
|
* @var DataFilter|null data filter to be used for the search filter composition. |
43
|
|
|
* You must setup this field explicitly in order to enable filter processing. |
44
|
|
|
* For example: |
45
|
|
|
* |
46
|
|
|
* ```php |
47
|
|
|
* [ |
48
|
|
|
* 'class' => 'yii\data\ActiveDataFilter', |
49
|
|
|
* 'searchModel' => function () { |
50
|
|
|
* return (new \yii\base\DynamicModel(['id' => null, 'name' => null, 'price' => null])) |
51
|
|
|
* ->addRule('id', 'integer') |
52
|
|
|
* ->addRule('name', 'trim') |
53
|
|
|
* ->addRule('name', 'string') |
54
|
|
|
* ->addRule('price', 'number'); |
55
|
|
|
* }, |
56
|
|
|
* ] |
57
|
|
|
* ``` |
58
|
|
|
* |
59
|
|
|
* @see DataFilter |
60
|
|
|
* |
61
|
|
|
* @since 2.0.13 |
62
|
|
|
*/ |
63
|
|
|
public $dataFilter; |
64
|
|
|
|
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* @return ActiveDataProvider |
68
|
|
|
* @throws \yii\base\InvalidConfigException |
69
|
|
|
*/ |
70
|
|
|
public function run() |
71
|
|
|
{ |
72
|
|
|
if ($this->checkAccess) { |
73
|
|
|
call_user_func($this->checkAccess, $this->id); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
return $this->prepareDataProvider(); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Prepares the data provider that should return the requested collection of the models. |
81
|
|
|
* @return mixed|null|object|DataFilter|ActiveDataProvider |
82
|
|
|
* @throws \yii\base\InvalidConfigException |
83
|
|
|
*/ |
84
|
|
|
protected function prepareDataProvider() |
85
|
|
|
{ |
86
|
|
|
$filter = $this->getFilter(); |
87
|
|
|
|
88
|
|
|
if ($this->prepareDataProvider !== null) { |
89
|
|
|
return call_user_func($this->prepareDataProvider, $this, $filter); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/* @var $modelClass \yii\db\BaseActiveRecord */ |
93
|
|
|
$modelClass = $this->modelClass; |
94
|
|
|
|
95
|
|
|
$query = $modelClass::find(); |
96
|
|
|
if (!empty($filter)) { |
97
|
|
|
$query->andWhere($filter); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
return Yii::createObject([ |
101
|
|
|
'class' => ActiveDataProvider::className(), |
|
|
|
|
102
|
|
|
'query' => $query, |
103
|
|
|
'pagination' => [ |
104
|
|
|
'class' => Pagination::className(), |
|
|
|
|
105
|
|
|
], |
106
|
|
|
'sort' => [ |
107
|
|
|
'enableMultiSort' => true |
108
|
|
|
] |
109
|
|
|
]); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
protected function getFilter() |
113
|
|
|
{ |
114
|
|
|
if ($this->dataFilter === null) { |
115
|
|
|
return null; |
116
|
|
|
} |
117
|
|
|
$requestParams = Yii::$app->getRequest()->getQueryParam('filter', []); |
118
|
|
|
$attributeMap = []; |
119
|
|
|
foreach ($requestParams as $attribute => $value) { |
120
|
|
|
$attributeMap[$attribute] = Inflector::camel2id(Inflector::variablize($attribute), '_'); |
121
|
|
|
if (is_string($value) && strpos($value, ',') !== false) { |
122
|
|
|
$requestParams[$attribute] = ['in' => explode(',', $value)]; |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
$config = array_merge(['attributeMap' => $attributeMap], $this->dataFilter); |
|
|
|
|
126
|
|
|
/** @var DataFilter $dataFilter */ |
127
|
|
|
$dataFilter = Yii::createObject($config); |
128
|
|
|
if ($dataFilter->load(['filter' => $requestParams])) { |
129
|
|
|
return $dataFilter->build(); |
130
|
|
|
} |
131
|
|
|
return null; |
132
|
|
|
} |
133
|
|
|
} |
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.