1 | <?php |
||||||||
2 | |||||||||
3 | declare(strict_types=1); |
||||||||
4 | |||||||||
5 | namespace Smoren\ArrayView\Traits; |
||||||||
6 | |||||||||
7 | use Smoren\ArrayView\Exceptions\IndexError; |
||||||||
8 | use Smoren\ArrayView\Exceptions\KeyError; |
||||||||
9 | use Smoren\ArrayView\Exceptions\NotSupportedError; |
||||||||
10 | use Smoren\ArrayView\Exceptions\ReadonlyError; |
||||||||
11 | use Smoren\ArrayView\Interfaces\ArraySelectorInterface; |
||||||||
12 | use Smoren\ArrayView\Interfaces\ArrayViewInterface; |
||||||||
13 | use Smoren\ArrayView\Selectors\IndexListSelector; |
||||||||
14 | use Smoren\ArrayView\Selectors\MaskSelector; |
||||||||
15 | use Smoren\ArrayView\Selectors\SliceSelector; |
||||||||
16 | use Smoren\ArrayView\Structs\Slice; |
||||||||
17 | use Smoren\ArrayView\Util; |
||||||||
18 | |||||||||
19 | /** |
||||||||
20 | * Trait providing methods for accessing elements in ArrayView object. |
||||||||
21 | * |
||||||||
22 | * The trait implements methods for accessing, retrieving, setting, |
||||||||
23 | * and unsetting elements in the ArrayView object. |
||||||||
24 | * |
||||||||
25 | * @template T Type of ArrayView values. |
||||||||
26 | * @template S of string|array<int|bool>|ArrayViewInterface<int|bool>|ArraySelectorInterface Selector type. |
||||||||
27 | */ |
||||||||
28 | trait ArrayViewAccessTrait |
||||||||
29 | { |
||||||||
30 | /** |
||||||||
31 | * Check if the specified offset exists in the ArrayView object. |
||||||||
32 | * |
||||||||
33 | * ```php |
||||||||
34 | * $source = [1, 2, 3, 4, 5]; |
||||||||
35 | * $view = ArrayView::toView($source); |
||||||||
36 | * |
||||||||
37 | * isset($view[0]); // true |
||||||||
38 | * isset($view[-1]); // true |
||||||||
39 | * isset($view[10]); // false |
||||||||
40 | * |
||||||||
41 | * isset($view[new SliceSelector('::2')]); // true |
||||||||
42 | * isset($view[new IndexListSelector([0, 2, 4])]); // true |
||||||||
43 | * isset($view[new IndexListSelector([0, 2, 10])]); // false |
||||||||
44 | * isset($view[new MaskSelector([true, true, false, false, true])]); // true |
||||||||
45 | * isset($view[new MaskSelector([true, true, false, false, true, true])]); // false |
||||||||
46 | * |
||||||||
47 | * isset($view['::2']); // true |
||||||||
48 | * isset($view[[0, 2, 4]]); // true |
||||||||
49 | * isset($view[[0, 2, 10]]); // false |
||||||||
50 | * isset($view[[true, true, false, false, true]]); // true |
||||||||
51 | * isset($view[[true, true, false, false, true, true]]); // false |
||||||||
52 | * ``` |
||||||||
53 | * |
||||||||
54 | * @param numeric|S $offset The offset to check. |
||||||||
0 ignored issues
–
show
The type
Smoren\ArrayView\Traits\numeric was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||||||
55 | * |
||||||||
56 | * @return bool |
||||||||
57 | * |
||||||||
58 | * {@inheritDoc} |
||||||||
59 | */ |
||||||||
60 | public function offsetExists($offset): bool |
||||||||
61 | { |
||||||||
62 | if (\is_numeric($offset)) { |
||||||||
0 ignored issues
–
show
|
|||||||||
63 | return $this->numericOffsetExists($offset); |
||||||||
64 | } |
||||||||
65 | |||||||||
66 | try { |
||||||||
67 | return $this->toSelector($offset)->compatibleWith($this); |
||||||||
0 ignored issues
–
show
$this of type Smoren\ArrayView\Traits\ArrayViewAccessTrait is incompatible with the type Smoren\ArrayView\Interfaces\ArrayViewInterface expected by parameter $view of Smoren\ArrayView\Selecto...ector::compatibleWith() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() $this of type Smoren\ArrayView\Traits\ArrayViewAccessTrait is incompatible with the type Smoren\ArrayView\Interfaces\ArrayViewInterface expected by parameter $view of Smoren\ArrayView\Selecto...ector::compatibleWith() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() $this of type Smoren\ArrayView\Traits\ArrayViewAccessTrait is incompatible with the type Smoren\ArrayView\Interfaces\ArrayViewInterface expected by parameter $view of Smoren\ArrayView\Selecto...ector::compatibleWith() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
68 | } catch (KeyError $e) { |
||||||||
69 | return false; |
||||||||
70 | } |
||||||||
71 | } |
||||||||
72 | |||||||||
73 | /** |
||||||||
74 | * Get the value at the specified offset in the ArrayView object. |
||||||||
75 | * |
||||||||
76 | * ```php |
||||||||
77 | * $source = [1, 2, 3, 4, 5]; |
||||||||
78 | * $view = ArrayView::toView($source); |
||||||||
79 | * |
||||||||
80 | * $view[0]; // 1 |
||||||||
81 | * $view[-1]; // 5 |
||||||||
82 | * |
||||||||
83 | * $view[new SliceSelector('::2')]; // [1, 3, 5] |
||||||||
84 | * $view[new IndexListSelector([0, 2, 4])]; // [1, 3, 5] |
||||||||
85 | * $view[new MaskSelector([true, true, false, false, true])]; // [1, 2, 5] |
||||||||
86 | * |
||||||||
87 | * $view['::2']; // [1, 3, 5] |
||||||||
88 | * $view[[0, 2, 4]]; // [1, 3, 5] |
||||||||
89 | * $view[[true, true, false, false, true]]; // [1, 2, 5] |
||||||||
90 | * ``` |
||||||||
91 | * |
||||||||
92 | * @param numeric|S $offset The offset to get the value at. |
||||||||
93 | * |
||||||||
94 | * @return T|array<T> The value at the specified offset. |
||||||||
95 | * |
||||||||
96 | * @throws IndexError if the offset is out of range. |
||||||||
97 | * @throws KeyError if the key is invalid. |
||||||||
98 | * |
||||||||
99 | * {@inheritDoc} |
||||||||
100 | */ |
||||||||
101 | #[\ReturnTypeWillChange] |
||||||||
102 | public function offsetGet($offset) |
||||||||
103 | { |
||||||||
104 | if (\is_numeric($offset)) { |
||||||||
0 ignored issues
–
show
|
|||||||||
105 | if (!$this->numericOffsetExists($offset)) { |
||||||||
106 | throw new IndexError("Index {$offset} is out of range."); |
||||||||
107 | } |
||||||||
108 | return $this->source[$this->convertIndex(\intval($offset))]; |
||||||||
109 | } |
||||||||
110 | |||||||||
111 | return $this->subview($this->toSelector($offset))->toArray(); |
||||||||
0 ignored issues
–
show
It seems like
subview() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
112 | } |
||||||||
113 | |||||||||
114 | /** |
||||||||
115 | * Set the value at the specified offset in the ArrayView object. |
||||||||
116 | * |
||||||||
117 | * ```php |
||||||||
118 | * $source = [1, 2, 3, 4, 5]; |
||||||||
119 | * $view = ArrayView::toView($source); |
||||||||
120 | * |
||||||||
121 | * $view[0] = 11; |
||||||||
122 | * $view[-1] = 55; |
||||||||
123 | * |
||||||||
124 | * $source; // [11, 2, 3, 4, 55] |
||||||||
125 | * |
||||||||
126 | * $source = [1, 2, 3, 4, 5]; |
||||||||
127 | * $view = ArrayView::toView($source); |
||||||||
128 | * |
||||||||
129 | * $view[new SliceSelector('::2')] = [11, 33, 55]; |
||||||||
130 | * $source; // [11, 2, 33, 4, 55] |
||||||||
131 | * |
||||||||
132 | * $view[new IndexListSelector([1, 3])] = [22, 44]; |
||||||||
133 | * $source; // [11, 22, 33, 44, 55] |
||||||||
134 | * |
||||||||
135 | * $view[new MaskSelector([true, false, false, false, true])] = [111, 555]; |
||||||||
136 | * $source; // [111, 22, 33, 44, 555] |
||||||||
137 | * |
||||||||
138 | * $source = [1, 2, 3, 4, 5]; |
||||||||
139 | * $view = ArrayView::toView($source); |
||||||||
140 | * |
||||||||
141 | * $view['::2'] = [11, 33, 55]; |
||||||||
142 | * $source; // [11, 2, 33, 4, 55] |
||||||||
143 | * |
||||||||
144 | * $view[[1, 3]] = [22, 44]; |
||||||||
145 | * $source; // [11, 22, 33, 44, 55] |
||||||||
146 | * |
||||||||
147 | * $view[[true, false, false, false, true]] = [111, 555]; |
||||||||
148 | * $source; // [111, 22, 33, 44, 555] |
||||||||
149 | * ``` |
||||||||
150 | * |
||||||||
151 | * @param numeric|S $offset The offset to set the value at. |
||||||||
152 | * @param T|array<T>|ArrayViewInterface<T> $value The value to set. |
||||||||
0 ignored issues
–
show
The type
Smoren\ArrayView\Traits\T was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||||||
153 | * |
||||||||
154 | * @return void |
||||||||
155 | * |
||||||||
156 | * @throws IndexError if the offset is out of range. |
||||||||
157 | * @throws KeyError if the key is invalid. |
||||||||
158 | * @throws ReadonlyError if the object is readonly. |
||||||||
159 | * |
||||||||
160 | * {@inheritDoc} |
||||||||
161 | */ |
||||||||
162 | public function offsetSet($offset, $value): void |
||||||||
163 | { |
||||||||
164 | if ($this->isReadonly()) { |
||||||||
0 ignored issues
–
show
It seems like
isReadonly() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
165 | throw new ReadonlyError("Cannot modify a readonly view."); |
||||||||
166 | } |
||||||||
167 | |||||||||
168 | if (!\is_numeric($offset)) { |
||||||||
0 ignored issues
–
show
|
|||||||||
169 | $this->subview($this->toSelector($offset))->set($value); |
||||||||
170 | return; |
||||||||
171 | } |
||||||||
172 | |||||||||
173 | if (!$this->numericOffsetExists($offset)) { |
||||||||
174 | throw new IndexError("Index {$offset} is out of range."); |
||||||||
175 | } |
||||||||
176 | |||||||||
177 | // @phpstan-ignore-next-line |
||||||||
178 | $this->source[$this->convertIndex(\intval($offset))] = $value; |
||||||||
179 | } |
||||||||
180 | |||||||||
181 | /** |
||||||||
182 | * Unset the value at the specified offset in the array-like object. |
||||||||
183 | * |
||||||||
184 | * @param numeric|S $offset The offset to unset the value at. |
||||||||
185 | * |
||||||||
186 | * @return void |
||||||||
187 | * |
||||||||
188 | * @throws NotSupportedError always. |
||||||||
189 | * |
||||||||
190 | * {@inheritDoc} |
||||||||
191 | */ |
||||||||
192 | public function offsetUnset($offset): void |
||||||||
0 ignored issues
–
show
The parameter
$offset is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||||
193 | { |
||||||||
194 | throw new NotSupportedError(); |
||||||||
195 | } |
||||||||
196 | |||||||||
197 | /** |
||||||||
198 | * Converts array to selector. |
||||||||
199 | * |
||||||||
200 | * @param S $input value to convert. |
||||||||
201 | * |
||||||||
202 | * @return ArraySelectorInterface |
||||||||
203 | */ |
||||||||
204 | protected function toSelector($input): ArraySelectorInterface |
||||||||
205 | { |
||||||||
206 | if ($input instanceof ArraySelectorInterface) { |
||||||||
207 | return $input; |
||||||||
208 | } |
||||||||
209 | |||||||||
210 | if (\is_string($input) && Slice::isSlice($input)) { |
||||||||
211 | return new SliceSelector($input); |
||||||||
212 | } |
||||||||
213 | |||||||||
214 | if ($input instanceof ArrayViewInterface) { |
||||||||
215 | $input = $input->toArray(); |
||||||||
216 | } |
||||||||
217 | |||||||||
218 | if (!\is_array($input) || !Util::isArraySequential($input)) { |
||||||||
219 | $strOffset = \is_scalar($input) ? \strval($input) : \gettype($input); |
||||||||
220 | throw new KeyError("Invalid key: \"{$strOffset}\"."); |
||||||||
221 | } |
||||||||
222 | |||||||||
223 | if (\count($input) > 0 && \is_bool($input[0])) { |
||||||||
224 | /** @var array<bool> $input */ |
||||||||
225 | return new MaskSelector($input); |
||||||||
226 | } |
||||||||
227 | |||||||||
228 | /** @var array<int> $input */ |
||||||||
229 | return new IndexListSelector($input); |
||||||||
230 | } |
||||||||
231 | } |
||||||||
232 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths