Passed
Push — master ( 76d1c8...bf40a8 )
by Babak
02:50
created

QueryHelper::getHierarchyFilterKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 14
c 1
b 0
f 1
nc 2
nop 1
dl 0
loc 20
rs 9.7998
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: alive
5
 * Date: 10/8/17
6
 * Time: 4:04 AM
7
 */
8
9
namespace Alive2212\LaravelQueryHelper;
10
11
use Illuminate\Database\Eloquent\Builder;
0 ignored issues
show
Bug introduced by
The type Illuminate\Database\Eloquent\Builder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Illuminate\Database\Eloquent\Model;
0 ignored issues
show
Bug introduced by
The type Illuminate\Database\Eloquent\Model was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
14
class QueryHelper
15
{
16
    /**
17
     * filter Delimiter
18
     * @var
19
     */
20
    protected $filterDelimiter = '.';
21
22
23
    /**
24
     * @var string
25
     */
26
    protected $queryFilterTitle = 'query_filters';
27
28
    /**
29
     * @param $query
30
     * @param $filters
31
     * @return mixed
32
     */
33
    public function orDeepFilter($query, $filters)
34
    {
35
        $result = $query;
36
        $keys = explode('.', $filters[0]['key']);
37
        if (collect($keys)->count() == 2) {
38
            $result = $result->orWhereHas($keys[0], function ($query) use ($filters, $keys) {
0 ignored issues
show
Unused Code introduced by
The import $keys is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
39
                foreach ($filters as $filter) {
40
                    $keys = explode('.', $filter['key']);
41
                    $query->where($keys[1], $filter['operator'], $filter['value']);
42
                }
43
            });
44
        }
45
        return $result;
46
    }
47
48
    /**
49
     * @param $query
50
     * @param $param
51
     * @return mixed
52
     */
53
    public function orderBy($query, $param)
54
    {
55
        $result = $query;
56
        if ($param->count()) {
57
            $query->orderBy($param[0], $param[1]);
58
        }
59
        return $result;
60
    }
61
62
    /**
63
     * @param $params
64
     * @param $field
65
     * @return array
66
     */
67
    public function getValueArray($params, $field)
68
    {
69
        $result = [];
70
        foreach ($params as $key => $item) {
71
            array_push($result, $item[$field]);
72
        }
73
        return $result;
74
    }
75
76
    /**
77
     * @param Builder $model
78
     * @param array $filters
79
     * @return Builder
80
     */
81
    public function smartDeepFilter(Builder $model, array $filters): Builder
82
    {
83
        $filters = $this->filterAdaptor($filters);
84
        $model = $this->addCondition($model, $filters);
85
        return $model;
86
    }
87
88
    /**
89
     * @param array $filters
90
     * @return array
91
     */
92
    public function filterAdaptor(array $filters): array
93
    {
94
        $adaptedFilters = [];
95
        foreach ($filters as $filter) {
96
            array_push($adaptedFilters, $this->filterWhereConditionAdaptor($filter));
97
        }
98
        return $adaptedFilters;
99
    }
100
101
    /**
102
     * @param array $filters
103
     * @return array
104
     */
105
    public function filterWhereConditionAdaptor(array $filters): array
106
    {
107
        $result = [];
108
        foreach ($filters as $filter) {
109
            $result = array_merge_recursive($result, $this->getHierarchyFilterKey($filter));
110
        }
111
        return $result;
112
    }
113
114
    public function getHierarchyFilterKey(array $filter): array
115
    {
116
        $filterKeyParams = $this->getFilterKey($filter);
117
        $firstFilterKey = $filterKeyParams[0];
118
        if (count($filterKeyParams) > 1) {
119
            unset($filterKeyParams[0]);
120
            $filter[0] = implode($this->filterDelimiter, $filterKeyParams);
121
            $result[$firstFilterKey] = $this->getHierarchyFilterKey($filter);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.
Loading history...
122
        } else {
123
            $firstFilterOperator = $this->getFilterOperator($filter);
124
            $firstFilterValue = $this->getFilterValue($filter);
125
            $result[$this->queryFilterTitle] = [
126
                [
127
                    $firstFilterKey,
128
                    $firstFilterOperator,
129
                    $firstFilterValue,
130
                ],
131
            ];
132
        }
133
        return $result;
134
    }
135
136
    /**
137
     * @param Builder $model
138
     * @param array $filters
139
     * @return Builder
140
     */
141
    public function addCondition(Builder $model, array $filters): Builder
142
    {
143
        $firstFilter = $filters[0];
144
        $modelQuery = $model->where(function ($query) use ($firstFilter) {
145
            $this->addWhereCondition($query, $firstFilter);
146
        });
147
        unset($filters[0]);
148
        foreach ($filters as $filter) {
149
            $modelQuery = $modelQuery->orWhere(function ($query) use ($filter) {
150
                $this->addWhereCondition($query, $filter);
151
            });
152
        }
153
        return $modelQuery;
154
    }
155
156
    /**
157
     * @param Builder $model
158
     * @param array $filters
159
     * @return Builder
160
     */
161
    public function addWhereCondition(Builder $model, array $filters): Builder
162
    {
163
        foreach ($filters as $filterKey => $filtersValues) {
164
            if ($filterKey == $this->queryFilterTitle) {
165
                $model = $model->where($filtersValues);
166
            } else {
167
                $model = $model->whereHas($filterKey, function (Builder $query) use ($model, $filtersValues) {
0 ignored issues
show
Unused Code introduced by
The import $model is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
168
                    $query = $this->addWhereCondition($query,$filtersValues);
0 ignored issues
show
Unused Code introduced by
The assignment to $query is dead and can be removed.
Loading history...
169
                });
170
            }
171
        }
172
        return $model;
173
    }
174
175
    /**
176
     * @return string
177
     */
178
    public function getFilterDelimiter():string
179
    {
180
        return $this->filterDelimiter;
181
    }
182
183
    /**
184
     * @param $filterDelimiter
185
     * @return QueryHelper
186
     */
187
    public function setFilterDelimiter($filterDelimiter):QueryHelper
188
    {
189
        $this->filterDelimiter = $filterDelimiter;
190
        return $this;
191
    }
192
193
    /**
194
     * @param array $filter
195
     * @return array
196
     */
197
    public function getFilterKey(array $filter): array
198
    {
199
        if (array_key_exists('key', $filter)) {
200
            $result = explode($this->filterDelimiter, $filter['key']);
201
        } else {
202
            $result = explode($this->filterDelimiter, $filter[0]);
203
        }
204
        return $result;
205
    }
206
207
    /**
208
     * @param array $filter
209
     * @return string
210
     */
211
    public function getFilterOperator(array $filter): string
212
    {
213
        return array_key_exists('operator', $filter) ? $filter['operator'] : $filter[1];
214
    }
215
216
    /**
217
     * @param array $filter
218
     * @return string
219
     */
220
    public function getFilterValue(array $filter): string
221
    {
222
        return array_key_exists('value', $filter) ? $filter['value'] : $filter[2];
223
    }
224
}