Filippo Bertilotti
2024-09-10 d409fa3653032013d861de0870eead9e282d3136
commit | author | age
9f6455 1 <?php
DC 2
3 namespace App\Traits;
4
5 use Carbon\Carbon;
6 use Illuminate\Database\Eloquent\Builder;
7 use Illuminate\Support\Arr;
8
9 trait SearchableExtended
10 {
11     /**
12      * The attributes that are searchable.
13      *
14      * @var array
15      */
16     protected $searchable = [];
17
18     /**
19      * Apply filters in your QueryBuilder based in $fields
20      *
21      * @param \Illuminate\Database\Eloquent\Builder $queryBuilder
22      * @param array $fields
23      *
24      * @return Builder
25      */
26     public function scopeSearchWithParams(Builder $queryBuilder, array $fields = []){
27         if (isset($this->searchable)) {
28             foreach ($fields as $field => $config) {
29                 $operator = (is_array($config)) ? Arr::get($config, 'operator', config('searchable.logical_operators.and')) : config('searchable.logical_operators.and');
30                 $value = (is_array($config) && Arr::has($config, "value")) ? Arr::get($config, 'value') : $config;
31
32                 if (!is_null($value) && $this->_isSearchable($field)) {
33                     $searchType = $this->_getSearchType($field, (is_array($config) ? $config : []));
34
35                     if(!is_null($searchType)) {
36                         $args = [
37                             "field" => $field,
38                             "value" => $value,
39                             "operator" => $operator,
40                             "where" => (strcasecmp($operator, config("searchable.logical_operators.or")) == 0) ? "orWhere" : "where",
41                             "searchType" => $searchType,
42                         ];
43
44                         if ($this->_callable($searchType)) {
45                             $functionName = "_applySearch" . $searchType;
46                             $this->$functionName($queryBuilder, $args);
47                         } else {
48                             $this->_callLocalScope($queryBuilder, $args);
49                         }
50                     }
51                 }
52             }
53         }
54
55         return $queryBuilder;
56     }
57
58     /**
59      * @param $type
60      * @return bool
61      */
62     protected function _callable($type)
63     {
64         return Arr::has(array_flip(config("searchable.filter_types")), $type);
65     }
66
67     /**
68      * Check if it is possible to perform a search on the indicated field
69      *
70      * @param string $field
71      * @return bool
72      */
73     protected function _isSearchable(string $field)
74     {
75         return Arr::has($this->searchable, 'columns.' . $field);
76     }
77
78     /**
79      * Returns the type of search associated with the field
80      *
81      * @param string $field
82      * @param array|null $config
83      * @return mixed
84      */
85     protected function _getSearchType(string $field, array $config = [])
86     {
87         $searchType = Arr::get($this->searchable, 'columns.' . $field, null);
88
89         if(!empty($config)) {
90             $searchType = Arr::get($config, "searchType", $searchType);
91         }
92
93         return $searchType;
94     }
95
96     /**
97      * @param Builder $queryBuilder
98      * @param array $args
99      */
100     protected function _applySearchBetween(Builder &$queryBuilder, array $args)
101     {
102         $value = Arr::get($args, "value", []);
103         $field = Arr::get($args, "field", null);
104         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
105
106         if (is_array($value) && count($value) == 2 && !is_null($field)) {
107             $field = $this->getTable() . "." . $field;
108             if(isset($value[0]) && !empty($value[0])) {
109                 $queryBuilder->$where($field, ">=", $value[0]);
110             }
111             if(isset($value[1]) && !empty($value[1])) {
112                 $queryBuilder->$where($field, "<=", $value[1]);
113             }
114         }
115     }
116
117     /**
118      * @param Builder $queryBuilder
119      * @param array $args
120      */
121     protected function _applySearchLike(Builder &$queryBuilder, array $args)
122     {
123         $value = Arr::get($args, "value", []);
124         $field = Arr::get($args, "field", null);
125         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
126
127         if(!is_null($field)) {
128             $field = $this->getTable() . "." . $field;
129             array_map(function ($value) use ($queryBuilder, $field, $where) {
130                 $queryBuilder->$where($field, "LIKE", "%" . $value . "%");
131             }, explode(" ", $value));
132         }
133     }
134
135     /**
136      * @param Builder $queryBuilder
137      * @param array $args
138      */
139     protected function _applySearchMatch(Builder &$queryBuilder, array $args)
140     {
141         $value = Arr::get($args, "value", []);
142         $field = Arr::get($args, "field", null);
143         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
144
145         if(!is_null($field)) {
146             $field = $this->getTable() . "." . $field;
147             $queryBuilder->$where($field, $value);
148         }
149     }
150
151     /**
152      * @param Builder $queryBuilder
153      * @param array $args
154      */
155     protected function _applySearchGreaterThan(Builder &$queryBuilder, array $args)
156     {
157         $value = Arr::get($args, "value", []);
158         $field = Arr::get($args, "field", null);
159         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
160
161         if(!is_null($field)) {
162             $field = $this->getTable() . "." . $field;
163             $queryBuilder->$where($field, ">", $value);
164         }
165     }
166
167     /**
168      * @param Builder $queryBuilder
169      * @param array $args
170      */
171     protected function _applySearchGreaterOrEqual(Builder &$queryBuilder, array $args)
172     {
173         $value = Arr::get($args, "value", []);
174         $field = Arr::get($args, "field", null);
175
176         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
177
178         if(!is_null($field)) {
179             $field = $this->getTable() . "." . $field;
180             $queryBuilder->$where($field, ">=", $value);
181         }
182     }
183
184     /**
185      * @param Builder $queryBuilder
186      * @param array $args
187      */
188     protected function _applySearchLessThan(Builder &$queryBuilder, array $args)
189     {
190         $value = Arr::get($args, "value", []);
191         $field = Arr::get($args, "field", null);
192         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
193
194         if(!is_null($field)) {
195             $field = $this->getTable() . "." . $field;
196             $queryBuilder->$where($field, "<", $value);
197         }
198     }
199
200     /**
201      * @param Builder $queryBuilder
202      * @param array $args
203      */
204     protected function _applySearchLessOrEqual(Builder &$queryBuilder, array $args)
205     {
206         $value = Arr::get($args, "value", []);
207         $field = Arr::get($args, "field", null);
208         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
209
210         if(!is_null($field)) {
211             $field = $this->getTable() . "." . $field;
212             $queryBuilder->$where($field, "<=", $value);
213         }
214     }
215
216     /**
217      * @param Builder $queryBuilder
218      * @param array $args
219      */
220     protected function _applySearchDateGreaterThan(Builder &$queryBuilder, array $args)
221     {
222         $value = Arr::get($args, "value", "");
223         $field = Arr::get($args, "field", null);
224         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
225
226         if(!is_null($field)) {
227             $field = $this->getTable() . "." . $field;
228             $queryBuilder->$where($field, ">", Carbon::createFromFormat('d/m/Y',  $value)->format("Y-m-d"));
229         }
230     }
231
232     /**
233      * @param Builder $queryBuilder
234      * @param array $args
235      */
236     protected function _applySearchDateGreaterOrEqual(Builder &$queryBuilder, array $args)
237     {
238         $value = Arr::get($args, "value", "");
239         $field = Arr::get($args, "field", null);
240         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
241
242         if(!is_null($field)) {
243             $field = $this->getTable() . "." . $field;
244             $queryBuilder->$where($field, ">=", Carbon::createFromFormat('d/m/Y',  $value)->format("Y-m-d"));
245         }
246     }
247
248     /**
249      * @param Builder $queryBuilder
250      * @param array $args
251      */
252     protected function _applySearchDateLessThan(Builder &$queryBuilder, array $args)
253     {
254         $value = Arr::get($args, "value", "");
255         $field = Arr::get($args, "field", null);
256         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
257
258         if(!is_null($field)) {
259             $field = $this->getTable() . "." . $field;
260             $queryBuilder->$where($field, "<", Carbon::createFromFormat('d/m/Y',  $value)->format("Y-m-d"));
261         }
262     }
263
264     /**
265      * @param Builder $queryBuilder
266      * @param array $args
267      */
268     protected function _applySearchDateLessOrEqual(Builder &$queryBuilder, array $args)
269     {
270         $value = Arr::get($args, "value", "");
271         $field = Arr::get($args, "field", null);
272         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
273
274         if(!is_null($field)) {
275             $field = $this->getTable() . "." . $field;
276             $queryBuilder->$where($field, "<=", Carbon::createFromFormat('d/m/Y',  $value)->format("Y-m-d"));
277         }
278     }
279
280     /**
281      * @param Builder $queryBuilder
282      * @param array $args
283      */
284     protected function _applySearchDateGreaterThanNullable(Builder &$queryBuilder, array $args)
285     {
286         $value = Arr::get($args, "value", "");
287         $field = Arr::get($args, "field", null);
288         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
289
290         if(!is_null($field)) {
291             $field = $this->getTable() . "." . $field;
292             $queryBuilder->where(function ($query) use ($value, $field, $where) {
293                 $query->$where($field, ">=", Carbon::createFromFormat('d/m/Y',  $value)->format("Y-m-d"))
294                     ->orWhereNull($field);
295             });
296         }
297     }
298
299     /**
300      * @param Builder $queryBuilder
301      * @param array $args
302      */
303     protected function _applySearchDateGreaterOrEqualNullable(Builder &$queryBuilder, array $args)
304     {
305         $value = Arr::get($args, "value", "");
306         $field = Arr::get($args, "field", null);
307         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
308
309         if(!is_null($field)) {
310             $field = $this->getTable() . "." . $field;
311             $queryBuilder->where(function ($query) use ($value, $field, $where) {
312                 $query->$where($field, ">=", Carbon::createFromFormat('d/m/Y',  $value)->format("Y-m-d"))
313                     ->orWhereNull($field);
314             });
315         }
316     }
317
318     /**
319      * @param Builder $queryBuilder
320      * @param array $args
321      */
322     protected function _applySearchDateLessThanNullable(Builder &$queryBuilder, array $args)
323     {
324         $value = Arr::get($args, "value", "");
325         $field = Arr::get($args, "field", null);
326         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
327
328         if(!is_null($field)) {
329             $field = $this->getTable() . "." . $field;
330             $queryBuilder->where(function ($query) use ($value, $field, $where) {
331                 $query->$where($field, "<", Carbon::createFromFormat('d/m/Y',  $value)->format("Y-m-d"))
332                     ->orWhereNull($field);
333             });
334         }
335     }
336
337     /**
338      * @param Builder $queryBuilder
339      * @param array $args
340      */
341     protected function _applySearchDateLessOrEqualNullable(Builder &$queryBuilder, array $args)
342     {
343         $value = Arr::get($args, "value", "");
344         $field = Arr::get($args, "field", null);
345         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
346
347         if(!is_null($field)) {
348             $field = $this->getTable() . "." . $field;
349             $queryBuilder->where(function ($query) use ($value, $field, $where) {
350                 $query->$where($field, "<=", Carbon::createFromFormat('d/m/Y',  $value)->format("Y-m-d"))
351                     ->orWhereNull($field);
352             });
353         }
354     }
355
356     /**
357      * @param Builder $queryBuilder
358      * @param array $args
359      */
360     protected function _applySearchDifferent(Builder &$queryBuilder, array $args)
361     {
362         $value = Arr::get($args, "value", []);
363         $field = Arr::get($args, "field", null);
364         $where = Arr::get($args, "where", config("searchable.logical_operators.and"));
365
366         if(!is_null($field)) {
367             $field = $this->getTable() . "." . $field;
368             $queryBuilder->$where($field, "<>", $value);
369         }
370     }
371
372     /**
373      * @param Builder $queryBuilder
374      * @param array $args
375      */
376     protected function _applySearchIn(Builder &$queryBuilder, array $args)
377     {
378         $value = Arr::get($args, "value", []);
379         $field = Arr::get($args, "field", null);
380
381         if(!is_null($field)) {
382             $field = $this->getTable() . "." . $field;
383             $queryBuilder->whereIn($field, $value);
384         }
385     }
386
387     /**
388      * @param Builder $queryBuilder
389      * @param array $args
390      */
391     protected function _callLocalScope(Builder &$queryBuilder, array $args)
392     {
393         $value = Arr::get($args, "value", []);
394         $scopeName = Arr::get($args, "searchType", null);
395
396         if(!is_null($scopeName)) {
397             $queryBuilder->{$scopeName}($value);
398         }
399     }
400 }