Passed
Pull Request — master (#1)
by Zing
08:22 queued 04:05
created

Filter::castValue()   B

Complexity

Conditions 10
Paths 8

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 17.8732

Importance

Changes 0
Metric Value
cc 10
eloc 17
c 0
b 0
f 0
nc 8
nop 1
dl 0
loc 27
ccs 8
cts 14
cp 0.5714
crap 17.8732
rs 7.6666

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