Completed
Push — master ( 4fa9cb...c3dd31 )
by Nathan
02:40
created

Element::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
1
<?php
2
3
namespace NatePage\EasyHtmlElement;
4
5
use HtmlGenerator\HtmlTag;
6
use HtmlGenerator\Markup;
7
8
class Element implements ElementInterface
9
{
10
    /** @var string|null */
11
    protected $type;
12
13
    /** @var string|null */
14
    protected $text;
15
16
    /** @var array */
17
    protected $attributes;
18
19
    /** @var array */
20
    protected $extras;
21
22
    /** @var array */
23
    protected $children;
24
25
    /** @var ElementInterface */
26
    protected $parent;
27
28
    public function __construct(
29
        $type = null,
30
        $text = null,
31
        array $attributes = array(),
32
        array $extras = array(),
33
        array $children = array()
34
    )
35
    {
36
        $this->setType($type);
37
        $this->setText($text);
38
        $this->setChildren($children);
39
40
        $this->attributes = $attributes;
41
        $this->extras = $extras;
42
43
        $this->init();
44
    }
45
46
    /**
47
     * Use this method to customize element comportment.
48
     */
49
    public function init(){}
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function __toString(): string
55
    {
56
        return (string) $this->renderRoot();
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function renderRoot(): Markup
63
    {
64
        return $this->getRoot()->render();
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function render(Markup $root = null): Markup
71
    {
72
        $type = $this->type;
73
        $attributes = $this->attributes;
74
75
        $element = null === $root ? HtmlTag::createElement($type) : $root->addElement($type);
76
        $element->text($this->text);
77
78
        $this->renderAttributes($element, $attributes);
79
        $this->renderChildren($element);
80
81
        return $element;
82
    }
83
84
    /**
85
     * Set Markup element attributes.
86
     *
87
     * @param Markup $element
88
     * @param array  $attributes
89
     */
90
    private function renderAttributes(Markup $element, array $attributes)
91
    {
92
        foreach ($attributes as $attr => $value) {
93
            if (is_array($value)) {
94
                $glue = 'style' == $attr ? '; ' : ' ';
95
                $value = implode($glue, $value);
96
            }
97
98
            if (null !== $value) {
99
                $element->set($attr, $value);
100
            }
101
        }
102
    }
103
104
    /**
105
     * Render element children.
106
     *
107
     * @param Markup $root
108
     */
109
    private function renderChildren(Markup $root)
110
    {
111
        foreach ($this->children as $child) {
112
            $child->render($root);
113
        }
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function getType()
120
    {
121
        return $this->type;
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function setType($type = null): ElementInterface
128
    {
129
        if (null !== $type) {
130
            $this->type = $type;
131
        }
132
133
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement\ElementInterface::setType of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139
    public function getText()
140
    {
141
        return $this->text;
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    public function setText($text = null): ElementInterface
148
    {
149
        if (null !== $text) {
150
            $this->text = $text;
151
        }
152
153
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement\ElementInterface::setText of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159
    public function addAttributes(array $attributes): ElementInterface
160
    {
161
        foreach ($attributes as $key => $value) {
162
            $this->addAttribute($key, $value);
163
        }
164
165
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement...nterface::addAttributes of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function addAttribute($key, $value): ElementInterface
172
    {
173
        $this->attributes[$key] = $value;
174
175
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement...Interface::addAttribute of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
176
    }
177
178
    /**
179
     * {@inheritdoc}
180
     */
181
    public function getAttributes(): array
182
    {
183
        return $this->attributes;
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189
    public function setAttributes(array $attributes = array()): ElementInterface
190
    {
191
        $this->attributes = $attributes;
192
193
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement...nterface::setAttributes of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
194
    }
195
196
    /**
197
     * {@inheritdoc}
198
     */
199
    public function addChildren(array $children): ElementInterface
200
    {
201
        foreach ($children as $child) {
202
            $this->addChild($child);
203
        }
204
205
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement...tInterface::addChildren of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211
    public function addChild(ElementInterface $child): ElementInterface
212
    {
213
        $child = $child->getRoot();
214
215
        $this->children[] = $child;
216
217
        $child->setParent($this);
218
219
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement...mentInterface::addChild of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225
    public function getChildren(): array
226
    {
227
        return $this->children;
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     */
233
    public function setChildren(array $children = array()): ElementInterface
234
    {
235
        $this->children = array();
236
237
        $this->addChildren($children);
238
239
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement...tInterface::setChildren of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
240
    }
241
242
    /**
243
     * {@inheritdoc}
244
     */
245
    public function getParent(): ElementInterface
246
    {
247
        return $this->parent;
248
    }
249
250
    /**
251
     * {@inheritdoc}
252
     */
253
    public function setParent(ElementInterface $parent = null): ElementInterface
254
    {
255
        $this->parent = $parent;
256
257
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (NatePage\EasyHtmlElement\Element) is incompatible with the return type declared by the interface NatePage\EasyHtmlElement...entInterface::setParent of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
258
    }
259
260
    /**
261
     * {@inheritdoc}
262
     */
263
    public function getRoot(): ElementInterface
264
    {
265
        return null !== $this->parent ? $this->parent->getRoot() : $this;
266
    }
267
}
268