Completed
Push — master ( 33cd17...4bddcc )
by Arnold
02:40
created

Remove::remove()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 20
c 1
b 0
f 0
nc 7
nop 3
dl 0
loc 34
ccs 19
cts 19
cp 1
crap 7
rs 8.6666
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 to remove items from subject with path.
11
 * @internal
12
 */
13
final class Remove
14
{
15
    /**
16
     * Get a particular value back from the config array
17
     *
18
     * @param object|array<string,mixed> $subject
19
     * @param string                     $path
20
     * @param string                     $delimiter
21
     * @return object|array<string,mixed>
22
     *
23
     * @template TSubject
24
     * @phpstan-param TSubject&(object|array<string,mixed>) $subject
25
     * @phpstan-param string                                $path
26
     * @phpstan-param string                                $delimiter
27
     * @phpstan-return TSubject&(object|array<string,mixed>)
28
     */
29 26
    public static function remove($subject, string $path, string $delimiter = '.')
30
    {
31 26
        $result =& $subject;
32
33 26
        $index = Helpers::splitPath($path, $delimiter);
34
35 25
        while (\count($index) > 1) {
36 24
            $key = \array_shift($index);
37
38
            try {
39 24
                $subject =& Helpers::descend($subject, $key, $exists);
40 1
            } catch (\Error $error) {
41 1
                $msg = "Unable to remove '$path': error at '%s'";
42 1
                throw ResolveException::create($msg, $path, $delimiter, $index, null, $error);
43
            }
44
45 23
            if (!$exists) {
46 4
                return $result;
47
            }
48
49 23
            if (!\is_array($subject) && !\is_object($subject)) {
50 5
                $msg = "Unable to remove '$path': '%s' is of type " . \gettype($subject);
51 5
                throw ResolveException::create($msg, $path, $delimiter, $index);
52
            }
53
        }
54
55
        try {
56 15
            self::removeChild($subject, $index[0]);
57 2
        } catch (\Error $error) {
58 2
            $msg = "Unable to remove '$path': error at '%s'";
59 2
            throw ResolveException::create($msg, $path, $delimiter, array_slice($index, 0, -1), null, $error);
60
        }
61
62 13
        return $result;
63
    }
64
65
    /**
66
     * Remove item or property from subject.
67
     *
68
     * @param object|array<string,mixed> $subject
69
     * @param string                     $key
70
     */
71 15
    protected static function removeChild(&$subject, string $key): void
72
    {
73 15
        if (\is_array($subject)) {
74 8
            if (\array_key_exists($key, $subject)) {
75 8
                unset($subject[$key]);
76
            }
77 7
        } elseif ($subject instanceof \ArrayAccess) {
78 2
            if ($subject->offsetExists($key)) {
79 2
                unset($subject[$key]);
80
            }
81 5
        } elseif (\property_exists($subject, $key)) {
82 5
            unset($subject->{$key});
83
        }
84 13
    }
85
}
86