Completed
Push — 1.x ( 3c735f...457137 )
by Pol
01:42
created

Attributes::offsetGet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
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\Attribute[]
14
     */
15
    private $storage = array();
16
17
    /**
18
     * {@inheritdoc}
19
     */
20 23
    public function __construct(array $attributes = array())
21
    {
22 23
        foreach ($attributes as $name => $value) {
23 1
            $this->storage[$name] = new Attribute(
24 1
                $name,
25 1
                $this->ensureString($value)
26
            );
27
        }
28 23
    }
29
30
    /**
31
     * {@inheritdoc}
32
     */
33 2
    public function &offsetGet($name)
34
    {
35 2
        if (!isset($this->storage[$name])) {
36 2
            $this->storage[$name] = new Attribute(
37 2
                $name
38
            );
39
        }
40
41 2
        return $this->storage[$name];
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 1
    public function offsetSet($name, $value = null)
48
    {
49 1
        $this->storage[$name] = new Attribute(
50 1
            $name,
51 1
            $this->ensureString($value)
52
        );
53 1
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 1
    public function offsetUnset($name)
59
    {
60 1
        unset($this->storage[$name]);
61 1
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 2
    public function offsetExists($name)
67
    {
68 2
        return isset($this->storage[$name]);
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74 14
    public function append($key, $value = null)
75
    {
76
        $this->storage += array(
77 14
            $key => new Attribute(
78 14
                $key,
79 14
                $this->ensureString($value)
80
            )
81
        );
82
83 14
        foreach ($this->normalizeValue($value) as $value_item) {
84 13
            $this->storage[$key]->append($value_item);
85
        }
86
87 14
        return $this;
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93 2
    public function remove($key, $value = false)
94
    {
95 2
        if (!isset($this->storage[$key])) {
96 1
            return $this;
97
        }
98
99 1
        foreach ($this->normalizeValue($value) as $value_item) {
100 1
            $this->storage[$key]->remove($value_item);
101
        }
102
103 1
        return $this;
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109 1
    public function delete($name = array())
110
    {
111 1
        foreach ($this->normalizeValue($name) as $attribute_name) {
112 1
            unset($this->storage[$attribute_name]);
113
        }
114
115 1
        return $this;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function without($key, $value)
122
    {
123
        $attributes = clone $this;
124
125
        return $attributes->remove($key, $value);
0 ignored issues
show
Documentation introduced by
$value is of type array|string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131 1
    public function replace($key, $value, $replacement)
132
    {
133 1
        if (!isset($this->storage[$key])) {
134 1
            return $this;
135
        }
136
137 1
        if (!$this->contains($key, $value)) {
138 1
            return $this;
139
        }
140
141 1
        $this->storage[$key]->remove($value);
142 1
        foreach ($this->normalizeValue($replacement) as $replacement_value) {
143 1
            $this->storage[$key]->append($replacement_value);
144
        }
145
146 1
        return $this;
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152 1
    public function merge(array $data = array())
153
    {
154 1
        foreach ($data as $key => $value) {
155
            $this->storage += array(
156 1
                $key => new Attribute(
157 1
                    $key
158
                )
159
            );
160
161 1
            $this->storage[$key]->merge(
162 1
                $this->normalizeValue($value)
163
            );
164
        }
165
166 1
        return $this;
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172 1
    public function exists($key, $value = null)
173
    {
174 1
        if (!isset($this->storage[$key])) {
175 1
            return false;
176
        }
177
178 1
        if (null !== $value) {
179 1
            return $this->contains($key, $value);
180
        }
181
182 1
        return true;
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     */
188 3
    public function contains($key, $value)
189
    {
190 3
        if (!isset($this->storage[$key])) {
191 1
            return false;
192
        }
193
194 3
        return $this->storage[$key]->contains($value);
195
    }
196
197
    /**
198
     * {@inheritdoc}
199
     */
200 7
    public function __toString()
201
    {
202 7
        return $this->render();
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208 12
    public function render()
209
    {
210 12
        $attributes = implode(' ', $this->prepareValues());
211
212 12
        return $attributes ? ' ' . $attributes : '';
213
    }
214
215
    /**
216
     * {@inheritdoc}
217
     */
218 2
    public function toArray()
219
    {
220 2
        $attributes = $this->storage;
221
222
        // If empty, just return an empty array.
223 2
        if (empty($attributes)) {
224 2
            return array();
225
        }
226
227 1
        $result = [];
228
229 1
        foreach ($this->prepareValues() as $attribute) {
230 1
            $result[$attribute->getName()] = $attribute->getValueAsArray();
231
        }
232
233 1
        return $result;
234
    }
235
236
    /**
237
     * {@inheritdoc}
238
     */
239 1
    public function getStorage()
240
    {
241 1
        return $this->storage;
242
    }
243
244
    /**
245
     * {@inheritdoc}
246
     */
247 1
    public function getIterator()
248
    {
249 1
        return new \ArrayIterator($this->toArray());
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255 1
    public function count()
256
    {
257 1
        return count($this->storage);
258
    }
259
260
    /**
261
     * Returns all storage elements as an array.
262
     *
263
     * @return \drupol\htmltag\Attribute[]
264
     *   An associative array of attributes.
265
     */
266 13
    private function prepareValues()
267
    {
268 13
        $attributes = $this->storage;
269
270
        // If empty, just return an empty array.
271 13
        if (empty($attributes)) {
272 5
            return array();
273
        }
274
275
        // Sort the attributes.
276 11
        ksort($attributes);
277
278 11
        $result = [];
279
280 11
        foreach ($attributes as $attribute_name => $attribute) {
281
            switch ($attribute_name) {
282 11
                case 'class':
283 10
                    $classes = $attribute->getValueAsArray();
284 10
                    asort($classes);
285 10
                    $result[$attribute->getName()] = $attribute->set(
286 10
                        implode(' ', $classes)
287
                    );
288 10
                    break;
289
290
                default:
291 11
                    $result[$attribute->getName()] = $attribute;
292
            }
293
        }
294
295 11
        return $result;
296
    }
297
298
    /**
299
     * Normalize a value.
300
     *
301
     * @param mixed $value
302
     *  The value to normalize.
303
     *
304
     * @return array
305
     *   The value normalized.
306
     */
307 15
    private function normalizeValue($value)
308
    {
309 15
        return $this->ensureFlatArray($value);
310
    }
311
312
    /**
313
     * Todo.
314
     *
315
     * @param mixed $value
316
     *   Todo.
317
     *
318
     * @return array
319
     *   The array, flattened.
320
     */
321 15
    private function ensureFlatArray($value)
322
    {
323 15
        $type = gettype($value);
324
325 15
        $return = array();
326
327
        switch ($type) {
328 15
            case 'string':
329 14
                $return = explode(
330 14
                    ' ',
331 14
                    $this->ensureString($value)
332
                );
333 14
                break;
334
335 14
            case 'array':
336 3
                $flat_array = iterator_to_array(
337 3
                    new \RecursiveIteratorIterator(
338 3
                        new \RecursiveArrayIterator(
339 3
                            $value
340
                        )
341
                    ),
342 3
                    false
343
                );
344
345 3
                $return = [];
346 3
                foreach ($flat_array as $item) {
347 3
                    $return = array_merge(
348 3
                        $return,
349 3
                        $this->normalizeValue($item)
350
                    );
351
                }
352 3
                break;
353
354 13
            case 'double':
355 13
            case 'integer':
356 1
                $return = array($value);
357 1
                break;
358 13
            case 'object':
359 13
            case 'boolean':
360 13
            case 'resource':
361 13
            case 'NULL':
362
        }
363
364 15
        return $return;
365
    }
366
367
    /**
368
     * Todo.
369
     *
370
     * @param mixed $value
371
     *   Todo.
372
     *
373
     * @return string
374
     *   A string.
375
     */
376 15
    private function ensureString($value)
377
    {
378 15
        $type = gettype($value);
379
380 15
        $return = '';
381
382
        switch ($type) {
383 15
            case 'string':
384 14
                $return = $value;
385 14
                break;
386
387 14
            case 'array':
388 2
                $return = implode(
389 2
                    ' ',
390 2
                    $this->ensureFlatArray($value)
391
                );
392 2
                break;
393
394 14
            case 'double':
395 14
            case 'integer':
396 1
                $return = (string) $value;
397 1
                break;
398 14
            case 'object':
399 14
            case 'boolean':
400 14
            case 'resource':
401 14
            case 'NULL':
402
        }
403
404 15
        return $return;
405
    }
406
}
407