Completed
Pull Request — master (#4)
by
unknown
06:08
created

EnvironmentNode   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 1
dl 0
loc 169
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 3
A addChild() 0 6 1
B __get() 0 17 5
A setValue() 0 8 2
A setParent() 0 4 1
A toConfig() 0 11 3
A getFullKey() 0 11 3
A ensureValueOrChildren() 0 6 3
1
<?php
2
declare(strict_types = 1);
3
4
/**
5
 * Micro
6
 *
7
 * @author    Fabian Jucker <[email protected]>
8
 * @copyright Copyright (c) 2017 gyselroth GmbH (https://gyselroth.com)
9
 * @license   MIT https://opensource.org/licenses/MIT
10
 */
11
12
namespace Micro\Config\Environment;
13
14
use \Micro\Config;
15
16
class EnvironmentNode
17
{
18
    /**
19
     * ROOT_KEY
20
     *
21
     * @var string
22
     */
23
    public const ROOT_KEY = '';
24
25
    /**
26
     * Key
27
     *
28
     * @var string
29
     */
30
    private $key;
31
32
    /**
33
     * Value
34
     *
35
     * @var mixed
36
     */
37
    private $value;
38
39
    /**
40
     * Children
41
     *
42
     * @var EnvironmentNode[]
43
     */
44
    private $children;
45
46
    /**
47
     * Parent
48
     *
49
     * @var EnvironmentNode
50
     */
51
    private $parent;
52
53
    /**
54
     * Create tree node
55
     *
56
     * @param  string $key
57
     * @param  mixed $value
58
     * @param  EnvironmentNode[] $children
59
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
60
     */
61
    public function __construct(string $key, $value = null, $children = [])
62
    {
63
        self::ensureValueOrChildren($value, $children);
64
65
        $this->key = $key;
66
        $this->value = $value;
67
        $this->children = [];
68
        foreach ($children as $child) {
69
            if ($child instanceof EnvironmentNode) {
70
                $this->addChild($child);
71
            }
72
        }
73
    }
74
75
    /**
76
     * Add child node to node
77
     *
78
     * @param  EnvironmentNode $child
79
     * @return void
80
     */
81
    public function addChild(EnvironmentNode $child)
82
    {
83
        self::ensureValueOrChildren($this->value, [$child]);
84
        $child->setParent($this);
85
        $this->children[] = $child;
86
    }
87
88
    /**
89
     * Get entry
90
     *
91
     * @param  string $key
0 ignored issues
show
Bug introduced by
There is no parameter named $key. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
92
     * @return mixed
93
     */
94
    public function __get($name)
95
    {
96
        // return "native" properties directly
97
        if (property_exists($this, $name)) {
98
            return $this->$name;
99
        }
100
101
        // otherwise search for children named $name
102
        foreach ($this->children as $child) {
103
            if ($child->key === $name) {
104
                if ($child->value) {
105
                    return $child->value;
106
                }
107
                return $child;
108
            }
109
        }
110
    }
111
112
    /**
113
     * Set value of node
114
     *
115
     * @param  mixed $value
116
     * @return void
117
     */
118
    public function setValue($value)
119
    {
120
        self::ensureValueOrChildren($value, $this->children);
121
        if (count($this->children) > 0) {
122
            throw new Exception('either $value or $children can be set but not both');
123
        }
124
        $this->value = $value;
125
    }
126
127
    /**
128
     * Set parent of node
129
     *
130
     * @param  EnvironmentNode $parent
131
     * @return void
132
     */
133
    public function setParent(EnvironmentNode $parent)
134
    {
135
        $this->parent = $parent;
136
    }
137
138
    /**
139
     * Transform node recursively to a Config object
140
     *
141
     * @return mixed
142
     */
143
    public function toConfig()
144
    {
145
        if ($this->value) {
146
            return $this->value;
147
        }
148
        $config = new Config();
149
        foreach ($this->children as $child) {
150
            $config[$child->key] = $child->toConfig();
151
        }
152
        return $config;
153
    }
154
155
    /**
156
     * Gets the fully qualified key of the node
157
     *
158
     * @return string
159
     */
160
    public function getFullKey(): string
161
    {
162
        $keyparts = [$this->key];
163
        $parent = $this->parent;
164
        while ($parent && $parent->key !== self::ROOT_KEY) {
165
            $keyparts[] = $parent->key;
166
            $parent = $parent->parent;
167
        }
168
169
        return implode('_', array_reverse($keyparts));
170
    }
171
172
    /**
173
     * Ensures that a node has either a value or children, but not both
174
     *
175
     * @throws Exception
176
     * @return void
177
     */
178
    protected static function ensureValueOrChildren($value, array $children)
179
    {
180
        if ($value && count($children) > 0) {
181
            throw new Exception('A node can either have a value or children, but not both');
182
        }
183
    }
184
}
185