Passed
Pull Request — master (#28)
by Zing
05:34
created

Filter::withCast()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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