Issues (4)

src/ObjectNode.php (1 issue)

Severity
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
$value is always a sub-type of DaveRandom\Jom\Node.
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