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