1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace drupol\htmltag; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Class Attributes. |
7
|
|
|
*/ |
8
|
|
|
class Attributes implements AttributesInterface |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* Stores the attribute data. |
12
|
|
|
* |
13
|
|
|
* @var \drupol\htmltag\AttributeInterface[] |
14
|
|
|
*/ |
15
|
|
|
private $storage = array(); |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* The attribute factory. |
19
|
|
|
* |
20
|
|
|
* @var \drupol\htmltag\AttributeFactoryInterface |
21
|
|
|
*/ |
22
|
|
|
private $attributeFactory; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Attributes constructor. |
26
|
|
|
* |
27
|
|
|
* @param \drupol\htmltag\AttributeFactoryInterface $attributeFactory |
28
|
|
|
* The attribute factory. |
29
|
|
|
* @param mixed[] $attributes |
30
|
|
|
* The input attributes. |
31
|
|
|
*/ |
32
|
26 |
|
public function __construct(AttributeFactoryInterface $attributeFactory, $attributes = array()) |
33
|
|
|
{ |
34
|
26 |
|
$this->attributeFactory = $attributeFactory; |
35
|
26 |
|
$this->import($attributes); |
36
|
26 |
|
} |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* {@inheritdoc} |
40
|
|
|
*/ |
41
|
26 |
|
public function import($attributes = array()) |
42
|
|
|
{ |
43
|
26 |
|
foreach ($attributes as $name => $value) { |
44
|
4 |
|
$this->set($name, $value); |
45
|
|
|
} |
46
|
|
|
|
47
|
26 |
|
return $this; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* {@inheritdoc} |
52
|
|
|
*/ |
53
|
8 |
|
public function set($name, $value = null) |
54
|
|
|
{ |
55
|
8 |
|
$this->storage[$name] = ($this->attributeFactory)::build($name, $value); |
56
|
|
|
|
57
|
8 |
|
return $this; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* {@inheritdoc} |
62
|
|
|
*/ |
63
|
2 |
|
public function offsetGet($name) |
64
|
|
|
{ |
65
|
2 |
|
if (!isset($this->storage[$name])) { |
66
|
2 |
|
$this->set($name); |
67
|
|
|
} |
68
|
|
|
|
69
|
2 |
|
return $this->storage[$name]; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* {@inheritdoc} |
74
|
|
|
*/ |
75
|
1 |
|
public function offsetSet($name, $value = null) |
76
|
|
|
{ |
77
|
1 |
|
$this->set($name, $value); |
78
|
1 |
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* {@inheritdoc} |
82
|
|
|
*/ |
83
|
1 |
|
public function offsetUnset($name) |
84
|
|
|
{ |
85
|
1 |
|
unset($this->storage[$name]); |
86
|
1 |
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* {@inheritdoc} |
90
|
|
|
*/ |
91
|
2 |
|
public function offsetExists($name) |
92
|
|
|
{ |
93
|
2 |
|
return isset($this->storage[$name]); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* {@inheritdoc} |
98
|
|
|
*/ |
99
|
14 |
|
public function append($key, $value = null) |
100
|
|
|
{ |
101
|
|
|
$this->storage += array( |
102
|
14 |
|
$key => ($this->attributeFactory)::build($key) |
103
|
|
|
); |
104
|
|
|
|
105
|
14 |
|
$this->storage[$key]->append($value); |
|
|
|
|
106
|
|
|
|
107
|
14 |
|
return $this; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* {@inheritdoc} |
112
|
|
|
*/ |
113
|
2 |
View Code Duplication |
public function remove($key, $value = '') |
|
|
|
|
114
|
|
|
{ |
115
|
2 |
|
if (!isset($this->storage[$key])) { |
116
|
1 |
|
return $this; |
117
|
|
|
} |
118
|
|
|
|
119
|
1 |
|
$this->storage[$key]->remove($value); |
120
|
|
|
|
121
|
1 |
|
return $this; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* {@inheritdoc} |
126
|
|
|
*/ |
127
|
2 |
|
public function delete($name) |
128
|
|
|
{ |
129
|
2 |
|
foreach (ArrayUtils::normalizeValue($name) as $attribute_name) { |
130
|
2 |
|
unset($this->storage[$attribute_name]); |
131
|
|
|
} |
132
|
|
|
|
133
|
2 |
|
return $this; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* {@inheritdoc} |
138
|
|
|
*/ |
139
|
1 |
|
public function without($key) |
140
|
|
|
{ |
141
|
1 |
|
$attributes = clone $this; |
142
|
|
|
|
143
|
1 |
|
return $attributes->delete($key); |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* {@inheritdoc} |
148
|
|
|
*/ |
149
|
1 |
|
public function replace($key, $value, $replacement) |
150
|
|
|
{ |
151
|
1 |
|
if (!isset($this->storage[$key])) { |
152
|
1 |
|
return $this; |
153
|
|
|
} |
154
|
|
|
|
155
|
1 |
|
if (!$this->contains($key, $value)) { |
156
|
1 |
|
return $this; |
157
|
|
|
} |
158
|
|
|
|
159
|
1 |
|
$this->storage[$key]->remove($value); |
160
|
1 |
|
$this->storage[$key]->append($replacement); |
|
|
|
|
161
|
|
|
|
162
|
1 |
|
return $this; |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* {@inheritdoc} |
167
|
|
|
*/ |
168
|
1 |
|
public function merge(array $data = array()) |
169
|
|
|
{ |
170
|
1 |
|
foreach ($data as $key => $value) { |
171
|
|
|
$this->storage += array( |
172
|
1 |
|
$key => ($this->attributeFactory)::build($key) |
173
|
|
|
); |
174
|
|
|
|
175
|
1 |
|
$this->storage[$key]->merge((array) $value); |
176
|
|
|
} |
177
|
|
|
|
178
|
1 |
|
return $this; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* {@inheritdoc} |
183
|
|
|
*/ |
184
|
1 |
|
public function exists($key, $value = null) |
185
|
|
|
{ |
186
|
1 |
|
if (!isset($this->storage[$key])) { |
187
|
1 |
|
return false; |
188
|
|
|
} |
189
|
|
|
|
190
|
1 |
|
if (null !== $value) { |
191
|
1 |
|
return $this->contains($key, $value); |
192
|
|
|
} |
193
|
|
|
|
194
|
1 |
|
return true; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* {@inheritdoc} |
199
|
|
|
*/ |
200
|
3 |
View Code Duplication |
public function contains($key, $value) |
|
|
|
|
201
|
|
|
{ |
202
|
3 |
|
if (!isset($this->storage[$key])) { |
203
|
1 |
|
return false; |
204
|
|
|
} |
205
|
|
|
|
206
|
3 |
|
return $this->storage[$key]->contains($value); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* {@inheritdoc} |
211
|
|
|
*/ |
212
|
4 |
|
public function __toString() |
213
|
|
|
{ |
214
|
4 |
|
return $this->render(); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* {@inheritdoc} |
219
|
|
|
*/ |
220
|
15 |
|
public function render() |
221
|
|
|
{ |
222
|
15 |
|
$attributes = implode(' ', $this->prepareValues()); |
223
|
|
|
|
224
|
15 |
|
return $attributes ? ' ' . $attributes : ''; |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** |
228
|
|
|
* {@inheritdoc} |
229
|
|
|
*/ |
230
|
2 |
|
public function toArray() |
231
|
|
|
{ |
232
|
2 |
|
$attributes = $this->storage; |
233
|
|
|
|
234
|
|
|
// If empty, just return an empty array. |
235
|
2 |
|
if (empty($attributes)) { |
236
|
2 |
|
return array(); |
237
|
|
|
} |
238
|
|
|
|
239
|
1 |
|
$result = []; |
240
|
|
|
|
241
|
1 |
|
foreach ($this->prepareValues() as $attribute) { |
242
|
1 |
|
$result[$attribute->getName()] = $attribute->getValueAsArray(); |
243
|
|
|
} |
244
|
|
|
|
245
|
1 |
|
return $result; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* {@inheritdoc} |
250
|
|
|
*/ |
251
|
1 |
|
public function getStorage() |
252
|
|
|
{ |
253
|
1 |
|
return $this->storage; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
/** |
257
|
|
|
* {@inheritdoc} |
258
|
|
|
*/ |
259
|
1 |
|
public function getIterator() |
260
|
|
|
{ |
261
|
1 |
|
return new \ArrayIterator($this->toArray()); |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* {@inheritdoc} |
266
|
|
|
*/ |
267
|
1 |
|
public function count() |
268
|
|
|
{ |
269
|
1 |
|
return count($this->storage); |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* Returns all storage elements as an array. |
274
|
|
|
* |
275
|
|
|
* @return \drupol\htmltag\AttributeInterface[] |
276
|
|
|
* An associative array of attributes. |
277
|
|
|
*/ |
278
|
16 |
|
private function prepareValues() |
279
|
|
|
{ |
280
|
16 |
|
$attributes = $this->storage; |
281
|
|
|
|
282
|
|
|
// If empty, just return an empty array. |
283
|
16 |
|
if (empty($attributes)) { |
284
|
5 |
|
return array(); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
// Sort the attributes. |
288
|
14 |
|
ksort($attributes); |
289
|
|
|
|
290
|
14 |
|
$result = []; |
291
|
|
|
|
292
|
14 |
|
foreach ($attributes as $attribute_name => $attribute) { |
293
|
|
|
switch ($attribute_name) { |
294
|
14 |
|
case 'class': |
295
|
12 |
|
$classes = $attribute->getValueAsArray(); |
296
|
12 |
|
asort($classes); |
297
|
12 |
|
$result[$attribute->getName()] = $attribute->set($classes); |
298
|
12 |
|
break; |
299
|
|
|
|
300
|
|
|
default: |
301
|
14 |
|
$result[$attribute->getName()] = $attribute; |
302
|
|
|
} |
303
|
|
|
} |
304
|
|
|
|
305
|
14 |
|
return $result; |
306
|
|
|
} |
307
|
|
|
} |
308
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.