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 | 64 | public function __construct(?array $properties = [], ?Document $ownerDocument = null) |
|
15 | { |
||
16 | 64 | parent::__construct($ownerDocument); |
|
17 | |||
18 | try { |
||
19 | 64 | foreach ($properties ?? [] as $name => $node) { |
|
20 | 64 | $this->setProperty((string)$name, $node); |
|
21 | } |
||
22 | } catch (InvalidSubjectNodeException $e) { |
||
23 | throw $e; |
||
24 | //@codeCoverageIgnoreStart |
||
25 | } catch (\Exception $e) { |
||
26 | throw unexpected($e); |
||
27 | } |
||
28 | //@codeCoverageIgnoreEnd |
||
29 | } |
||
30 | |||
31 | /** |
||
32 | * @return string[] |
||
33 | */ |
||
34 | public function getPropertyNames(): array |
||
35 | { |
||
36 | return \array_keys($this->children); |
||
37 | } |
||
38 | |||
39 | public function hasProperty(string $name): bool |
||
40 | { |
||
41 | return isset($this->children[$name]); |
||
42 | } |
||
43 | |||
44 | /** |
||
45 | * @throws InvalidKeyException |
||
46 | */ |
||
47 | 52 | public function getProperty(string $name): Node |
|
48 | { |
||
49 | 52 | if (!isset($this->children[$name])) { |
|
50 | 2 | throw new InvalidKeyException("Property '{$name}' does not exist on the object"); |
|
51 | } |
||
52 | |||
53 | 51 | return $this->children[$name]; |
|
54 | } |
||
55 | |||
56 | /** |
||
57 | * @throws InvalidSubjectNodeException |
||
58 | * @throws WriteOperationForbiddenException |
||
59 | */ |
||
60 | 64 | public function setProperty(string $name, Node $value): void |
|
61 | { |
||
62 | 64 | if (!isset($this->children[$name])) { |
|
63 | 64 | $this->appendNode($value, $name); |
|
64 | 64 | return; |
|
65 | } |
||
66 | |||
67 | try { |
||
68 | $this->replaceNode($value, $this->children[$name]); |
||
69 | } catch (WriteOperationForbiddenException | InvalidSubjectNodeException $e) { |
||
70 | throw $e; |
||
71 | //@codeCoverageIgnoreStart |
||
72 | } catch (\Exception $e) { |
||
73 | throw unexpected($e); |
||
74 | } |
||
75 | //@codeCoverageIgnoreEnd |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * @param Node|string $nodeOrName |
||
80 | * @throws InvalidSubjectNodeException |
||
81 | * @throws WriteOperationForbiddenException |
||
82 | * @throws InvalidKeyException |
||
83 | */ |
||
84 | public function removeProperty($nodeOrName): void |
||
85 | { |
||
86 | $this->removeNode($this->resolveNode($nodeOrName)); |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * @param string $propertyName |
||
91 | * @return Node |
||
92 | * @throws InvalidKeyException |
||
93 | */ |
||
94 | 49 | public function offsetGet($propertyName): Node |
|
95 | { |
||
96 | 49 | return $this->getProperty((string)$propertyName); |
|
97 | } |
||
98 | |||
99 | /** |
||
100 | * @param string $propertyName |
||
101 | * @param Node $value |
||
102 | * @throws InvalidSubjectNodeException |
||
103 | * @throws WriteOperationForbiddenException |
||
104 | */ |
||
105 | public function offsetSet($propertyName, $value): void |
||
106 | { |
||
107 | if (!($value instanceof Node)) { |
||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
108 | throw new \TypeError('Child must be instance of ' . Node::class); |
||
109 | } |
||
110 | |||
111 | $this->setProperty((string)$propertyName, $value); |
||
112 | } |
||
113 | |||
114 | public function getValue(): \stdClass |
||
115 | { |
||
116 | $result = new \stdClass; |
||
117 | |||
118 | foreach ($this as $name => $value) { |
||
119 | $result->{$name} = $value->getValue(); |
||
120 | } |
||
121 | |||
122 | return $result; |
||
123 | } |
||
124 | |||
125 | public function toArray(): array |
||
126 | { |
||
127 | $result = []; |
||
128 | |||
129 | foreach ($this as $name => $value) { |
||
130 | $result[$name] = $value instanceof VectorNode |
||
131 | ? $value->toArray() |
||
132 | : $value->getValue(); |
||
133 | } |
||
134 | |||
135 | return $result; |
||
136 | } |
||
137 | } |
||
138 |