Passed
Push — master ( 370b21...400b6f )
by Matthew
02:13
created

EUpdateAllAction::prepareDataProvider()   C

Complexity

Conditions 13
Paths 32

Size

Total Lines 72
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 13
eloc 39
c 2
b 0
f 0
nc 32
nop 0
dl 0
loc 72
rs 6.6166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * Date: 2017-12-07
5
 * Time: 03:12
6
 */
7
8
namespace MP\ExtendedApi;
9
10
use Yii;
11
use yii\data\ActiveDataProvider;
12
use yii\db\ActiveQuery;
13
use yii\db\ActiveRecord;
14
use yii\rest\IndexAction;
15
use yii\web\BadRequestHttpException;
16
17
/**
18
 * Class    EUpdateAllAction
19
 * @package MP\ExtendedApi
20
 * @author  Yarmaliuk Mikhail
21
 * @version 1.0
22
 */
23
class EUpdateAllAction extends IndexAction
24
{
25
    /**
26
     * @var string
27
     */
28
    public $filterAttribute = 'filter';
29
30
    /**
31
     * @var string
32
     */
33
    public $extraFilter = 'extraFilter';
34
35
    /**
36
     * @var string
37
     */
38
    public $updatedAttribute = 'updatedAttributes';
39
40
    /**
41
     * Add custom query condition
42
     *
43
     * @var null|\Closure
44
     */
45
    public $addQuery = null;
46
47
    /**
48
     * Column name
49
     *
50
     * @var null|string
51
     */
52
    public $filterUser = null;
53
54
    /**
55
     * @var array
56
     */
57
    private $_updatedModels = [];
58
59
    /**
60
     * Get deleted models
61
     *
62
     * @return array
63
     */
64
    public function getUpdatedModels(): array
65
    {
66
        return $this->_updatedModels;
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    protected function prepareDataProvider()
73
    {
74
        $filter            = Yii::$app->request->get($this->filterAttribute);
75
        $extraFilter       = Yii::$app->request->get($this->extraFilter);
76
        $queryParams       = Yii::$app->request->getQueryParams();
77
        $updatedAttributes = [];
78
79
        if (!empty($filter)) {
80
            $queryParams[$this->filterAttribute] = json_decode($filter, true);
0 ignored issues
show
Bug introduced by
It seems like $filter can also be of type array; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

80
            $queryParams[$this->filterAttribute] = json_decode(/** @scrutinizer ignore-type */ $filter, true);
Loading history...
81
        }
82
83
        if (!empty($extraFilter) && is_string($extraFilter)) {
84
            $extraFilter = json_decode($extraFilter, true);
85
        }
86
87
        if (!empty($queryParams[$this->updatedAttribute])) {
88
            $updatedAttributes = json_decode($queryParams[$this->updatedAttribute], true);
89
        }
90
91
        if (empty($updatedAttributes)) {
92
            throw new BadRequestHttpException("Param '{$this->updatedAttribute}' cannot be empty");
93
        }
94
95
        Yii::$app->request->setQueryParams($queryParams);
96
97
        $this->prepareDataProvider = function (EIndexAction $action, $filter) use ($extraFilter) {
98
            /** @var ActiveDataProvider $dataProvider */
99
            $dataProvider = call_user_func([$action->dataFilter->searchModel, 'getDataProvider']);
100
            $dataProvider->query->andWhere($filter);
101
102
            if ($this->addQuery) {
103
                call_user_func($this->addQuery, $dataProvider->query, $extraFilter, $action->dataFilter);
104
105
                if ($action->dataFilter->hasErrors()) {
0 ignored issues
show
Bug introduced by
The method hasErrors() does not exist on null. ( Ignorable by Annotation )

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

105
                if ($action->dataFilter->/** @scrutinizer ignore-call */ hasErrors()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
106
                    return $action->dataFilter;
107
                }
108
            }
109
110
            if ($this->filterUser) {
111
                $filterUserColumn = is_callable($this->filterUser) ? call_user_func($this->filterUser) : $this->filterUser;
112
113
                if ($filterUserColumn !== null) {
114
                    $dataProvider->query->andWhere([$filterUserColumn => Yii::$app->user->getId()]);
0 ignored issues
show
Bug introduced by
The method getId() does not exist on null. ( Ignorable by Annotation )

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

114
                    $dataProvider->query->andWhere([$filterUserColumn => Yii::$app->user->/** @scrutinizer ignore-call */ getId()]);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
115
                }
116
            }
117
118
            return $dataProvider;
119
        };
120
121
        $dataProvider = parent::prepareDataProvider();
122
        /** @var ActiveQuery $query */
123
        $query = $dataProvider->query;
124
        $query
125
            ->limit(-1)
126
            ->offset(-1)
127
            ->orderBy([]);
128
129
        $countUpdated = 0;
130
131
        foreach ($query->each() as $model) {
132
            /** @var $model ActiveRecord */
133
            $model->setAttributes($updatedAttributes);
134
135
            if ($model->save()) {
136
                $this->_updatedModels[] = $model;
137
                $countUpdated++;
138
            }
139
        }
140
141
        Yii::$app->response->headers->set('X-Total-Updated', $countUpdated);
142
143
        return;
144
    }
145
}
146