ChildMaintainance   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 205
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 10
Bugs 3 Features 5
Metric Value
wmc 31
c 10
b 3
f 5
lcom 1
cbo 1
dl 0
loc 205
rs 9.8

21 Methods

Rating   Name   Duplication   Size   Complexity  
A addHookGainChild() 0 7 2
A count() 0 4 1
A offsetExists() 0 4 1
A offsetGet() 0 4 1
A offsetSet() 0 14 4
A offsetUnset() 0 4 1
A getIterator() 0 4 1
A getRecursiveIterator() 0 17 4
A addChildInternal() 0 5 1
A addChildBeginning() 0 5 1
B gainChild() 0 13 5
A __clone() 0 6 2
A valid() 0 4 1
A hasChildren() 0 4 1
A next() 0 4 1
A current() 0 4 1
A getChildren() 0 4 1
A rewind() 0 4 1
A key() 0 4 1
isValidChild() 0 1 ?
getInheritableAppendages() 0 1 ?
1
<?php
2
3
namespace hemio\html\Trait_;
4
5
/**
6
 * Most required utils to implement elements that can have childs and
7
 * containers. Recomended implementation from most of
8
 * {@link MaintainsChilds} requirements.
9
 *
10
 * @uses MaintainsChilds ChildMaintainance is the recommended
11
 * implementation from most of MaintainsChilds requirements
12
 * @author Michael Herold <[email protected]>
13
 * @todo Cleanup
14
 */
15
trait ChildMaintainance
16
{
17
    /**
18
     * child elemnts of the element
19
     * @var array
20
     */
21
    private $arrChilds = [];
22
23
    /**
24
     *
25
     * @var array[callable]
26
     */
27
    protected $arrHooksGainChild = [];
28
29
    public function addHookGainChild(callable $hook, $idx = null)
30
    {
31
        if ($idx === null)
32
            $this->arrHooksGainChild[]     = $hook;
33
        else
34
            $this->arrHooksGainChild[$idx] = $hook;
35
    }
36
37
    /**
38
     *
39
     * @return integer
40
     */
41
    public function count()
42
    {
43
        return count($this->arrChilds);
44
    }
45
46
    /**
47
     *
48
     * @param mixed $offset
49
     * @return boolean
50
     */
51
    public function offsetExists($offset)
52
    {
53
        return array_key_exists($offset, $this->arrChilds);
54
    }
55
56
    /**
57
     *
58
     * @param mixed $offset
59
     * @return Interface_\HtmlCode
60
     */
61
    public function offsetGet($offset)
62
    {
63
        return $this->arrChilds[$offset];
64
    }
65
66
    /**
67
     *
68
     * @param mixed $offset
69
     * @param Interface_\HtmlCode $value
70
     */
71
    public function offsetSet($offset, $value)
72
    {
73
        if ($this->isValidChild($value) || $value instanceof \hemio\html\Nothing) {
74
            if ($offset === null)
75
                $this->arrChilds[]        = $value;
76
            else
77
                $this->arrChilds[$offset] = $value;
78
79
            $this->gainChild($value);
80
        } else {
81
            trigger_error('An instance of `'.get_class($value).
82
                '` is no valid child for `'.get_class($this).'`', E_USER_WARNING);
83
        }
84
    }
85
86
    /**
87
     *
88
     * @param type $offset
89
     */
90
    public function offsetUnset($offset)
91
    {
92
        unset($this->arrChilds[$offset]);
93
    }
94
95
    /**
96
     * Implements iteration
97
     *
98
     * @return \Traversable
99
     */
100
    public function getIterator()
101
    {
102
        return new \ArrayIterator($this->arrChilds);
103
    }
104
105
    /**
106
     *
107
     * @param callable $selectFilter
108
     * @return \Traversable
109
     */
110
    public function getRecursiveIterator(callable $selectFilter = null)
111
    {
112
        if ($selectFilter === null) {
113
            return new \RecursiveIteratorIterator($this,
114
                                                  \RecursiveIteratorIterator::SELF_FIRST);
115
        } else {
116
            $array = [];
117
118
            foreach ($this->getRecursiveIterator() as $child) {
119
                if ($selectFilter($child)) {
120
                    $array[] = $child;
121
                }
122
            }
123
124
            return new \ArrayIterator($array);
125
        }
126
    }
127
128
    /**
129
     *
130
     * @param \hemio\html\Interface_\HtmlCode $child
131
     * @return \hemio\html\Interface_\HtmlCode
132
     */
133
    protected function addChildInternal(\hemio\html\Interface_\HtmlCode $child)
134
    {
135
        $this[] = $child;
136
        return $child;
137
    }
138
139
    /**
140
     *
141
     * @param \hemio\html\Interface_\HtmlCode $child
142
     * @return \hemio\html\Interface_\HtmlCode
143
     */
144
    public function addChildBeginning(\hemio\html\Interface_\HtmlCode $child)
145
    {
146
        array_unshift($this->arrChilds, $child);
147
        return $child;
148
    }
149
150
    /**
151
     *
152
     * @param \hemio\html\Interface_\HtmlCode $child
153
     */
154
    protected function gainChild(\hemio\html\Interface_\HtmlCode $child)
155
    {
156
        foreach ($this->arrHooksGainChild as $hook) {
157
            $hook($this, $child);
158
        }
159
160
        if ($child instanceof \hemio\html\Abstract_\Element)
161
            $child->setParent($this);
162
163
        if ($child instanceof \hemio\html\Interface_\MaintainsAppendages)
164
            foreach ($this->getInheritableAppendages() as $appKey => $appValue)
165
                $child->leaveInheritableAppendage($appKey, $appValue);
166
    }
167
168
    public function __clone()
169
    {
170
        foreach ($this->arrChilds as $key => $child) {
171
            $this->arrChilds[$key] = clone $child;
172
        }
173
    }
174
175
    public function valid()
176
    {
177
        return current($this->arrChilds) !== false;
178
    }
179
180
    public function hasChildren()
181
    {
182
        return $this->current() instanceof \RecursiveIterator;
183
    }
184
185
    public function next()
186
    {
187
        next($this->arrChilds);
188
    }
189
190
    public function current()
191
    {
192
        return current($this->arrChilds);
193
    }
194
195
    public function getChildren()
196
    {
197
        return $this->current();
198
    }
199
200
    public function rewind()
201
    {
202
        reset($this->arrChilds);
203
    }
204
205
    public function key()
206
    {
207
        return key($this->arrChilds);
208
    }
209
210
    /**
211
     * Existence usually ensured via (@link \hemio\html\Interface_\MaintainsChilds)
212
     */
213
    abstract public function isValidChild(\hemio\html\Interface_\HtmlCode $child);
214
215
    /**
216
     * Existence usually ensured via (@link \hemio\html\Interface_\MaintainsAppendages)
217
     */
218
    abstract public function getInheritableAppendages();
219
}
220