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

Helpers::descend()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 12
c 1
b 0
f 0
nc 8
nop 4
dl 0
loc 18
ccs 11
cts 11
cp 1
crap 7
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\DotKey\Internal;
6
7
/**
8
 * Static class with helper functions.
9
 * @internal
10
 */
11
final class Helpers
12
{
13
    /**
14
     * Make subject a child of the subject.
15
     * If `$exists` is false, it wasn't possible to decent and subject is returned.
16
     *
17
     * @param object|array<string,mixed> $subject
18
     * @param string                     $key
19
     * @param mixed                      $exists      output as bool
20
     * @param bool                       $accessible  Check not only if property exists, but also is accessible.
21
     * @return mixed
22
     */
23 100
    public static function &descend(&$subject, string $key, &$exists, bool $accessible = false)
24
    {
25 100
        if (!\is_array($subject) && !$subject instanceof \ArrayAccess) {
26 28
            $exists = $accessible
27 3
                ? self::propertyIsAccessible($subject, $key)
28 28
                : \property_exists($subject, $key);
29
30 28
            if ($exists) {
31 28
                $subject =& $subject->{$key};
32
            }
33
        } else {
34 83
            $exists = \is_array($subject) ? \array_key_exists($key, $subject) : $subject->offsetExists($key);
35 83
            if ($exists) {
36 83
                $subject =& $subject[$key];
37
            }
38
        }
39
40 95
        return $subject;
41
    }
42
43
    /**
44
     * Check if property exists and is accessible.
45
     *
46
     * @param object $object
47
     * @param string $property
48
     * @return bool
49
     */
50 3
    public static function propertyIsAccessible(object $object, string $property): bool
51
    {
52 3
        $exists = \property_exists($object, $property);
53
54 3
        if (!$exists || isset($object->{$property})) {
55 2
            return $exists;
56
        }
57
58
        try {
59 2
            $reflection = new \ReflectionProperty($object, $property);
60
        } catch (\ReflectionException $exception) { // @codeCoverageIgnore
61
            return false;                           // @codeCoverageIgnore
62
        }
63
64 2
        return $reflection->isPublic() && !$reflection->isStatic();
65
    }
66
67
    /**
68
     * Explode with trimming and check.
69
     * @see explode()
70
     *
71
     * @param string $path
72
     * @param string $delimiter
73
     * @return string[]
74
     */
75 108
    public static function splitPath(string $path, string $delimiter): array
76
    {
77 108
        if ($delimiter === '') {
78 5
            throw new \InvalidArgumentException("Delimiter can't be an empty string");
79
        }
80
81
        /** @var array<int,string> $parts */
82 103
        $parts = \explode($delimiter, trim($path, $delimiter));
83
84 103
        return $parts;
85
    }
86
}
87