Completed
Push — master ( 8bff4b...55715d )
by Arnold
07:14
created

DotKey::onCopy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
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 $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 125
    public function __construct(&$subject, int $opts = 0)
29
    {
30 125
        if (!\is_object($subject) && !\is_array($subject)) {
31 1
            $type = \gettype($subject);
32 1
            throw new \InvalidArgumentException("Subject should be an array or object; $type given");
33
        }
34
35 124
        $this->subject =& $subject;
36 124
        $this->copy = (bool)($opts & self::COPY);
37 124
    }
38
39
40
    /**
41
     * Check if path exists in subject.
42
     */
43 10
    public function exists(string $path, string $delimiter = '.'): bool
44
    {
45 10
        return Internal\Read::exists($this->subject, $path, $delimiter);
46
    }
47
48
    /**
49
     * Get a value from subject by path.
50
     *
51
     * @param string $path
52
     * @param string $delimiter
53
     * @return mixed
54
     * @throws ResolveException
55
     */
56 19
    public function get(string $path, string $delimiter = '.')
57
    {
58 19
        return Internal\Read::get($this->subject, $path, $delimiter);
59
    }
60
61
62
    /**
63
     * Set a value within the subject by path.
64
     *
65
     * @param string $path
66
     * @param mixed  $value
67
     * @param string $delimiter
68
     * @throws ResolveException
69
     */
70 26
    public function set(string $path, $value, string $delimiter = '.'): void
71
    {
72 26
        if ($this->copy && Internal\Read::same($this->subject, $path, $delimiter, $value)) {
73 2
            return;
74
        }
75
76 24
        Internal\Set::apply($this->subject, $path, $value, $delimiter, $this->copy);
77 10
    }
78
79
    /**
80
     * Set a value, creating a structure if needed.
81
     *
82
     * @param string    $path
83
     * @param mixed     $value
84
     * @param string    $delimiter
85
     * @param bool|null $assoc     Create new structure as array. Omit to base upon subject type.
86
     * @throws ResolveException
87
     */
88 35
    public function put(string $path, $value, string $delimiter = '.', ?bool $assoc = null): void
89
    {
90 35
        if ($this->copy && Internal\Read::same($this->subject, $path, $delimiter, $value)) {
91 1
            return;
92
        }
93
94 34
        $assoc ??= is_array($this->subject) || $this->subject instanceof \ArrayAccess;
95
96 34
        Internal\Put::apply($this->subject, $path, $value, $delimiter, $assoc, $this->copy);
97 30
    }
98
99
    /**
100
     * Get a particular value back from the config array
101
     *
102
     * @param string $path
103
     * @param string $delimiter
104
     */
105 34
    public function remove(string $path, string $delimiter = '.'): void
106
    {
107 34
        if ($this->copy && !Internal\Read::exists($this->subject, $path, $delimiter)) {
108 4
            return;
109
        }
110
111 30
        Internal\Remove::apply($this->subject, $path, $delimiter, $this->copy);
112 21
    }
113
114
115
    /**
116
     * Factory method.
117
     *
118
     * @param object|array<string,mixed> $subject
119
     * @return static
120
     */
121 105
    public static function on(&$subject): self
122
    {
123 105
        return new static($subject);
124
    }
125
126
    /**
127
     * Factory method.
128
     *
129
     * @param object|array<string,mixed> $source
130
     * @param mixed                      $copy
131
     * @return static
132
     */
133 20
    public static function onCopy($source, &$copy): self
134
    {
135 20
        $copy = $source;
136
137 20
        return new static($copy, self::COPY);
138
    }
139
}
140