Passed
Push — master ( 3ca966...bbe27c )
by Zing
15:44 queued 09:09
created

Filter::castValue()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.016

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
nc 3
nop 1
dl 0
loc 15
ccs 9
cts 10
cp 0.9
crap 4.016
rs 9.9666
c 3
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Zing\QueryBuilder;
6
7
use Illuminate\Database\Eloquent\Builder;
8
use Illuminate\Support\Collection;
9
use Zing\QueryBuilder\Concerns\FilterCreator;
10
use Zing\QueryBuilder\Enums\CastType;
11
12
class Filter
13
{
14
    use FilterCreator;
15
16
    /**
17
     * @param mixed $value
18
     */
19 46
    public function filter(Builder $query, $value): Builder
20
    {
21 46
        $value = $this->resolveValueForFiltering($value);
22 46
        if ($value === null) {
23 1
            return $query;
24
        }
25
26 45
        if ($value === '') {
27 1
            return $query;
28
        }
29
30 44
        return $this->filter->apply($query, $value, $this->column);
31
    }
32
33 44
    public function getProperty(): string
34
    {
35 44
        return $this->property;
36
    }
37
38 3
    public function isForProperty(string $property): bool
39
    {
40 3
        return $this->property === $property;
41
    }
42
43
    /**
44
     * @return \Illuminate\Database\Query\Expression|string
45
     */
46 1
    public function getColumn()
47
    {
48 1
        return $this->column;
49
    }
50
51 10
    public function withCast(string $cast): self
52
    {
53 10
        $this->cast = $cast;
54
55 10
        return $this;
56
    }
57
58 1
    public function hasCast(): bool
59
    {
60 1
        return $this->cast !== null;
61
    }
62
63 37
    public function getCast(): ?string
64
    {
65 37
        return $this->cast;
66
    }
67
68
    /**
69
     * @param mixed[] $values
70
     */
71 1
    public function ignore(array $values): self
72
    {
73 1
        $this->ignored = ($this->ignored === null ? collect($values) : $this->ignored
74
            ->merge($values))
75 1
            ->flatten();
76
77 1
        return $this;
78
    }
79
80
    /**
81
     * @return \Illuminate\Support\Collection<int, mixed>
82
     */
83 47
    public function getIgnored(): Collection
84
    {
85 47
        return $this->ignored ?: collect();
86
    }
87
88
    /**
89
     * @param mixed $value
90
     */
91 6
    public function default($value): self
92
    {
93 6
        $this->default = $value;
94
95 6
        return $this;
96
    }
97
98
    /**
99
     * @return mixed|null
100
     */
101 7
    public function getDefault()
102
    {
103 7
        return $this->default;
104
    }
105
106 6
    public function hasDefault(): bool
107
    {
108 6
        return $this->default !== null;
109
    }
110
111
    /**
112
     * @param mixed $value
113
     *
114
     * @return false|mixed|string[]
115
     */
116 37
    protected function castValue($value)
117
    {
118 37
        $cast = $this->getCast();
119 37
        if (! \is_string($value)) {
120
            return $value;
121
        }
122
123 37
        if ($cast === CastType::STRING) {
124 2
            return $value;
125
        }
126
127 35
        return collect(explode($this->delimiter, $value))
128 35
            ->map($this->castUsing($cast))
129 35
            ->whenNotEmpty(function (Collection $collection) {
130 35
                return $collection->count() === 1 ? $collection->first() : $collection->all();
131
            });
132
    }
133
134 35
    protected function castUsing(?string $cast): \Closure
135
    {
136 35
        return function ($value) use ($cast) {
137 35
            if ($cast === CastType::STRING) {
138
                return (string) $value;
139
            }
140
141 35
            if ($cast === CastType::INTEGER) {
142 1
                return (int) $value;
143
            }
144
145 34
            if ($cast === CastType::BOOLEAN) {
146 4
                return filter_var($value, FILTER_VALIDATE_BOOLEAN);
147
            }
148
149 32
            if (\in_array(strtolower($value), ['true', 'false'], true)) {
150 2
                return filter_var($value, FILTER_VALIDATE_BOOLEAN);
151
            }
152
153 30
            return $value;
154
        };
155
    }
156
157
    /**
158
     * @param mixed $value
159
     *
160
     * @return mixed[]|mixed|null
161
     */
162 47
    protected function resolveValueForFiltering($value)
163
    {
164 47
        if (\is_string($value)) {
165 37
            $value = $this->castValue($value);
166
        }
167
168 47
        if (\is_array($value)) {
169 17
            $remainingProperties = array_diff($value, $this->getIgnored()->toArray());
170
171 17
            return empty($remainingProperties) ? null : $remainingProperties;
172
        }
173
174 32
        return $this->getIgnored()
175 32
            ->contains($value) ? null : $value;
176
    }
177
178
    /**
179
     * @param non-empty-string $delimiter
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
180
     */
181 1
    public function delimiter(string $delimiter): self
182
    {
183 1
        $this->delimiter = $delimiter;
184
185 1
        return $this;
186
    }
187
}
188