Passed
Push — master ( fa8b55...986d5c )
by smiley
01:43
created

PrototypeHTMLElementTrait::addClassNames()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 12
rs 10
cc 3
nc 3
nop 1
1
<?php
2
/**
3
 * Trait PrototypeHTMLElementTrait
4
 *
5
 * @filesource   PrototypeHTMLElementTrait.php
6
 * @created      11.05.2017
7
 * @package      chillerlan\PrototypeDOM\Node
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 *
12
 * @noinspection PhpIncompatibleReturnTypeInspection
13
 */
14
15
namespace chillerlan\PrototypeDOM\Node;
16
17
use function array_key_exists, array_keys, array_merge, array_unique, count, explode, implode, in_array, strtolower, trim;
18
19
/**
20
 * @implements \chillerlan\PrototypeDOM\Node\PrototypeElement
21
 */
22
trait PrototypeHTMLElementTrait{
23
	use PrototypeElementTrait;
24
25
	public function getClassName():string{
26
		return trim($this->getAttribute('class'));
0 ignored issues
show
Bug introduced by
The method getAttribute() does not exist on chillerlan\PrototypeDOM\...ototypeHTMLElementTrait. Did you maybe mean getAttributes()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

26
		return trim($this->/** @scrutinizer ignore-call */ getAttribute('class'));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
27
	}
28
29
	public function setClassName(string $class):PrototypeHTMLElement{
30
		$this->setAttribute('class', $class);
0 ignored issues
show
Bug introduced by
The method setAttribute() does not exist on chillerlan\PrototypeDOM\...ototypeHTMLElementTrait. Did you maybe mean setAttributes()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

30
		$this->/** @scrutinizer ignore-call */ 
31
         setAttribute('class', $class);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
31
32
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type chillerlan\PrototypeDOM\...ototypeHTMLElementTrait which is incompatible with the type-hinted return chillerlan\PrototypeDOM\Node\PrototypeHTMLElement.
Loading history...
33
	}
34
35
	public function getHref():string{
36
		return trim($this->getAttribute('href'));
37
	}
38
39
	public function setHref(string $href):PrototypeHTMLElement{
40
		$this->setAttribute('href', $href);
41
42
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type chillerlan\PrototypeDOM\...ototypeHTMLElementTrait which is incompatible with the type-hinted return chillerlan\PrototypeDOM\Node\PrototypeHTMLElement.
Loading history...
43
	}
44
45
	public function getSrc():string{
46
		return trim($this->getAttribute('src'));
47
	}
48
49
	public function setSrc(string $src):PrototypeHTMLElement{
50
		$this->setAttribute('src', $src);
51
52
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type chillerlan\PrototypeDOM\...ototypeHTMLElementTrait which is incompatible with the type-hinted return chillerlan\PrototypeDOM\Node\PrototypeHTMLElement.
Loading history...
53
	}
54
55
	/*************
56
	 * Prototype *
57
	 *************/
58
59
	/**
60
	 * @inheritDoc
61
	 */
62
	public function identify(string $newID = null):string{
63
		$oldID = trim($this->getAttribute('id'));
64
65
		if($newID !== null){
66
			$this->setAttribute('id', trim($newID));
67
		}
68
69
		return $oldID;
70
	}
71
72
	/**
73
	 * @inheritDoc
74
	 */
75
	public function classNames():array{
76
77
		if(!$this->hasAttributes()){
0 ignored issues
show
Bug introduced by
It seems like hasAttributes() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
		if(!$this->/** @scrutinizer ignore-call */ hasAttributes()){
Loading history...
78
			return [];
79
		}
80
81
		$classnames        = explode(' ', $this->getClassName());
82
		$currentClassnames = [];
83
84
		foreach($classnames as $classname){
85
			$classname = trim($classname);
86
87
			if(!empty($classname)){
88
				$currentClassnames[] = $classname;
89
			}
90
91
		}
92
93
		return $currentClassnames;
94
	}
95
96
	/**
97
	 * @inheritDoc
98
	 */
99
	public function hasClassName(string $classname):bool{
100
		return in_array($classname, $this->classNames(), true);
101
	}
102
103
	/**
104
	 * @inheritDoc
105
	 */
106
	public function addClassName(string $classname):PrototypeHTMLElement{
107
		return $this->addClassNames([$classname]);
108
	}
109
110
	/**
111
	 * @inheritDoc
112
	 */
113
	public function removeClassName(string $classname):PrototypeHTMLElement{
114
		return $this->removeClassNames([$classname]);
115
	}
116
117
	/**
118
	 * @inheritDoc
119
	 */
120
	public function toggleClassName(string $classname):PrototypeHTMLElement{
121
122
		if($this->hasClassName($classname)){
123
			return $this->removeClassName($classname);
124
		}
125
126
		return $this->addClassName($classname);
127
	}
128
129
	/**
130
	 * @inheritDoc
131
	 */
132
	public function getStyle(string $property):?string{
133
		$currentStyle = $this->getStyles();
134
135
		if(array_key_exists(strtolower($property), $currentStyle)){
136
			return $currentStyle[$property];
137
		}
138
139
		return null;
140
	}
141
142
	/**
143
	 * @inheritDoc
144
	 */
145
	public function setStyle(array $style, bool $replace = null):PrototypeHTMLElement{
146
		$currentStyle = $this->getStyles();
147
148
		if($replace !== true){
149
			$style = array_merge($currentStyle, $style);
150
		}
151
152
		foreach($style as $property => $value){
153
			$style[$property] = $property.': '.$value.';';
154
		}
155
156
		$this->setAttribute('style', implode(' ', $style));
157
158
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type chillerlan\PrototypeDOM\...ototypeHTMLElementTrait which is incompatible with the type-hinted return chillerlan\PrototypeDOM\Node\PrototypeHTMLElement.
Loading history...
159
	}
160
161
	/***********
162
	 * Generic *
163
	 ***********/
164
165
	/**
166
	 * @inheritDoc
167
	 */
168
	public function getAttributes():array{
169
		$attributes = [];
170
171
		foreach($this->attributes as $attribute){
172
			$attributes[$attribute->nodeName] = $attribute->nodeValue;
173
		}
174
175
		return $attributes;
176
	}
177
178
	/**
179
	 * @inheritDoc
180
	 */
181
	public function setAttributes(array $attributes):PrototypeHTMLElement{
182
183
		foreach($attributes as $name => $value){
184
			$this->setAttribute($name, $value);
185
		}
186
187
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type chillerlan\PrototypeDOM\...ototypeHTMLElementTrait which is incompatible with the type-hinted return chillerlan\PrototypeDOM\Node\PrototypeHTMLElement.
Loading history...
188
	}
189
190
	/**
191
	 * @inheritDoc
192
	 */
193
	public function removeAttributes(array $attributes):PrototypeHTMLElement{
194
195
		foreach($attributes as $name){
196
			$this->removeAttribute($name);
0 ignored issues
show
Bug introduced by
The method removeAttribute() does not exist on chillerlan\PrototypeDOM\...ototypeHTMLElementTrait. Did you maybe mean removeAttributes()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

196
			$this->/** @scrutinizer ignore-call */ 
197
          removeAttribute($name);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
197
		}
198
199
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type chillerlan\PrototypeDOM\...ototypeHTMLElementTrait which is incompatible with the type-hinted return chillerlan\PrototypeDOM\Node\PrototypeHTMLElement.
Loading history...
200
	}
201
202
	/**
203
	 * @inheritDoc
204
	 */
205
	public function addClassNames(array $classnames):PrototypeHTMLElement{
206
		$currentClassnames = $this->classNames();
207
208
		foreach($classnames as $classname){
209
210
			if(!in_array($classname, $currentClassnames, true)){
211
				$currentClassnames[] = $classname;
212
			}
213
214
		}
215
216
		return $this->setClassName(implode(' ', array_unique($currentClassnames)));
217
	}
218
219
	/**
220
	 * @inheritDoc
221
	 */
222
	public function removeClassNames(array $classnames):PrototypeHTMLElement{
223
		$currentClassnames = $this->classNames();
224
225
		foreach($classnames as $classname){
226
			$keys = array_keys($currentClassnames, $classname);
227
228
			foreach($keys as $key){
229
				unset($currentClassnames[$key]);
230
			}
231
232
		}
233
234
		return $this->setClassName(implode(' ', array_unique($currentClassnames)));
235
	}
236
237
	/**
238
	 * @inheritDoc
239
	 */
240
	public function getStyles():array{
241
242
		if(!$this->hasAttributes()){
243
			return [];
244
		}
245
246
		$styles       = explode(';', trim($this->getAttribute('style')));
247
		$currentStyle = [];
248
249
		foreach($styles as $style){
250
			$s = explode(':', $style);
251
252
			if(count($s) === 2){
253
				$currentStyle[strtolower(trim($s[0]))] = trim($s[1]);
254
			}
255
256
		}
257
258
		return $currentStyle;
259
	}
260
261
}
262