SelectFilter   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 77
c 2
b 1
f 0
dl 0
loc 163
rs 9.76
ccs 0
cts 124
cp 0
wmc 33

12 Methods

Rating   Name   Duplication   Size   Complexity  
A applyRelationValues() 0 8 1
A getSelectedGroupedOptions() 0 22 6
A isSelectField() 0 3 1
A getSelectedOptions() 0 8 1
A getOptions() 0 8 2
A multiple() 0 5 1
A isNullable() 0 7 2
A render() 0 12 4
A options() 0 5 1
A isMultiple() 0 7 2
A nullable() 0 5 1
B apply() 0 41 11
1
<?php
2
3
namespace Yaro\Jarboe\Table\Filters;
4
5
class SelectFilter extends AbstractFilter
6
{
7
    const NO_INPUT_APPLIED = '__jarboe-no-search-input-applied';
8
9
    private $multiple = false;
10
    private $options = null;
11
    private $nullable = false;
12
13
    public function render()
14
    {
15
        $value = $this->value();
16
        $values = [];
17
        if (!is_null($value) && $value !== self::NO_INPUT_APPLIED) {
18
            $values = is_array($value) ? $value : [$value];
19
        }
20
21
        return view('jarboe::crud.filters.select', [
22
            'filter' => $this,
23
            'values' => $values,
24
            'desearch' => self::NO_INPUT_APPLIED,
25
        ]);
26
    }
27
28
    public function multiple(bool $multiple = true)
29
    {
30
        $this->multiple = $multiple;
31
32
        return $this;
33
    }
34
35
    public function nullable(bool $nullable = true)
36
    {
37
        $this->nullable = $nullable;
38
39
        return $this;
40
    }
41
42
    public function isNullable(): bool
43
    {
44
        if (is_null($this->nullable)) {
0 ignored issues
show
introduced by
The condition is_null($this->nullable) is always false.
Loading history...
45
            return $this->field()->isNullable();
46
        }
47
48
        return $this->nullable;
49
    }
50
51
    public function isMultiple(): bool
52
    {
53
        if (is_null($this->multiple)) {
0 ignored issues
show
introduced by
The condition is_null($this->multiple) is always false.
Loading history...
54
            return $this->field()->isMultiple();
55
        }
56
57
        return $this->multiple;
58
    }
59
60
    public function options(array $options)
61
    {
62
        $this->options = $options;
63
64
        return $this;
65
    }
66
67
    public function getOptions()
68
    {
69
        $options = $this->options;
70
        if (is_null($options)) {
71
            $options = $this->field()->getOptions();
72
        }
73
74
        return $options;
75
    }
76
77
    public function getSelectedOptions(array $values, int $index = 0): array
78
    {
79
        $total = 0;
80
        $options = $this->field()->getOptions(null, null, null, $total, $index, function ($query, $related) use ($values) {
81
            $query->whereIn($related->getTable() .'.'. $related->getKeyName(), $values);
82
        });
83
84
        return $options;
85
    }
86
87
    public function getSelectedGroupedOptions(): array
88
    {
89
        $value = $this->value();
90
        $values = is_array($value) ? $value : [$value];
91
        $values = array_filter($values);
92
93
        $options = [];
94
        foreach ($this->field()->getRelations() as $index => $relation) {
95
            $groupValues = [];
96
            foreach ($values as $value) {
97
                list($groupHash, $groupValue) = explode('~~~', $value);
98
                if ($groupHash == crc32($relation['group'])) {
99
                    $groupValues[] = $groupValue;
100
                }
101
            }
102
103
            if ($groupValues) {
104
                $options[$relation['group']] = $this->getSelectedOptions($groupValues, $index);
105
            }
106
        }
107
108
        return array_filter($options);
109
    }
110
111
    public function isSelectField(): bool
112
    {
113
        return method_exists($this->field(), 'isSelect2Type');
114
    }
115
116
    public function apply($query)
117
    {
118
        $value = $this->value();
119
        if (is_null($value) || $value == self::NO_INPUT_APPLIED) {
120
            return;
121
        }
122
123
        if ($this->field()->isRelationField()) {
124
            $values = is_array($value) ? $value : [$value];
125
            $model = $this->field()->getModel();
126
            $model = new $model;
127
128
            foreach ($this->field()->getRelations() as $index => $relation) {
129
                $groupValues = $values;
130
                if ($this->field()->isGroupedRelation()) {
131
                    $groupValues = [];
132
                    foreach ($values as $value) {
133
                        list($groupHash, $groupValue) = explode('~~~', $value);
134
                        if ($groupHash == crc32($relation['group'])) {
135
                            $groupValues[] = $groupValue;
136
                        }
137
                    }
138
                }
139
140
                if ($groupValues) {
141
                    $this->applyRelationValues($model, $query, $groupValues, $index);
142
                }
143
            }
144
145
            return;
146
        }
147
148
        if ($this->field()->isMultiple()) {
149
            $query->whereIn($this->field()->name(), $value);
150
            return;
151
        }
152
153
        $query->where(
154
            $this->field()->name(),
155
            $this->sign,
156
            $value
157
        );
158
    }
159
160
    private function applyRelationValues($model, $query, $values, int $index = 0)
161
    {
162
        $relationQuery = $model->{$this->field()->getRelationMethod($index)}()->getRelated();
163
        $relationClass = get_class($relationQuery);
164
        $relationClass = new $relationClass;
165
166
        $query->whereHas($this->field()->getRelationMethod($index), function ($query) use ($values, $relationClass, $relationQuery) {
167
            $query->whereIn($relationQuery->getTable() .'.'. $relationClass->getKeyName(), $values);
168
        });
169
    }
170
}
171