Completed
Push — master ( 236b50...7a7214 )
by Lars
02:07
created

SimpleHtmlAttributes::tokenize()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6.0073

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 16
cts 17
cp 0.9412
rs 8.8337
c 0
b 0
f 0
cc 6
nc 6
nop 0
crap 6.0073
1
<?php
2
3
declare(strict_types=1);
4
5
namespace voku\helper;
6
7
/**
8
 * {@inheritDoc}
9
 */
10
class SimpleHtmlAttributes implements SimpleHtmlAttributesInterface
11
{
12
    /**
13
     * @var string
14
     */
15
    private $attributeName;
16
17
    /**
18
     * @var null|\DOMElement
19
     */
20
    private $element;
21
22
    /**
23
     * @var string[]
24
     */
25
    private $tokens = [];
26
27
    /**
28
     * @var null|string
29
     */
30
    private $previousValue;
31
32
    /**
33
     * Creates a list of space-separated tokens based on the attribute value of an element.
34
     *
35
     * @param null|\DOMElement $element
36
     *                                  <p>The DOM element.</p>
37
     * @param string $attributeName
38
     *                                  <p>The name of the attribute.</p>
39
     */
40 12
    public function __construct($element, string $attributeName)
41
    {
42 12
        $this->element = $element;
43 12
        $this->attributeName = $attributeName;
44
45 12
        $this->tokenize();
46 12
    }
47
48
    /** @noinspection MagicMethodsValidityInspection */
49
    /**
50
     * Returns the value for the property specified.
51
     *
52
     * @param string $name The name of the property
53
     *
54
     * @return string The value of the property specified
55
     */
56 3
    public function __get(string $name)
57
    {
58 3
        if ($name === 'length') {
59 1
            $this->tokenize();
60
61 1
            return count($this->tokens);
62
        }
63
64 2
        if ($name === 'value') {
65 1
            return (string) $this;
66
        }
67
68 1
        throw new \InvalidArgumentException('Undefined property: $' . $name);
69
    }
70
71
    /**
72
     *
73
     * @return string
74
     */
75 4
    public function __toString(): string
76
    {
77 4
        $this->tokenize();
78
79 4
        return implode(' ', $this->tokens);
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     */
85
    public function add(string ...$tokens)
86
    {
87
        if (count($tokens) === 0) {
88
            return null;
89
        }
90
91
        foreach ($tokens as $t) {
92
            if (in_array($t, $this->tokens)) {
93
                continue;
94
            }
95
96
            $this->tokens[] = $t;
97
        }
98
99
        return $this->setAttributeValue();
100
    }
101
102
    /**
103
     * {@inheritDoc}
104
     */
105 1
    public function contains(string $token): bool
106
    {
107 1
        $this->tokenize();
108
109 1
        return in_array($token, $this->tokens);
110
    }
111
112
    /**
113
     * {@inheritDoc}
114
     */
115 1
    public function entries(): \ArrayIterator
116
    {
117 1
        $this->tokenize();
118
119 1
        return new \ArrayIterator($this->tokens);
120
    }
121
122 1
    public function item(int $index)
123
    {
124 1
        $this->tokenize();
125 1
        if ($index >= count($this->tokens)) {
126 1
            return null;
127
        }
128
129 1
        return $this->tokens[$index];
130
    }
131
132
    /**
133
     * {@inheritDoc}
134
     */
135 1
    public function remove(string ...$tokens)
136
    {
137 1
        if (count($tokens) === 0) {
138
            return null;
139
        }
140
141 1
        if (count($this->tokens) === 0) {
142 1
            return null;
143
        }
144
145 1
        foreach ($tokens as $t) {
146 1
            $i = array_search($t, $this->tokens);
147 1
            if ($i === false) {
148 1
                continue;
149
            }
150
151 1
            array_splice($this->tokens, $i, 1);
152
        }
153
154 1
        return $this->setAttributeValue();
155
    }
156
157
    /**
158
     * {@inheritDoc}
159
     */
160 1
    public function replace(string $old, string $new)
161
    {
162 1
        if ($old === $new) {
163 1
            return null;
164
        }
165
166 1
        $this->tokenize();
167 1
        $i = array_search($old, $this->tokens);
168 1
        if ($i !== false) {
169 1
            $j = array_search($new, $this->tokens);
170 1
            if ($j === false) {
171 1
                $this->tokens[$i] = $new;
172
            } else {
173 1
                array_splice($this->tokens, $i, 1);
174
            }
175
176 1
            return $this->setAttributeValue();
177
        }
178
179 1
        return null;
180
    }
181
182
    /**
183
     * {@inheritDoc}
184
     */
185 2
    public function toggle(string $token, bool $force = null): bool
186
    {
187
        // init
188 2
        $this->tokenize();
189 2
        $isThereAfter = false;
190
191 2
        $i = array_search($token, $this->tokens);
192 2
        if ($force === null) {
193 1 View Code Duplication
            if ($i === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194 1
                $this->tokens[] = $token;
195 1
                $isThereAfter = true;
196
            } else {
197 1
                array_splice($this->tokens, $i, 1);
198
            }
199 1 View Code Duplication
        } elseif ($force) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
200 1
            if ($i === false) {
201 1
                $this->tokens[] = $token;
202
            }
203 1
            $isThereAfter = true;
204
        } else {
205
            /** @noinspection NestedPositiveIfStatementsInspection */
206 1
            if ($i !== false) {
207 1
                array_splice($this->tokens, $i, 1);
208
            }
209
        }
210
211
        /** @noinspection UnusedFunctionResultInspection */
212 2
        $this->setAttributeValue();
213
214 2
        return $isThereAfter;
215
    }
216
217
    /**
218
     * @return \DOMAttr|false|null
219
     */
220 4
    private function setAttributeValue()
221
    {
222 4
        if ($this->element === null) {
223
            return false;
224
        }
225
226 4
        $value = implode(' ', $this->tokens);
227 4
        if ($this->previousValue === $value) {
228 1
            return null;
229
        }
230
231 4
        $this->previousValue = $value;
232
233 4
        return $this->element->setAttribute($this->attributeName, $value);
234
    }
235
236
    /**
237
     * @return void
238
     */
239 12
    private function tokenize()
240
    {
241 12
        if ($this->element === null) {
242
            return;
243
        }
244
245 12
        $current = $this->element->getAttribute($this->attributeName);
246 12
        if ($this->previousValue === $current) {
247 10
            return;
248
        }
249
250 12
        $this->previousValue = $current;
251 12
        $tokens = explode(' ', $current);
252 12
        $finals = [];
253 12
        foreach ($tokens as $token) {
254
255 12
            if ($token === '') {
256 11
                continue;
257
            }
258
259 11
            if (in_array($token, $finals, true)) {
260 10
                continue;
261
            }
262
263 11
            $finals[] = $token;
264
        }
265
266 12
        $this->tokens = $finals;
267 12
    }
268
269
}
270