Passed
Push — master ( 5e2b09...a39721 )
by Ben
09:28 queued 02:28
created

Fields::any()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 1
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Thinktomorrow\Chief\Fields;
6
7
use ArrayIterator;
8
use Thinktomorrow\Chief\Fields\Types\Field;
9
10
class Fields implements \ArrayAccess, \IteratorAggregate, \Countable
11
{
12
    /** @var array */
13 128
    private $fields;
14
15 128
    final public function __construct(array $fields = [])
16
    {
17 128
        $this->validateFields($fields);
18 128
19
        $this->fields = $this->convertToKeyedArray($fields);
20 100
    }
21
22 100
    public static function make(array $fields = [])
23
    {
24
        return new static($fields);
25 5
    }
26
27 5
    public function all(): array
28
    {
29
        return $this->fields;
30
    }
31 5
32
    public function first(): ?Field
33
    {
34 5
        if (!$this->any()) {
35
            return null;
36 5
        }
37
38
        return reset($this->fields);
39
    }
40
41
    public function any(): bool
42
    {
43
        return count($this->all()) > 0;
44 7
    }
45
46 7
    public function isEmpty(): bool
47
    {
48
        return !$this->any();
49 108
    }
50
51 108
    public function keys(): array
52 108
    {
53
        return array_keys($this->fields);
54 99
    }
55
56 5
    public function map(callable $callback): Fields
57
    {
58 5
        $keys = array_keys($this->fields);
59
60 5
        $items = array_map($callback, $this->fields, $keys);
61 5
62 2
        return new static(array_combine($keys, $items));
0 ignored issues
show
Bug introduced by
It seems like array_combine($keys, $items) can also be of type false; however, parameter $fields of Thinktomorrow\Chief\Fields\Fields::__construct() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

62
        return new static(/** @scrutinizer ignore-type */ array_combine($keys, $items));
Loading history...
63 2
    }
64
65
    public function filterBy($key, $value = null)
66 2
    {
67
        $fields = [];
68
69
        foreach ($this->fields as $i => $field) {
70 3
            if ($key instanceof \Closure) {
71 3
                if (true == $key($field)) {
72
                    $fields[] = $field;
73
                }
74
75 3
                continue;
76 3
            }
77
78
            $method = 'get' . ucfirst($key);
79
80 5
            // Reject from list if value does not match expected one
81
            if ($value && $value == $field->$method()) {
82
                $fields[] = $field;
83 89
            } // Reject from list if key returns null (key not present on field)
84
            elseif (!$value && !is_null($field->$method())) {
85 89
                $fields[] = $field;
86
            }
87
        }
88 87
89
        return new static($fields);
90 87
    }
91
92
    public function render(): string
93
    {
94
        return array_reduce($this->fields, function(string $carry, Field $field){
95
            return $carry . $field->render();
96
        }, '');
97
    }
98
99
    public function keyed($key): Fields
100
    {
101
        $keys = (array) $key;
102
103
        return new static(array_filter($this->fields, function(Field $field) use($keys){
104
            return in_array($field->getKey(), $keys);
105
        }));
106
    }
107
108
    public function tagged($tag): Fields
109
    {
110
        return new static(array_filter($this->fields, function(Field $field) use($tag){
111
            return $field->tagged($tag);
0 ignored issues
show
Bug introduced by
The method tagged() does not exist on Thinktomorrow\Chief\Fields\Types\Field. Since it exists in all sub-types, consider adding an abstract or default implementation to Thinktomorrow\Chief\Fields\Types\Field. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
            return $field->/** @scrutinizer ignore-call */ tagged($tag);
Loading history...
112 24
        }));
113
    }
114 24
115
    public function untagged(): Fields
116
    {
117 25
        return new static(array_filter($this->fields, function(Field $field){
118
            return $field->untagged();
0 ignored issues
show
Bug introduced by
The method untagged() does not exist on Thinktomorrow\Chief\Fields\Types\Field. Since it exists in all sub-types, consider adding an abstract or default implementation to Thinktomorrow\Chief\Fields\Types\Field. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
            return $field->/** @scrutinizer ignore-call */ untagged();
Loading history...
119 25
        }));
120 25
    }
121 25
122
    public function add(Field ...$fields): Fields
123
    {
124 95
        return new Fields(array_merge($this->fields, $fields));
125
    }
126 95
127
    public function merge(Fields $fields): Fields
128
    {
129
        return new Fields(array_merge($this->fields, $fields->all()));
130 95
    }
131 95
132
    public function remove($keys = null)
133 4
    {
134
        if (!$keys) {
135 4
            return $this;
136 4
        }
137
138 108
        if (is_string($keys)) {
139
            $keys = func_get_args();
140 108
        }
141
142
        foreach ($this->fields as $k => $field) {
143 128
            if (in_array($field->getKey(), $keys)) {
144
                unset($this->fields[$k]);
145 128
            }
146
        }
147 128
148 124
        return $this;
149
    }
150
151 128
    public function offsetExists($offset)
152
    {
153
        return isset($this->fields[$offset]);
154 128
    }
155
156
    public function offsetGet($offset)
157 128
    {
158 128
        return (isset($this->fields[$offset]))
159
            ? $this->fields[$offset]
160 12
            : null;
161
    }
162 12
163
    public function offsetSet($offset, $value)
164
    {
165
        if (!$value instanceof Field) {
166
            throw new \InvalidArgumentException('Passed value must be of type ' . Field::class);
167
        }
168
169
        $this->fields[$offset] = $value;
170
    }
171
172
    public function offsetUnset($offset)
173
    {
174
        unset($this->fields[$offset]);
175
    }
176
177
    public function getIterator()
178
    {
179
        return new ArrayIterator($this->fields);
180
    }
181
182
    private function convertToKeyedArray(array $fields): array
183
    {
184
        $keyedFields = [];
185
186
        /** @var Field */
187
        foreach ($fields as $field) {
188
            $keyedFields[$field->getKey()] = $field;
189
        }
190
191
        return $keyedFields;
192
    }
193
194
    private function validateFields(array $fields)
195
    {
196
        array_map(function (Field $field) {
197
        }, $fields);
198
    }
199
200
    public function count()
201
    {
202
        return count($this->fields);
203
    }
204
}
205