Completed
Push — master ( c1d6b3...c06cd7 )
by Viacheslav
01:46
created

JsonProcessor::arrayKeyExists()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 2
dl 0
loc 12
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace Swaggest\JsonDiff;
4
5
6
class JsonProcessor
7
{
8
    public static function pushByPath(&$holder, $path, $value)
9
    {
10
        $pathItems = explode('/', $path);
11
        if ('#' === $pathItems[0]) {
12
            array_shift($pathItems);
13
        }
14
        $ref = &$holder;
15
        while (null !== $key = array_shift($pathItems)) {
16
            if (is_string($key)) {
17
                $key = urldecode($key);
18
            }
19
            if ($ref instanceof \stdClass) {
20
                $ref = &$ref->$key;
21
            } elseif ($ref === null
22
                && !is_int($key)
23
                && false === filter_var($key, FILTER_VALIDATE_INT)
24
            ) {
25
                $key = (string)$key;
26
                $ref = new \stdClass();
27
                $ref = &$ref->{$key};
28
            } else {
29
                $ref = &$ref[$key];
30
            }
31
        }
32
        $ref = $value;
33
    }
34
35
    private static function arrayKeyExists($key, array $a)
36
    {
37
        if (array_key_exists($key, $a)) {
38
            return true;
39
        }
40
        $key = (string)$key;
41
        foreach ($a as $k => $v) {
42
            if ((string)$k === $key) {
43
                return true;
44
            }
45
        }
46
        return false;
47
    }
48
49
    private static function arrayGet($key, array $a)
50
    {
51
        $key = (string)$key;
52
        foreach ($a as $k => $v) {
53
            if ((string)$k === $key) {
54
                return $v;
55
            }
56
        }
57
        return false;
58
    }
59
60
61
    public static function getByPath($holder, $path)
62
    {
63
        $pathItems = explode('/', $path);
64
        if ('#' === $pathItems[0]) {
65
            array_shift($pathItems);
66
        }
67
        $ref = $holder;
68
        while (null !== $key = array_shift($pathItems)) {
69
            $key = urldecode($key);
70
            if ($ref instanceof \stdClass) {
71
                $vars = (array)$ref;
72
                if (self::arrayKeyExists($key, $vars)) {
73
                    $ref = self::arrayGet($key, $vars);
74
                } else {
75
                    throw new Exception('Key not found: ' . $key);
76
                }
77
            } else {
78
                if (self::arrayKeyExists($key, $ref)) {
0 ignored issues
show
Bug introduced by
It seems like $ref can also be of type false; however, parameter $a of Swaggest\JsonDiff\JsonProcessor::arrayKeyExists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

78
                if (self::arrayKeyExists($key, /** @scrutinizer ignore-type */ $ref)) {
Loading history...
79
                    $ref = $ref[$key];
80
                } else {
81
                    throw new Exception('Key not found: ' . $key);
82
                }
83
            }
84
        }
85
        return $ref;
86
    }
87
88
    public static function removeByPath(&$holder, $path)
89
    {
90
        $pathItems = explode('/', $path);
91
        if ('#' === $pathItems[0]) {
92
            array_shift($pathItems);
93
        }
94
        $ref = &$holder;
95
        while (null !== $key = array_shift($pathItems)) {
96
            $parent = &$ref;
97
            $key = urldecode($key);
98
            $refKey = $key;
99
            if ($ref instanceof \stdClass) {
100
                if (property_exists($ref, $key)) {
101
                    $ref = &$ref->$key;
102
                } else {
103
                    throw new Exception('Key not found: ' . $key);
104
                }
105
            } else {
106
                if (array_key_exists($key, $ref)) {
107
                    $ref = &$ref[$key];
108
                } else {
109
                    throw new Exception('Key not found: ' . $key);
110
                }
111
            }
112
        }
113
114
        if (isset($parent) && isset($refKey)) {
115
            if ($parent instanceof \stdClass) {
116
                unset($parent->$refKey);
117
            } else {
118
                unset($parent[$refKey]);
119
            }
120
        }
121
        return $ref;
122
    }
123
}