Issues (13)

src/EDeleteAllAction.php (5 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\NotFoundHttpException;
16
17
/**
18
 * Class    EDeleteAllAction
19
 * @package MP\ExtendedApi
20
 * @author  Yarmaliuk Mikhail
21
 * @version 1.0
22
 */
23
class EDeleteAllAction extends IndexAction
24
{
25
    /**
26
     * @var string
27
     */
28
    public string $filterAttribute = 'filter';
29
30
    /**
31
     * Add custom query condition
32
     * @see \Closure params
33
     *
34
     * @var null|array
35
     */
36
    public ?array $addQuery = null;
37
38
    /**
39
     * Column name
40
     * @see \Closure
41
     *
42
     * @var null|array
43
     */
44
    public ?array $filterUser = null;
45
46
    /**
47
     * Delete all without condition
48
     *
49
     * @var bool
50
     */
51
    public bool $hardDelete = false;
52
53
    /**
54
     * @var array
55
     */
56
    private array $_deletedModels = [];
57
58
    /**
59
     * Get deleted models
60
     *
61
     * @return array
62
     */
63
    public function getDeletedModels(): array
64
    {
65
        return $this->_deletedModels;
66
    }
67
68
    /**
69
     * @inheritdoc
70
     */
71
    protected function prepareDataProvider()
72
    {
73
        $filter      = Yii::$app->request->get($this->filterAttribute);
74
        $queryParams = Yii::$app->request->getQueryParams();
75
76
        if (!empty($filter)) {
77
            $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

77
            $queryParams[$this->filterAttribute] = json_decode(/** @scrutinizer ignore-type */ $filter, true);
Loading history...
78
        }
79
80
        if (!$this->hardDelete && (empty($queryParams[$this->filterAttribute]) || empty(array_filter($queryParams[$this->filterAttribute])))) {
81
            throw new NotFoundHttpException("Param '{$this->filterAttribute}' cannot be empty");
82
        }
83
84
        Yii::$app->request->setQueryParams($queryParams);
85
86
        $this->prepareDataProvider = function (EDeleteAllAction $action, $filter) {
87
            /** @var ActiveDataProvider $dataProvider */
88
            $dataProvider = call_user_func([$action->dataFilter->searchModel, 'getDataProvider']);
89
            $dataProvider->query->andWhere($filter);
90
91
            if ($this->addQuery) {
92
                call_user_func($this->addQuery, $dataProvider->query, null, $action->dataFilter, $dataProvider);
93
            }
94
95
            if ($this->filterUser) {
96
                $filterUserColumn = call_user_func($this->filterUser);
97
98
                if ($filterUserColumn !== null) {
99
                    $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

99
                    $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...
100
                }
101
            }
102
103
            return $dataProvider;
104
        };
105
106
        if ($this->hardDelete) {
107
            $this->modelClass::deleteAll();
108
        } else {
109
            $dataProvider = parent::prepareDataProvider();
110
111
            if ($dataProvider instanceof ActiveDataProvider) {
0 ignored issues
show
$dataProvider is always a sub-type of yii\data\ActiveDataProvider.
Loading history...
112
                /** @var ActiveQuery $query */
113
                $query = $dataProvider->query;
114
                $query
115
                    ->limit(-1)
116
                    ->offset(-1)
117
                    ->orderBy([]);
118
119
                $countDeleted = 0;
120
121
                foreach ($query->each() as $model) {
122
                    /** @var $model ActiveRecord */
123
                    if ($model->delete()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $model->delete() of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
124
                        $this->_deletedModels[] = $model;
125
                        $countDeleted++;
126
                    }
127
                }
128
            }
129
        }
130
131
        Yii::$app->response->headers->set('X-Total-Deleted', $countDeleted);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $countDeleted does not seem to be defined for all execution paths leading up to this point.
Loading history...
132
133
        return;
134
    }
135
}
136