Set::apply()   B
last analyzed

Complexity

Conditions 9
Paths 15

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 20
c 1
b 0
f 0
dl 0
loc 33
ccs 19
cts 19
cp 1
rs 8.0555
cc 9
nc 15
nop 5
crap 9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\DotKey\Internal;
6
7
use Jasny\DotKey\ResolveException;
8
9
/**
10
 * Static class with get and put methods.
11
 * @internal
12
 */
13
final class Set
14
{
15
    /**
16
     * Set a value within the subject by path.
17
     *
18
     * @param object|array<string,mixed> $subject
19
     * @param string                     $path
20
     * @param mixed                      $value
21
     * @param string                     $delimiter
22
     * @param bool                       $copy
23
     * @throws ResolveException
24
     */
25 30
    public static function apply(&$subject, string $path, $value, string $delimiter, bool $copy): void
26
    {
27 30
        $current =& $subject;
28 30
        $index = Helpers::splitPath($path, $delimiter);
29
30 29
        while (count($index) > 1) {
31 28
            if (!\is_array($current) && !\is_object($current)) {
32 5
                $msg = "Unable to set '$path': '%s' is of type " . \gettype($current);
33 5
                throw ResolveException::create($msg, $path, $delimiter, $index);
34
            }
35
36 28
            $key = \array_shift($index);
37
38
            try {
39 28
                $current =& Helpers::descend($current, $key, $exists, false, $copy);
40 1
            } catch (\Error $error) {
41 1
                $msg = "Unable to set '$path': error at '%s'";
42 1
                throw ResolveException::create($msg, $path, $delimiter, $index, $error);
43
            }
44
45 27
            if (!$exists) {
46 5
                throw ResolveException::create("Unable to set '$path': '%s' doesn't exist", $path, $delimiter, $index);
47
            }
48
        }
49
50
        try {
51 18
            if ($copy && is_object($current)) {
52 4
                $current = clone $current;
53
            }
54
55 18
            self::setValue($current, $index[0], $value);
56 2
        } catch (\Error $error) {
57 2
            throw new ResolveException("Unable to set '$path': error at '$path'", 0, $error);
58
        }
59
    }
60
61
    /**
62
     * Set the value of a property or key.
63
     *
64
     * @param object|array<string,mixed> $target
65
     * @param string                     $key
66
     * @param mixed                      $value
67
     */
68 18
    protected static function setValue(&$target, string $key, $value): void
69
    {
70 18
        if (\is_array($target) || $target instanceof \ArrayAccess) {
71 13
            $target[$key] = $value;
72
        } else {
73 7
            $target->{$key} = $value;
74
        }
75
    }
76
}
77