Issues (13)

src/EUpdateAllAction.php (4 issues)

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 string $filterAttribute = 'filter';
29
30
    /**
31
     * @var string
32
     */
33
    public string $extraFilter = 'extraFilter';
34
35
    /**
36
     * @var string
37
     */
38
    public string $updatedAttribute = 'updatedAttributes';
39
40
    /**
41
     * Add custom query condition
42
     * @see \Closure params
43
     *
44
     * @var null|array
45
     */
46
    public ?array $addQuery = null;
47
48
    /**
49
     * Column name
50
     * @see \Closure
51
     *
52
     * @var null|array
53
     */
54
    public ?array $filterUser = null;
55
56
    /**
57
     * @var array
58
     */
59
    private array $_updatedModels = [];
60
61
    /**
62
     * Get deleted models
63
     *
64
     * @return array
65
     */
66
    public function getUpdatedModels(): array
67
    {
68
        return $this->_updatedModels;
69
    }
70
71
    /**
72
     * @inheritdoc
73
     */
74
    protected function prepareDataProvider()
75
    {
76
        $filter            = Yii::$app->request->get($this->filterAttribute);
77
        $extraFilter       = Yii::$app->request->get($this->extraFilter);
78
        $queryParams       = Yii::$app->request->getQueryParams();
79
        $updatedAttributes = [];
80
81
        if (!empty($filter)) {
82
            $queryParams[$this->filterAttribute] = json_decode($filter, true);
0 ignored issues
show
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

82
            $queryParams[$this->filterAttribute] = json_decode(/** @scrutinizer ignore-type */ $filter, true);
Loading history...
83
        }
84
85
        if (!empty($extraFilter) && is_string($extraFilter)) {
86
            $extraFilter = json_decode($extraFilter, true);
87
        }
88
89
        if (!empty($queryParams[$this->updatedAttribute])) {
90
            $updatedAttributes = json_decode($queryParams[$this->updatedAttribute], true);
91
        }
92
93
        if (empty($updatedAttributes)) {
94
            throw new BadRequestHttpException("Param '{$this->updatedAttribute}' cannot be empty");
95
        }
96
97
        Yii::$app->request->setQueryParams($queryParams);
98
99
        $this->prepareDataProvider = function (EUpdateAllAction $action, $filter) use ($extraFilter) {
100
            /** @var ActiveDataProvider $dataProvider */
101
            $dataProvider = call_user_func([$action->dataFilter->searchModel, 'getDataProvider']);
102
            $dataProvider->query->andWhere($filter);
103
104
            if ($this->addQuery) {
105
                call_user_func($this->addQuery, $dataProvider->query, $extraFilter, $action->dataFilter, $dataProvider);
106
107
                if ($action->dataFilter->hasErrors()) {
0 ignored issues
show
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

107
                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...
108
                    return $action->dataFilter;
109
                }
110
            }
111
112
            if ($this->filterUser) {
113
                $filterUserColumn = call_user_func($this->filterUser);
114
115
                if ($filterUserColumn !== null) {
116
                    $dataProvider->query->andWhere([$filterUserColumn => Yii::$app->user->getId()]);
0 ignored issues
show
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

116
                    $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...
117
                }
118
            }
119
120
            return $dataProvider;
121
        };
122
123
        $dataProvider = parent::prepareDataProvider();
124
        $countUpdated = 0;
125
126
        if ($dataProvider instanceof ActiveDataProvider) {
0 ignored issues
show
$dataProvider is always a sub-type of yii\data\ActiveDataProvider.
Loading history...
127
            /** @var ActiveQuery $query */
128
            $query = $dataProvider->query;
129
            $query
130
                ->limit(-1)
131
                ->offset(-1)
132
                ->orderBy([]);
133
134
            foreach ($query->each() as $model) {
135
                /** @var $model ActiveRecord */
136
                $model->setAttributes($updatedAttributes);
137
138
                if ($model->save()) {
139
                    $this->_updatedModels[] = $model;
140
                    $countUpdated++;
141
                }
142
            }
143
        }
144
145
        Yii::$app->response->headers->set('X-Total-Updated', $countUpdated);
146
147
        return $dataProvider;
148
    }
149
}
150