Completed
Push — master ( 80b847...ba65ab )
by Zing
10:58
created

Filter   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 56
dl 0
loc 203
ccs 65
cts 65
cp 1
rs 9.92
c 1
b 0
f 0
wmc 31

20 Methods

Rating   Name   Duplication   Size   Complexity  
A ignore() 0 7 1
A custom() 0 3 1
A getColumn() 0 3 1
A getDefault() 0 3 1
A partial() 0 3 1
A filter() 0 8 3
A exact() 0 3 1
A getIgnored() 0 3 1
A getProperty() 0 3 1
A __construct() 0 7 1
A hasCast() 0 3 1
A isForProperty() 0 3 1
A withCast() 0 5 1
A default() 0 5 1
A getCast() 0 3 1
A hasDefault() 0 3 1
A callback() 0 3 1
A scope() 0 3 1
A castValue() 0 19 6
A resolveValueForFiltering() 0 12 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Zing\QueryBuilder;
6
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Str;
9
use Zing\QueryBuilder\Enums\CastType;
10
use Zing\QueryBuilder\Filters\FiltersCallback;
11
use Zing\QueryBuilder\Filters\FiltersExact;
12
use Zing\QueryBuilder\Filters\FiltersPartial;
13
use Zing\QueryBuilder\Filters\FiltersScope;
14
15
class Filter
16
{
17
    /**
18
     * @var \Zing\QueryBuilder\Contracts\Filter
19
     */
20
    protected $filter;
21
22
    /**
23
     * @var string
24
     */
25
    protected $property;
26
27
    /**
28
     * @var string
29
     */
30
    protected $column;
31
32
    /**
33
     * @var \Illuminate\Support\Collection
34
     */
35
    protected $ignored;
36
37
    /**
38
     * @var mixed
39
     */
40
    protected $default;
41
42
    protected $cast;
43
44 20
    public function __construct(string $property, $filter, $column = null)
45
    {
46 20
        $this->property = $property;
47
48 20
        $this->filter = $filter;
49 20
        $this->ignored = collect();
50 20
        $this->column = $column ?? $property;
51 20
    }
52
53 18
    public function filter($query, $value)
54
    {
55 18
        $value = $this->resolveValueForFiltering($value);
56 18
        if ($value === null || $value === '') {
57 1
            return $query;
58
        }
59
60 17
        return $this->filter->apply($query, $value, $this->column);
61
    }
62
63
    /**
64
     * 通过另一个字段查询.
65
     *
66
     * @param string $property
67
     * @param \Illuminate\Database\Query\Expression|string|null $column
68
     *
69
     * @return \Zing\QueryBuilder\Filter
70
     */
71 9
    public static function exact(string $property, $column = null): self
72
    {
73 9
        return new static($property, new FiltersExact(), $column);
74
    }
75
76
    /**
77
     * 通过字段模糊查询.
78
     *
79
     * @param string $property
80
     * @param string|null $column
81
     *
82
     * @return \Zing\QueryBuilder\Filter
83
     */
84 6
    public static function partial(string $property, $column = null): self
85
    {
86 6
        return new static($property, new FiltersPartial(), $column);
87
    }
88
89 1
    public static function callback(string $property, $callback, $column = null): self
90
    {
91 1
        return new static($property, new FiltersCallback($callback), $column);
92
    }
93
94
    /**
95
     * 通过作用域查询.
96
     *
97
     * @param string $property
98
     * @param string|null $column
99
     *
100
     * @return \Zing\QueryBuilder\Filter
101
     */
102 2
    public static function scope(string $property, $column = null): self
103
    {
104 2
        return new static($property, new FiltersScope(), $column);
105
    }
106
107
    /**
108
     * 自定义过滤器.
109
     *
110
     * @param string $property
111
     * @param \Zing\QueryBuilder\Contracts\Filter $filterClass
112
     * @param string|null $column
113
     *
114
     * @return \Zing\QueryBuilder\Filter
115
     */
116 2
    public static function custom(string $property, Contracts\Filter $filterClass, $column = null): self
117
    {
118 2
        return new static($property, $filterClass, $column);
119
    }
120
121 18
    public function getProperty(): string
122
    {
123 18
        return $this->property;
124
    }
125
126 1
    public function isForProperty(string $property): bool
127
    {
128 1
        return $this->property === $property;
129
    }
130
131 1
    public function getColumn(): string
132
    {
133 1
        return $this->column;
134
    }
135
136 6
    public function withCast($cast)
137
    {
138 6
        $this->cast = $cast;
139
140 6
        return $this;
141
    }
142
143 1
    public function hasCast(): bool
144
    {
145 1
        return isset($this->cast);
146
    }
147
148 13
    public function getCast()
149
    {
150 13
        return $this->cast;
151
    }
152
153 1
    public function ignore(...$values): self
154
    {
155 1
        $this->ignored = $this->ignored
156 1
            ->merge($values)
157 1
            ->flatten();
158
159 1
        return $this;
160
    }
161
162 19
    public function getIgnored(): Collection
163
    {
164 19
        return $this->ignored;
165
    }
166
167 1
    public function default($value): self
168
    {
169 1
        $this->default = $value;
170
171 1
        return $this;
172
    }
173
174 1
    public function getDefault()
175
    {
176 1
        return $this->default;
177
    }
178
179 1
    public function hasDefault(): bool
180
    {
181 1
        return isset($this->default);
182
    }
183
184 13
    protected function castValue($value)
185
    {
186 13
        switch ($this->getCast()) {
187
            case CastType::CAST_BOOLEAN:
188 2
                return filter_var($value, FILTER_VALIDATE_BOOLEAN);
189
            case CastType::CAST_INTEGER:
190 1
                return filter_var($value, FILTER_VALIDATE_INT);
191
            case CastType::CAST_ARRAY:
192 1
                return explode(',', $value);
193
            default:
194 10
                if (Str::contains($value, ',')) {
195 2
                    return explode(',', $value);
196
                }
197
198 8
                if (in_array(strtolower($value), ['true', 'false'])) {
199 1
                    return filter_var($value, FILTER_VALIDATE_BOOLEAN);
200
                }
201
202 7
                return $value;
203
        }//end switch
204
    }
205
206 19
    protected function resolveValueForFiltering($value)
207
    {
208 19
        if (is_string($value)) {
209 13
            $value = $this->castValue($value);
210
        }
211 19
        if (is_array($value)) {
212 5
            $remainingProperties = array_diff($value, $this->getIgnored()->toArray());
213
214 5
            return ! empty($remainingProperties) ? $remainingProperties : null;
215
        }
216
217 14
        return ! $this->getIgnored()->contains($value) ? $value : null;
218
    }
219
}
220