DotKey::on()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\DotKey;
6
7
/**
8
 * Access objects and arrays through dot notation.
9
 */
10
class DotKey
11
{
12
    public const COPY = 0b1;
13
14
    /**
15
     * @var object|array<string,mixed>
16
     */
17
    protected object|array $subject;
18
19
    protected bool $copy;
20
21
22
    /**
23
     * Class constructor.
24
     *
25
     * @param object|array<string,mixed> $subject
26
     * @param int                        $opts     Binary set of options
27
     */
28 134
    public function __construct(array|object &$subject, int $opts = 0)
29
    {
30 134
        $this->subject =& $subject;
31 134
        $this->copy = (bool)($opts & self::COPY);
32
    }
33
34
35
    /**
36
     * Check if path exists in subject.
37
     */
38 10
    public function exists(string $path, string $delimiter = '.'): bool
39
    {
40 10
        return Internal\Read::exists($this->subject, $path, $delimiter);
41
    }
42
43
    /**
44
     * Get a value from subject by path.
45
     *
46
     * @throws ResolveException
47
     */
48 21
    public function get(string $path, string $delimiter = '.'): mixed
49
    {
50 21
        return Internal\Read::get($this->subject, $path, $delimiter);
51
    }
52
53
54
    /**
55
     * Set a value within the subject by path.
56
     *
57
     * @throws ResolveException
58
     */
59 34
    public function set(string $path, mixed $value, string $delimiter = '.'): void
60
    {
61 34
        if ($this->copy && Internal\Read::same($this->subject, $path, $delimiter, $value)) {
62 4
            return;
63
        }
64
65 30
        Internal\Set::apply($this->subject, $path, $value, $delimiter, $this->copy);
66
    }
67
68
    /**
69
     * Set a value, creating a structure if needed.
70
     *
71
     * @throws ResolveException
72
     */
73 37
    public function put(string $path, mixed $value, string $delimiter = '.', ?bool $assoc = null): void
74
    {
75 37
        if ($this->copy && Internal\Read::same($this->subject, $path, $delimiter, $value)) {
76 1
            return;
77
        }
78
79 36
        $assoc ??= is_array($this->subject) || $this->subject instanceof \ArrayAccess;
80
81 36
        Internal\Put::apply($this->subject, $path, $value, $delimiter, $assoc, $this->copy);
82
    }
83
84
    /**
85
     * Get a particular value back from the config array
86
     */
87 34
    public function remove(string $path, string $delimiter = '.'): void
88
    {
89 34
        if ($this->copy && !Internal\Read::exists($this->subject, $path, $delimiter)) {
90 4
            return;
91
        }
92
93 30
        Internal\Remove::apply($this->subject, $path, $delimiter, $this->copy);
94
    }
95
96
    /**
97
     * Update a value within the subject by path.
98
     *
99
     * @throws ResolveException
100
     */
101 2
    public function update(string $path, callable $callback, string $delimiter = '.'): void
102
    {
103 2
        $value = $this->get($path, $delimiter);
104 2
        $this->set($path, $callback($value), $delimiter);
105
    }
106
107
108
    /**
109
     * Factory method.
110
     *
111
     * @param object|array<string,mixed> $subject
112
     * @return static
113
     */
114 110
    public static function on(array|object &$subject): self
115
    {
116 110
        return new static($subject);
117
    }
118
119
    /**
120
     * Factory method.
121
     *
122
     * @param object|array<string,mixed> $source
123
     * @param mixed                      $copy
124
     * @return static
125
     */
126 24
    public static function onCopy(array|object $source, mixed &$copy): self
127
    {
128 24
        $copy = $source;
129
130 24
        return new static($copy, self::COPY);
131
    }
132
}
133