Node::getKey()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 1
1
<?php declare(strict_types=1);
2
3
namespace DaveRandom\Jom;
4
5
use DaveRandom\Jom\Exceptions\InvalidNodeValueException;
6
use DaveRandom\Jom\Exceptions\InvalidReferenceNodeException;
7
8
abstract class Node implements \JsonSerializable, Taggable
9
{
10
    use TagData;
11
12
    public const IGNORE_INVALID_VALUES = 0b01;
13
    public const PERMIT_INCORRECT_REFERENCE_TYPE = 0b10;
14
15
    /** @var NodeFactory */
16
    private static $nodeFactory;
17
18
    /** @var Document|null */
19
    protected $ownerDocument;
20
21
    /** @var string|int|null */
22
    protected $key;
23
24
    /** @var VectorNode|null */
25
    protected $parent;
26
27
    /** @var Node|null */
28
    protected $previousSibling;
29
30
    /** @var Node|null */
31
    protected $nextSibling;
32
33
    /** @uses __init() */
34 1
    private static function __init(): void
35
    {
36 1
        self::$nodeFactory = new UnsafeNodeFactory();
37
    }
38
39
    /**
40
     * @param mixed $value
41
     * @throws InvalidNodeValueException
42
     */
43 37
    private static function validateCreatedNodeType(Node $node, string $expectedType, $value, ?int $flags): Node
44
    {
45 37
        if ($node instanceof $expectedType || ($flags & self::PERMIT_INCORRECT_REFERENCE_TYPE)) {
46 37
            return $node;
47
        }
48
49
        throw new InvalidNodeValueException(\sprintf(
50
            "Value of type %s parsed as instance of %s, instance of %s expected",
51
            describe($value),
52
            \get_class($node),
53
            $expectedType
54
        ));
55
    }
56
57
    /**
58
     * @param bool|int|float|string|array|object|null A value that can be encoded as JSON
59
     * @throws InvalidNodeValueException
60
     * @return static
61
     */
62 37
    public static function createFromValue($value, ?Document $ownerDocument = null, ?int $flags = 0): Node
63
    {
64
        try {
65 37
            $result = self::$nodeFactory->createNodeFromValue($value, $ownerDocument, $flags ?? 0);
66
        } catch (InvalidNodeValueException $e) {
67
            throw $e;
68
        //@codeCoverageIgnoreStart
69
        } catch (\Exception $e) {
70
            throw unexpected($e);
71
        }
72
        //@codeCoverageIgnoreEnd
73
74 37
        return self::validateCreatedNodeType($result, static::class, $value, $flags);
75
    }
76
77 165
    protected function __construct(?Document $ownerDocument)
78
    {
79 165
        $this->ownerDocument = $ownerDocument;
80
    }
81
82
    public function __clone()
83
    {
84
        $this->setReferences(null, null, null, null);
85
    }
86
87 151
    final protected function setReferences(?VectorNode $parent, $key, ?Node $previousSibling, ?Node $nextSibling): void
88
    {
89 151
        $this->parent = $parent;
90 151
        $this->key = $key;
91 151
        $this->previousSibling = $previousSibling;
92 151
        $this->nextSibling = $nextSibling;
93
    }
94
95 47
    final public function getParent(): ?VectorNode
96
    {
97 47
        return $this->parent;
98
    }
99
100 7
    final public function getPreviousSibling(): ?Node
101
    {
102 7
        return $this->previousSibling;
103
    }
104
105 7
    final public function getNextSibling(): ?Node
106
    {
107 7
        return $this->nextSibling;
108
    }
109
110
    public function hasChildren(): bool
111
    {
112
        return false;
113
    }
114
115
    public function containsChild(Node $child): bool
116
    {
117
        return $child !== $child;
118
    }
119
120
    public function getFirstChild(): ?Node
121
    {
122
        return null;
123
    }
124
125
    public function getLastChild(): ?Node
126
    {
127
        return null;
128
    }
129
130 49
    final public function getOwnerDocument(): ?Document
131
    {
132 49
        return $this->ownerDocument;
133
    }
134
135
    /**
136
     * @return string|int|null
137
     */
138 50
    final public function getKey()
139
    {
140 50
        return $this->key;
141
    }
142
143
    /**
144
     * @return Node[]
145
     * @throws InvalidReferenceNodeException
146
     */
147 11
    final public function getAncestors(?Node $root = null): array
148
    {
149 11
        $path = [$this];
150 11
        $current = $this->parent;
151 11
        $rootParent = $root !== null
152 11
            ? $root->parent
153 11
            : null;
154
155 11
        while ($current !== $rootParent && $current !== null) {
156 9
            $path[] = $current;
157 9
            $current = $current->parent;
158
        }
159
160 11
        if ($current !== $rootParent) {
161
            throw new InvalidReferenceNodeException('Path target node is not an ancestor of the subject node');
162
        }
163
164 11
        return $path;
165
    }
166
167
    abstract public function getValue();
168
    abstract public function jsonSerialize();
169
}
170
171
\DaveRandom\Jom\initialize(Node::class);
172