ExtendedArguments   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 26
eloc 53
c 2
b 0
f 1
dl 0
loc 104
ccs 62
cts 62
cp 1
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A append() 0 6 1
A extract() 0 7 2
A __construct() 0 5 2
A flatten() 0 16 3
A has() 0 15 5
A set() 0 16 6
A get() 0 3 1
A delete() 0 18 6
1
<?php declare(strict_types=1);
2
3
/*
4
 * This file is part of the Koded package.
5
 *
6
 * (c) Mihail Binev <[email protected]>
7
 *
8
 * Please view the LICENSE distributed with this source code
9
 * for the full copyright and license information.
10
 */
11
12
namespace Koded\Stdlib;
13
14
use RecursiveArrayIterator;
15
use RecursiveIteratorIterator;
16
use function array_key_exists;
17
use function array_push;
18
use function array_slice;
19
use function explode;
20
use function is_array;
21
use function is_string;
22
use function join;
23
use function str_contains;
24
25
/**
26
 * Class ExtendedArguments
27
 *
28
 * - NULL key is not supported; also it doesn't make sense
29
 * - boolean is a wrong type for the key; do not use a boolean key (it's juggled into a string)
30
 *
31
 * Use string values for the keys and you'll be golden.
32
 *
33
 * @property array $data
34
 */
35
36
#[\AllowDynamicProperties]
37
class ExtendedArguments extends Arguments
38
{
39 11
    public function __construct(protected array $data = [])
40
    {
41 11
        $this->data = [];
42 11
        foreach ($data as $index => $value) {
43 10
            $this->set($index, $value);
44
        }
45
    }
46
47 6
    public function get(string $index, mixed $default = null): mixed
48
    {
49 6
        return $this->find($index, $default);
50
    }
51
52 11
    public function set(mixed $index, mixed $value): static
53
    {
54 11
        if (is_string($index) && false === str_contains($index, '.')) {
55 11
            return parent::set($index, $value);
0 ignored issues
show
Bug Best Practice introduced by
The expression return parent::set($index, $value) returns the type Koded\Stdlib\Arguments which includes types incompatible with the type-hinted return Koded\Stdlib\ExtendedArguments.
Loading history...
56
        }
57 7
        $data =& $this->data;
58 7
        foreach (explode('.', (string)$index) as $i) {
59 7
            if (false === array_key_exists($i, $data) ||
60 7
                false === is_array($data[$i])
61
            ) {
62 7
                $data[$i] = [];
63
            }
64 7
            $data =& $data[$i];
65
        }
66 7
        $data = $value;
67 7
        return $this;
68
    }
69
70 1
    public function append(string $index, mixed $value): static
71
    {
72 1
        $partial = (array)$this->get($index);
73 1
        array_push($partial, $value);
74 1
        $this->set($index, $partial);
75 1
        return $this;
76
    }
77
78 3
    public function has(string $index): bool
79
    {
80 3
        if (false === str_contains($index, '.')) {
81 3
            return array_key_exists($index, $this->data);
82
        }
83 3
        $data =& $this->data;
84 3
        foreach (explode('.', $index) as $i) {
85 3
            if (false === is_array($data) ||
86 3
                false === array_key_exists($i, $data)
87
            ) {
88 1
                return false;
89
            }
90 3
            $data =& $data[$i];
91
        }
92 3
        return true;
93
    }
94
95 2
    public function delete(string $index): static
96
    {
97 2
        if (false === str_contains($index, '.')) {
98 1
            return parent::delete($index);
0 ignored issues
show
Bug Best Practice introduced by
The expression return parent::delete($index) returns the type Koded\Stdlib\Arguments which includes types incompatible with the type-hinted return Koded\Stdlib\ExtendedArguments.
Loading history...
99
        }
100 2
        $data =& $this->data;
101 2
        foreach (explode('.', $index) as $i) {
102 2
            if (false === array_key_exists($i, $data) ||
103 2
                false === is_array($data[$i])
104
            ) {
105 2
                continue;
106
            }
107 1
            $data =& $data[$i];
108
        }
109 2
        if (isset($i)) {
110 2
            unset($data[$i]);
111
        }
112 2
        return $this;
113
    }
114
115 2
    public function extract(array $indexes): array
116
    {
117 2
        $found = [];
118 2
        foreach ($indexes as $index) {
119 2
            $found[$index] = $this->find($index);
120
        }
121 2
        return $found;
122
    }
123
124 2
    public function flatten(): static
125
    {
126 2
        $indexes = [];
127 2
        $flatten = [];
128 2
        $iterator = new RecursiveIteratorIterator(
129 2
            new RecursiveArrayIterator($this->data),
130 2
            RecursiveIteratorIterator::SELF_FIRST
131 2
        );
132 2
        foreach ($iterator as $index => $value) {
133 2
            $indexes[$iterator->getDepth()] = $index;
134 2
            if (false === is_array($value)) {
135 2
                $_ = join('.', array_slice($indexes, 0, $iterator->getDepth() + 1));
136 2
                $flatten[$_] = $value;
137
            }
138
        }
139 2
        return new static($flatten);
140
    }
141
}
142