Completed
Push — master ( f400d6...2675c1 )
by Chris
02:17
created

ObjectNode::__construct()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 12
c 0
b 0
f 0
ccs 0
cts 11
cp 0
rs 9.2
cc 4
eloc 8
nc 4
nop 2
crap 20
1
<?php declare(strict_types=1);
2
3
namespace DaveRandom\Jom;
4
5
use DaveRandom\Jom\Exceptions\InvalidKeyException;
6
use DaveRandom\Jom\Exceptions\InvalidSubjectNodeException;
7
use DaveRandom\Jom\Exceptions\WriteOperationForbiddenException;
8
9
final class ObjectNode extends VectorNode
10
{
11
    /**
12
     * @throws InvalidSubjectNodeException
13
     */
14
    public function __construct(?array $properties = [], ?Document $ownerDocument = null)
15
    {
16
        parent::__construct($ownerDocument);
17
18
        try {
19
            foreach ($properties ?? [] as $name => $node) {
20
                $this->setProperty((string)$name, $node);
21
            }
22
        } catch (InvalidSubjectNodeException $e) {
23
            throw $e;
24
        } catch (\Exception $e) {
25
            throw new \Error('Unexpected ' . \get_class($e) . ": {$e->getMessage()}", 0, $e);
26
        }
27
    }
28
29
    /**
30
     * @return string[]
31
     */
32
    public function getPropertyNames(): array
33
    {
34
        return \array_keys($this->children);
35
    }
36
37
    public function hasProperty(string $name): bool
38
    {
39
        return isset($this->children[$name]);
40
    }
41
42
    /**
43
     * @throws InvalidKeyException
44
     */
45
    public function getProperty(string $name): Node
46
    {
47
        if (!isset($this->children[$name])) {
48
            throw new InvalidKeyException("Property '{$name}' does not exist on the object");
49
        }
50
51
        return $this->children[$name];
52
    }
53
54
    /**
55
     * @throws InvalidSubjectNodeException
56
     * @throws WriteOperationForbiddenException
57
     */
58
    public function setProperty(string $name, Node $value): void
59
    {
60
        if (!isset($this->children[$name])) {
61
            $this->appendNode($value, $name);
62
            return;
63
        }
64
65
        try {
66
            $this->replaceNode($value, $this->children[$name]);
67
        } catch (WriteOperationForbiddenException | InvalidSubjectNodeException $e) {
68
            throw $e;
69
        } catch (\Exception $e) {
70
            throw new \Error('Unexpected ' . \get_class($e) . ": {$e->getMessage()}", 0, $e);
71
        }
72
    }
73
74
    /**
75
     * @param Node|string $nodeOrName
76
     * @throws InvalidSubjectNodeException
77
     * @throws WriteOperationForbiddenException
78
     * @throws InvalidKeyException
79
     */
80
    public function removeProperty($nodeOrName): void
81
    {
82
        $this->removeNode($this->resolveNode($nodeOrName));
83
    }
84
85
    /**
86
     * @throws InvalidKeyException
87
     */
88
    public function offsetGet($propertyName): Node
89
    {
90
        return $this->getProperty((string)$propertyName);
91
    }
92
93
    /**
94
     * @throws InvalidSubjectNodeException
95
     * @throws WriteOperationForbiddenException
96
     */
97
    public function offsetSet($propertyName, $value): void
98
    {
99
        if (!($value instanceof Node)) {
100
            throw new \TypeError('Child must be instance of ' . Node::class);
101
        }
102
103
        $this->setProperty((string)$propertyName, $value);
104
    }
105
106
    public function getValue(): \stdClass
107
    {
108
        $result = new \stdClass;
109
110
        foreach ($this as $name => $value) {
111
            $result->$name = $value->getValue();
112
        }
113
114
        return $result;
115
    }
116
117
    public function toArray(): array
118
    {
119
        $result = [];
120
121
        foreach ($this as $value) {
122
            $result[] = $value instanceof VectorNode
123
                ? $value->toArray()
124
                : $value->getValue();
125
        }
126
127
        return $result;
128
    }
129
}
130