Passed
Push — master ( 74cbab...62dc6b )
by Stephen
02:33
created

ApplyFilter::applyFilterToQuery()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 2
nop 4
dl 0
loc 9
rs 10
1
<?php
2
3
4
namespace Sfneal\Queries\Traits;
5
6
7
use Illuminate\Database\Eloquent\Builder;
8
use Sfneal\Filters\FilterInterface;
9
use Sfneal\Filters\FilterNullableInterface;
10
11
trait ApplyFilter
12
{
13
    /**
14
     * Apply a filter to a Query if the Filter class is valid
15
     *
16
     * @param Builder $query
17
     * @param string $filterName
18
     * @param mixed $filterValue
19
     * @param FilterInterface|FilterNullableInterface $decorator
20
     * @return Builder
21
     */
22
    public function applyFilterToQuery(Builder $query, string $filterName, $filterValue=null, $decorator=null) {
23
        // Get the Filter class if none is provided
24
        $decorator = $decorator ?? self::getFilterClass($filterName);
0 ignored issues
show
Bug Best Practice introduced by
The method Sfneal\Queries\Traits\Ap...ilter::getFilterClass() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

24
        $decorator = $decorator ?? self::/** @scrutinizer ignore-call */ getFilterClass($filterName);
Loading history...
25
26
        // Apply Filter class if it exists and is a filterable attribute
27
        if (!is_null($decorator) && self::isValidFilterClass($decorator, $filterName)) {
0 ignored issues
show
Bug Best Practice introduced by
The method Sfneal\Queries\Traits\Ap...r::isValidFilterClass() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

27
        if (!is_null($decorator) && self::/** @scrutinizer ignore-call */ isValidFilterClass($decorator, $filterName)) {
Loading history...
28
            $query = $decorator::apply($query, $filterValue);
29
        }
30
        return $query;
31
    }
32
33
    /**
34
     * Determine if the Filter decorator class exists and is valid
35
     *
36
     * Check that the Filter class exists or the $decorator is an object.
37
     * Then check that the attribute is declared as filterable.
38
     *
39
     * @param string|mixed $decorator
40
     * @param string $attribute
41
     * @return bool
42
     */
43
    private function isValidFilterClass($decorator, string $attribute): bool
44
    {
45
        return (class_exists($decorator) || is_object($decorator)) && $this->isFilterableAttribute($attribute);
46
    }
47
48
    /**
49
     * Create a filter decorator by manipulating filter name to find the corresponding filter class
50
     *
51
     * @param $name
52
     * @return null|string|FilterInterface
53
     */
54
    private function getFilterClass($name)
55
    {
56
        // Check if an array of attribute keys and Filter class values is defined
57
        if (self::isValidFiltersArray($this->attribute_filters) && $this->isFilterableAttribute($name)) {
58
            return $this->attribute_filters[$name];
59
        }
60
    }
61
62
    /**
63
     * Check if the filters array is valid for querying
64
     *
65
     * @param $filters
66
     * @return bool
67
     */
68
    private static function isValidFiltersArray($filters) {
69
        return !empty($filters) && is_array($filters);
70
    }
71
72
    /**
73
     * Determine if a particular filter is in the array of filterable attributes
74
     *
75
     * @param string $name
76
     * @return bool
77
     */
78
    private function isFilterableAttribute(string $name) {
79
        if (property_exists($this, 'attribute_filters')) {
80
            return in_array($name, array_keys($this->attribute_filters));
81
        } else {
82
            return true;
83
        }
84
    }
85
}
86