QueryFilters   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 24
c 4
b 0
f 0
dl 0
loc 123
ccs 27
cts 27
cp 1
rs 10
wmc 13

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A applyToQuery() 0 11 3
A filterCanBeApplied() 0 19 4
A getRequest() 0 7 2
A hydrate() 0 5 1
A setRequest() 0 5 1
A getRules() 0 3 1
1
<?php
2
3
namespace Cerbero\QueryFilters;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Http\Request;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Facades\Request as RequestFacade;
9
use Illuminate\Support\Facades\Validator;
10
use Illuminate\Support\Str;
11
use ReflectionMethod;
12
13
/**
14
 * Abstract implementation of a query filters class.
15
 *
16
 */
17
abstract class QueryFilters
18
{
19
    /**
20
     * The HTTP request with query parameters.
21
     *
22
     * @var \Illuminate\Http\Request
23
     */
24
    protected $request;
25
26
    /**
27
     * The Eloquent query builder.
28
     *
29
     * @var \Illuminate\Database\Eloquent\Builder
30
     */
31
    protected $query;
32
33
    /**
34
     * Set the dependencies.
35
     *
36
     * @param \Illuminate\Http\Request|null $request
37 18
     */
38
    public function __construct(Request $request = null)
39 18
    {
40 18
        // do not inject requests to support Laravel Octane
41
        // @todo: remove constructor in the next major release
42
    }
43
44
    /**
45
     * Set the request that query filters are based on
46
     *
47 3
     * @param \Illuminate\Http\Request $request
48
     * @return self
49 3
     */
50
    public function setRequest(Request $request)
51
    {
52
        $this->request = $request;
53
54
        return $this;
55
    }
56
57
    /**
58 6
     * Retrieve the request that query filters are based on
59
     *
60 6
     * @return \Illuminate\Http\Request
61
     */
62 6
    public function getRequest()
63
    {
64
        if (!isset($this->request)) {
65
            $this->request = RequestFacade::instance();
66
        }
67
68
        return $this->request;
69
    }
70
71 15
    /**
72
     * Hydrate query filters from a plain array.
73 15
     *
74
     * @param array $queries
75 15
     * @return static
76 15
     */
77 15
    public static function hydrate(array $queries)
78 5
    {
79 5
        $request = new Request($queries);
80
81 15
        return (new static())->setRequest($request);
82
    }
83
84
    /**
85
     * Apply filters based on query parameters.
86
     *
87
     * @param \Illuminate\Database\Eloquent\Builder $query
88
     * @return \Illuminate\Database\Eloquent\Builder
89
     */
90
    public function applyToQuery(Builder $query)
91 15
    {
92
        $this->query = $query;
93 15
94
        foreach ($this->getRequest()->all() as $filter => $value) {
95
            if ($this->filterCanBeApplied($filter, $value)) {
96 15
                call_user_func([$this, Str::camel($filter)], $value);
97 3
            }
98
        }
99
100
        return $query;
101 15
    }
102 12
103 12
    /**
104
     * Determine whether the given filter can be applied with the provided value.
105 12
     *
106
     * @param string $filter
107
     * @param mixed $value
108
     * @return boolean
109 15
     */
110
    protected function filterCanBeApplied($filter, $value)
111
    {
112
        $method = Str::camel($filter);
113
114
        // do not apply query filters that haven't been implemented
115
        if (!method_exists($this, $method)) {
116
            return false;
117
        }
118 9
119
        // apply query filters with valid values
120 9
        if ($value !== '' && $value !== null) {
121
            $data = $this->getRequest()->only($filter);
122
            $rules = Arr::only($this->getRules(), $filter);
123
124
            return !Validator::make($data, $rules)->fails();
125
        }
126
127
        // apply query filters that don't need values (implicit filters)
128
        return (new ReflectionMethod($this, $method))->getNumberOfParameters() === 0;
129
    }
130
131
    /**
132
     * Retrieve the rules to validate filters value.
133
     * If a filter validation fails, the filter is not applied.
134
     *
135
     * @return array
136
     */
137
    protected function getRules()
138
    {
139
        return [];
140
    }
141
}
142