Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
81.25% covered (success)
81.25%
13 / 16
CRAP
76.00% covered (success)
76.00%
76 / 100
TraitFilterModel
0.00% covered (danger)
0.00%
0 / 1
81.25% covered (success)
81.25%
13 / 16
101.91
76.00% covered (success)
76.00%
76 / 100
 selectAll
0.00% covered (danger)
0.00%
0 / 1
90
0.00% covered (danger)
0.00%
0 / 18
 selectPaginate
0.00% covered (danger)
0.00%
0 / 1
10.74
72.22% covered (success)
72.22%
13 / 18
 applyFilter
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
5 / 5
 applyFields
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 applyOrderBy
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 applyLimit
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 applyConditions
100.00% covered (success)
100.00%
1 / 1
10
100.00% covered (success)
100.00%
18 / 18
 whereFiltered
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
4 / 4
 whereNullFiltered
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
4 / 4
 whereNotNullFiltered
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
4 / 4
 whereInFiltered
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
4 / 4
 whereNotInFiltered
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
4 / 4
 hasAggregate
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 applyAggregate
0.00% covered (danger)
0.00%
0 / 1
3.07
80.00% covered (success)
80.00%
4 / 5
 formatAggregateResponse
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 addPotentialFiltersErrors
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
1<?php
2
3namespace Qmp\Laravel\ApiFilterRequest\Traits;
4
5use Carbon\Carbon;
6use Illuminate\Support\Facades\Log;
7use Qmp\Laravel\ApiFilterRequest\Filters;
8use Qmp\Laravel\ApiFilterRequest\Filters\Fields;
9use Qmp\Laravel\ApiFilterRequest\Filters\Limit;
10use Qmp\Laravel\ApiFilterRequest\Filters\OrderBy;
11
12trait TraitFilterModel
13{
14    protected $queryFiltered;
15
16    protected $filterErrors = [];
17
18    /**
19     * @param null|Filter $filters
20     * @return null
21     */
22    public static function selectAll($filters = null)
23    {
24        $model = resolve(get_called_class());
25
26        $model->queryFiltered = $model->newQuery();
27
28        $result = null;
29        if ($filters instanceof Filters) {
30            if (property_exists($model, 'carbonDates')) {
31                $conditions = $filters->conditions->get();
32                foreach($conditions as &$condition) {
33                    if (isset($condition[0]) && in_array($condition[0], $model->carbonDates)) {
34                        $condition[count($condition) - 1] = new Carbon($condition[count($condition) - 1]);
35                    }
36                }
37                $filters->conditions->set($conditions);
38            }            
39
40            $model->applyFilter($filters);
41            if ($model->hasAggregate($filters->aggregate)) {
42                $result = $model->applyAggregate($filters->aggregate);
43            }
44        }
45
46        if (!$result) {
47            $result = $model->queryFiltered->get()->toArray();
48        }
49
50        if ($filters instanceof Filters) {
51            $model->addPotentialFiltersErrors($filters, $result);
52        }
53
54        return $result;
55    }
56
57    /**
58     * @param null|Filter $filters
59     * @return null
60     */
61    public static function selectPaginate($filters = null)
62    {
63        $model = resolve(get_called_class());
64
65        $model->queryFiltered = $model->newQuery();
66
67        $result = null;
68        if ($filters instanceof Filters) {
69            if (property_exists($model, 'carbonDates')) {
70                $conditions = $filters->conditions->get();
71                foreach($conditions as &$condition) {
72                    if (isset($condition[0]) && in_array($condition[0], $model->carbonDates)) {
73                        $condition[count($condition) - 1] = new Carbon($condition[count($condition) - 1]);
74                    }
75                }
76                $filters->conditions->set($conditions);
77            }            
78
79            $model->applyFilter($filters);
80            if ($model->hasAggregate($filters->aggregate)) {
81                $result = $model->applyAggregate($filters->aggregate);
82            }
83        }
84
85        if (!$result) {
86            $result = $model->queryFiltered->simplePaginate()->toArray();
87        }
88
89        if ($filters instanceof Filters) {
90            $model->addPotentialFiltersErrors($filters, $result);
91        }
92
93        return $result;
94    }
95
96    /**
97     * @param Filters $filters
98     * @return $this
99     */
100    protected function applyFilter(Filters $filters)
101    {
102        $this->applyFields($filters->fields)
103            ->applyOrderBy($filters->orderBy)
104            ->applyConditions($filters->conditions)
105            ->applyLimit($filters->limit);
106
107        return $this;
108    }
109
110    /**
111     * @param Fields $fields
112     * @return $this
113     */
114    protected function applyFields(Fields $fields)
115    {
116        if (!empty(($fields->get()))) {
117            $this->queryFiltered->select($fields->get());
118        }
119
120        return $this;
121    }
122
123    /**
124     * @param OrderBy $orderBy
125     * @return $this
126     */
127    protected function applyOrderBy(OrderBy $orderBy)
128    {
129        foreach ($orderBy->get() as $key => $orderBy) {
130            $this->queryFiltered->orderBy($key, $orderBy);
131        }
132
133        return $this;
134    }
135
136    protected function applyLimit(Limit $limit)
137    {
138        $limitValue = $limit->get();
139        if ($limitValue !== null) {
140            $this->queryFiltered->skip(0)->take($limitValue);
141        }
142        
143        return $this;
144    }
145
146    /**
147     * @param Filters\Conditions $conditions
148     * @return $this
149     */
150    protected function applyConditions(Filters\Conditions $conditions)
151    {
152        foreach ($conditions->get() as $condition) {
153            switch ($condition[1]) {
154                case Filters\Conditions::BEGIN_BY:
155                    $this->whereFiltered([$condition[0], 'like', $condition[2] . '%']);
156                    break;
157                case Filters\Conditions::END_BY:
158                    $this->whereFiltered([$condition[0], 'like', '%' . $condition[2]]);
159                    break;
160                case Filters\Conditions::CONTAIN:
161                    $this->whereFiltered([$condition[0], 'like', '%' . $condition[2] . '%']);
162                    break;
163                case Filters\Conditions::IS_NULL:
164                    $this->whereNullFiltered($condition);
165                    break;
166                case Filters\Conditions::NOT_NULL:
167                    $this->whereNotNullFiltered($condition);
168                    break;
169                case Filters\Conditions::IN:
170                    $this->whereInFiltered($condition);
171                    break;
172                case Filters\Conditions::NOT_IN:
173                    $this->whereNotInFiltered($condition);
174                    break;
175                default:
176                    $this->whereFiltered($condition);
177            }
178        }
179
180        return $this;
181    }
182
183    /**
184     * @param array $condition
185     */
186    protected function whereFiltered(array $condition)
187    {
188        if (!empty($condition[3]) && strtolower($condition[3]) === Filters\Conditions::OR_REQUEST) {
189            $this->queryFiltered->orWhere($condition[0], $condition[1], $condition[2]);
190        } else {
191            $this->queryFiltered->where($condition[0], $condition[1], $condition[2]);
192        }
193    }
194
195    /**
196     * @param array $condition
197     */
198    protected function whereNullFiltered(array $condition)
199    {
200        if (!empty($condition[3]) && strtolower($condition[3]) === Filters\Conditions::OR_REQUEST) {
201            $this->queryFiltered->orWhereNull($condition[0]);
202        } else {
203            $this->queryFiltered->whereNull($condition[0]);
204        }
205    }
206
207    /**
208     * @param array $condition
209     */
210    protected function whereNotNullFiltered(array $condition)
211    {
212        if (!empty($condition[3]) && strtolower($condition[3]) === Filters\Conditions::OR_REQUEST) {
213            $this->queryFiltered->orWhereNotNull($condition[0]);
214        } else {
215            $this->queryFiltered->whereNotNull($condition[0]);
216        }
217    }
218
219    /**
220     * @param array $condition
221     */
222    protected function whereInFiltered(array $condition)
223    {
224        if (!empty($condition[3]) && strtolower($condition[3]) === Filters\Conditions::OR_REQUEST) {
225            $this->queryFiltered->orWhereIn($condition[0], $condition[2]);
226        } else {
227            $this->queryFiltered->whereIn($condition[0], $condition[2]);
228        }
229    }
230
231    /**
232     * @param array $condition
233     */
234    protected function whereNotInFiltered(array $condition)
235    {
236        if (!empty($condition[3]) && strtolower($condition[3]) === Filters\Conditions::OR_REQUEST) {
237            $this->queryFiltered->orWhereNotIn($condition[0], $condition[2]);
238        } else {
239            $this->queryFiltered->whereNotIn($condition[0], $condition[2]);
240        }
241    }
242
243    /**
244     * @param Filters\Aggregate $aggregate
245     * @return bool
246     */
247    protected function hasAggregate(Filters\Aggregate $aggregate)
248    {
249        return !empty(($aggregate->get()));
250    }
251
252    /**
253     * @param Filters\Aggregate $aggregate
254     * @return array|null
255     */
256    protected function applyAggregate(Filters\Aggregate $aggregate)
257    {
258        foreach ($aggregate->get() as $aggregate => $field) {
259            if ($aggregate === 'count') {
260                return $this->formatAggregateResponse($aggregate, $field, $this->queryFiltered->count());
261            }
262
263            return $this->formatAggregateResponse($aggregate, $field, $this->queryFiltered->$aggregate($field));
264        }
265
266        return null;
267    }
268
269    /**
270     * @param string $type
271     * @param string $field
272     * @param $value
273     * @return array
274     */
275    protected function formatAggregateResponse(string $type, string $field, $value)
276    {
277        return [
278            'data' => [
279                [
280                    $field => [$type => $value]
281                ]
282            ]
283        ];
284    }
285
286    /**
287     * @param Filters $filters
288     * @param array $result
289     */
290    protected function addPotentialFiltersErrors(Filters $filters, array &$result)
291    {
292        $errors = $filters->getErrors();
293
294        if (!empty($errors)) {
295            $result['filter_errors'] = $errors;
296        }
297    }
298}