Smoren /
array-view-php
| 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 Loading history...
|
|||||||||
| 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
Loading history...
$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
Loading history...
$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
Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 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 Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 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. Loading history...
|
|||||||||
| 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