Passed
Push — master ( a46232...f763ca )
by Anton
01:03
created

IndexAction   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 118
rs 10
c 0
b 0
f 0
wmc 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getFilter() 0 20 5
A run() 0 7 2
A prepareDataProvider() 0 25 3
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 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(),
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

100
            '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...
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 = [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
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);
0 ignored issues
show
Bug introduced by
$this->dataFilter of type yii\data\DataFilter is incompatible with the type null|array expected by parameter $array2 of array_merge(). ( Ignorable by Annotation )

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

125
        $config = array_merge(['attributeMap' => $attributeMap], /** @scrutinizer ignore-type */ $this->dataFilter);
Loading history...
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
}