InputCriteria::apply()   F
last analyzed

Complexity

Conditions 13
Paths 1024

Size

Total Lines 58

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 41
CRAP Score 13

Importance

Changes 0
Metric Value
cc 13
nc 1024
nop 2
dl 0
loc 58
ccs 41
cts 41
cp 1
crap 13
rs 2.45
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace NwLaravel\Repositories\Criterias;
3
4
use Prettus\Repository\Contracts\CriteriaInterface;
5
use Prettus\Repository\Contracts\RepositoryInterface;
6
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
7
use Illuminate\Database\Eloquent\Model;
8
use NwLaravel\Entities\AbstractEntity;
9
10
/**
11
 * Class InputCriteria
12
 */
13
class InputCriteria implements CriteriaInterface
14
{
15
    /**
16
     * @var array
17
     */
18
    protected $input = [];
19
20
    /**
21
     * @var array
22
     */
23
    protected $columns = [];
24
25
    /**
26
     * @var array
27
     */
28
    protected $dates = [];
29
30
    /**
31
     * @var string
32
     */
33
    protected $table = '';
34
35
    /**
36
     * @var string
37
     */
38
    protected $nameSearchable = 'search';
39
40
    /**
41
     * @var array
42
     */
43
    protected $searchables = [];
44
45
    /**
46
     * @var string
47
     */
48
    protected $orderBy = null;
49
50
    /**
51
     * @var string
52
     */
53
    protected $sortedBy = 'asc';
54
55
    /**
56
     * @var RepositoryInterface
57
     */
58
    protected $repository = null;
59
60
    /**
61
     * @var Grammar
62
     */
63
    private $grammar = null;
64
65
    /**
66
     * Construct
67
     *
68
     * @param array $input
69
     */
70 14
    public function __construct(array $input = array())
71
    {
72
        $this->input = array_filter($input, function ($value) {
73 14
            return (!empty($value) || $value == "0" || is_null($value));
74 14
        });
75 14
    }
76
77
    /**
78
     * Add Columns
79
     *
80
     * @param array $columns Array Columns
81
     *
82
     * @return this
83
     */
84 5
    public function addColumns(array $columns)
85
    {
86 5
        $this->columns = array_unique(array_merge($this->columns, $columns));
87 5
        return $this;
88
    }
89
90
    /**
91
     * Set Fields Searchable
92
     *
93
     * @param array $searchables
94
     *
95
     * @return this
96
     */
97 1
    public function setSearchables(array $searchables)
98
    {
99 1
        $this->searchables = $searchables;
100 1
        return $this;
101
    }
102
103
    /**
104
     * Set Name Fields Searchable
105
     *
106
     * @param string $name
107
     *
108
     * @return this
109
     */
110 5
    public function setNameSearchable($name)
111
    {
112 5
        $this->nameSearchable = $name;
113 5
        return $this;
114
    }
115
116
    /**
117
     * Set Order BY
118
     *
119
     * @param string $orderBy
120
     *
121
     * @return this
122
     */
123 5
    public function setFieldOrderBy($orderBy)
124
    {
125 5
        $this->orderBy = strtolower($orderBy);
126 5
        return $this;
127
    }
128
129
    /**
130
     * Set Sorted By
131
     *
132
     * @param string $sortedBy
133
     *
134
     * @return this
135
     */
136 5
    public function setFieldSortedBy($sortedBy)
137
    {
138 5
        $sortedBy = strtolower($sortedBy);
139 5
        $this->sortedBy = in_array($sortedBy, ['asc', 'desc']) ? $sortedBy : 'asc';
140 5
        return $this;
141
    }
142
143
    /**
144
     * Apply criteria in query
145
     *
146
     * @param Builder $query
147
     *
148
     * @return mixed
149
     */
150
151 12
    public function apply($query, RepositoryInterface $repository = null)
152
    {
153 12
        if ($repository) {
154 7
            $this->searchables = array_merge($this->searchables, $repository->getFieldsSearchable());
155 7
        }
156
157 12
        if ($nameSearchable = config('repository.criteria.params.search')) {
158 5
            $this->setNameSearchable($nameSearchable);
159 5
        }
160
161 12
        if ($orderBy = config('repository.criteria.params.orderBy')) {
162 5
            $this->setFieldOrderBy($orderBy);
163 5
        }
164
165 12
        if ($sortedBy = config('repository.criteria.params.sortedBy')) {
166 5
            $this->setFieldSortedBy($sortedBy);
167 5
        }
168
169 12
        $model = $query;
170
171 12
        if ($query instanceof EloquentBuilder) {
172 4
            $model = $query->getModel();
173 4
        }
174
175 12
        if ($model instanceof Model) {
176 10
            $this->dates = $model->getDates();
177 10
            $this->table = $model->getTable();
178 10
        }
179
180 12
        if ($model instanceof AbstractEntity) {
181 4
            $this->addColumns($model->columns());
182 4
        }
183
184
        $filters = [
185 12
            new Filters\FilterClosure,
186 12
            new Filters\FilterScope($model),
187 12
            new Filters\FilterSearch($this->nameSearchable, $this->searchables, $this->table),
188 12
            new Filters\FilterExpression,
189 12
            new Filters\FilterArray($this->table, $this->columns, $this->dates),
190 12
            new Filters\FilterWhere($this->table, $this->columns, $this->dates),
191 12
        ];
192
193 12
        foreach ($this->input as $key => $value) :
194
195 12
            foreach ($filters as $filter) {
196 12
                if ($filter->filter($query, $key, $value)) {
197 4
                    break;
198
                }
199 12
            }
200 11
        endforeach;
201
202
        // Order By
203 11
        if ($this->orderBy && in_array($this->orderBy, $this->columns)) {
204 4
            $query = $query->orderBy($this->orderBy, $this->sortedBy);
205 4
        }
206
207 11
        return $query;
208
    }
209
210
    /**
211
     * Where
212
     *
213
     * @param Builder $query    Builder
214
     * @param string  $key      Key
215
     * @param string  $operator String Operator
216
     * @param int     $value    Value
217
     *
218
     * @throws InvalidArgumentException
219
     * @return mixed
220
     */
221
    protected function whereCriteria($query, $key, $operator = null, $value = null)
222
    {
223
        $validOperator = function ($operator) {
224
            $operators = ['=', '<', '>', '<=', '>=', '<>', '!='];
225
            return in_array($operator, $operators);
226
        };
227
228
        if (! $validOperator($operator)) {
229
            throw new InvalidArgumentException("Illegal operator and value combination.");
230
        }
231
232
        // Raw Expression with Bidding
233
        if (strpos($key, '?') !== false) {
234
            $query = $query->whereRaw($key, (array) $value);
235
            return $query;
236
        }
237
238
        $table = $this->table;
239
        $column = $key;
240
        if (preg_match('/^(.+\.)(.+)/', $key, $matches)) {
241
            $table = $matches[1];
242
            $column = $matches[2];
243
        }
244
245
        // Montagem Tabela com Coluns
246
        $key = $table.$column;
247
248
        // Attributes Valids
249
        if (in_array($column, $this->columns)) {
250
            if (is_null($value)) {
251
                if ($operator == '!=' || $operator == '<>') {
252
                    $query = $query->whereNotNull($key);
253
                } else {
254
                    $query = $query->whereNull($key);
255
                }
256
                return $query;
257
            }
258
259
            if (in_array($column, $this->dates)) {
260
                $query = $this->whereDate($query, $key, $operator, $value);
261
                return $query;
262
            }
263
264
            // Using Where In With An Array
265
            if (is_array($value)) {
266
                if ($operator == '!=' || $operator == '<>') {
267
                    $query = $query->whereNotIn($key, $value);
268
                } else {
269
                    $query = $query->whereIn($key, $value);
270
                }
271
                return $query;
272
            }
273
274
            // Busca Direta
275
            $query = $query->where($key, $operator, $value);
276
            return $query;
277
        }
278
279
        $query = $this->whereBetweenColumn($query, $key, $value);
280
        return $query;
281
    }
282
283
    /**
284
     * Where Search
285
     *
286
     * @param Builder $query  Builder
287
     * @param string  $search String Search
288
     *
289
     * @return mixed
290
     */
291
    protected function whereSearch($query, $search)
292
    {
293
        $fieldsSearchable = $this->searchables;
294
        $query = $query->where(function ($query) use ($fieldsSearchable, $search) {
295
            foreach ($fieldsSearchable as $field => $condition) {
296
                if (is_numeric($field)) {
297
                    $field = $condition;
298
                    $condition = "=";
299
                }
300
301
                $condition  = trim(strtolower($condition));
302
303
                if (!empty($search)) {
304
                    $value = in_array($condition, ["like", "ilike"]) ? "%{$search}%" : $search;
305
                    $query->orWhere($this->table.$field, $condition, $value);
306
                }
307
            }
308
        });
309
310
        return $query;
311
    }
312
313
    /**
314
     * Where Date
315
     *
316
     * @param Builder $query    Builder
317
     * @param string  $key      Key
318
     * @param string  $operator String Operator
319
     * @param int     $value    Value
320
     *
321
     * @throws InvalidArgumentException
322
     * @return mixed
323
     */
324
    private function whereDate($query, $key, $operator, $value)
325
    {
326
        if (is_string($value)) {
327
            $value = str_replace("_", '', $value); // Caso vier com a mascara __/__/____
328
        }
329
330
        if (! empty($value)) {
331
            $date = asDateTime($value);
332
333
            if ($date instanceof Datetime) {
0 ignored issues
show
Bug introduced by
The class NwLaravel\Repositories\Criterias\Datetime does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
334
                $query = $query->whereRaw(
335
                    $this->dateFormatDb($query, $key, $operator),
336
                    [$date->format('Y-m-d')]
337
                );
338
            } else {
339
                if ($operator == '!=' || $operator == '<>') {
340
                    $query = $query->whereNotNull($key);
341
                } else {
342
                    $query = $query->whereNull($key);
343
                }
344
            }
345
        }
346
347
        return $query;
348
    }
349
350
    /**
351
     *
352
     * @param Builder $query Builder Query
353
     * @param string  $key   String  Key
354
     * @param int     $value Value
355
     *
356
     *@return mixed
357
     */
358
    private function whereBetweenColumn($query, $key, $value)
359
    {
360
        $table = $this->table;
361
        $column = $key;
362
        if (preg_match('/^(.+\.)(.+)/', $key, $matches)) {
363
            $table = $matches[1];
364
            $column = $matches[2];
365
        }
366
367
        if (preg_match('/^(.+)(_ini|_fim)$/', $column, $match) && in_array($match[1], $this->columns)) {
368
            $field = $match[1];
369
            $operator = ($match[2]=='_ini')? '>=' : '<=';
370
            if (in_array($field, $this->dates)) {
371
                $query = $this->whereDate($query, $table.$field, $operator, $value);
372
            } else {
373
                $query = $query->where($table.$field, $operator, $value);
374
            }
375
        }
376
377
        return $query;
378
    }
379
    
380
    /**
381
     * Date Formate Database
382
     *
383
     * @param Builder  $query    Builder
384
     * @param string   $key      Column
385
     * @param string   $operator String Operator
386
     *
387
     * @return string
388
     */
389
    private function dateFormatDb($query, $key, $operator)
390
    {
391
        if (!$this->grammar) {
392
            $this->grammar = $query->getQuery()->getGrammar();
393
        }
394
395
        $key = $this->grammar->wrap($key);
396
397
        $formatDb = sprintf("%s %s ?", $key, $operator);
398
399
        switch (true) {
400
            case $this->grammar instanceof \Illuminate\Database\Query\Grammars\MySqlGrammar:
401
                $formatDb = sprintf("DATE(%s) %s ?", $key, $operator);
402
                break;
403
404
            case $this->grammar instanceof \Illuminate\Database\Query\Grammars\PostgresGrammar:
405
                $formatDb = sprintf("DATE_TRUNC('day', %s) %s ?", $key, $operator);
406
                break;
407
408
            case $this->grammar instanceof \Illuminate\Database\Query\Grammars\SQLiteGrammar:
409
                $formatDb = sprintf("strftime('%%Y-%%m-%%d', %s) %s ?", $key, $operator);
410
                break;
411
412
            case $this->grammar instanceof \Illuminate\Database\Query\Grammars\SqlServerGrammar:
413
                $formatDb = sprintf("CAST(%s AS DATE) %s ?", $key, $operator);
414
        }
415
416
        return $formatDb;
417
    }
418
}
419