StringType   B
last analyzed

Complexity

Total Complexity 44

Size/Duplication

Total Lines 302
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 72
c 2
b 1
f 0
dl 0
loc 302
ccs 84
cts 84
cp 1
rs 8.8798
wmc 44

16 Methods

Rating   Name   Duplication   Size   Complexity  
A checkValueRegex() 0 10 5
A checkValue() 0 7 1
A setConversion() 0 9 3
A setAllowedValues() 0 13 4
A getValueRegex() 0 7 3
A getMaxLength() 0 3 1
A getConversion() 0 3 1
A setMinLength() 0 5 1
A getMinLength() 0 3 1
A convertValue() 0 10 5
A setValue() 0 18 5
B checkValueLength() 0 9 7
A setValueRegex() 0 5 1
A getAllowedValues() 0 3 1
A checkIfValueIsInAllowedValues() 0 12 4
A setMaxLength() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like StringType often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use StringType, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of Wszetko Sitemap.
7
 *
8
 * (c) Paweł Kłopotek-Główczewski <[email protected]>
9
 *
10
 * This source file is subject to the MIT license that is bundled
11
 * with this source code in the file LICENSE.
12
 */
13
14
namespace Wszetko\Sitemap\Items\DataTypes;
15
16
use InvalidArgumentException;
17
use Wszetko\Sitemap\Interfaces\DataType;
18
19
/**
20
 * Class StringType.
21
 *
22
 * @package Wszetko\Sitemap\Items\DataTypes
23
 */
24
class StringType extends AbstractDataType
25
{
26
    /**
27
     * Minimum length of string.
28
     *
29
     * @var null|int
30
     */
31
    protected $minLength;
32
33
    /**
34
     * Maximum length of string.
35
     *
36
     * @var null|int
37
     */
38
    protected $maxLength;
39
40
    /**
41
     * List of allowed values that can be set.
42
     *
43
     * @var null|array
44
     */
45
    protected $allowedValues;
46
47
    /**
48
     * Regular expression to test value.
49
     *
50
     * @var null|string
51
     */
52
    protected $regex;
53
54
    /**
55
     * Type of string conversion.
56
     *
57
     * @var null|string
58
     */
59
    protected $conversion;
60
61
    /**
62
     * Return minimal string length.
63
     *
64
     * @return null|int
65
     */
66 506
    public function getMinLength(): ?int
67
    {
68 506
        return $this->minLength;
69
    }
70
71
    /**
72
     * Set minimal string length.
73
     *
74
     * @param int $minLength
75
     *
76
     * @return \Wszetko\Sitemap\Items\DataTypes\StringType
77
     */
78 312
    public function setMinLength(int $minLength): self
79
    {
80 312
        $this->minLength = $minLength;
81
82 312
        return $this;
83
    }
84
85
    /**
86
     * Return maximum string length.
87
     *
88
     * @return null|int
89
     */
90 506
    public function getMaxLength(): ?int
91
    {
92 506
        return $this->maxLength;
93
    }
94
95
    /**
96
     * Set maximum string length.
97
     *
98
     * @param int $maxLength
99
     *
100
     * @return self
101
     */
102 312
    public function setMaxLength(int $maxLength): self
103
    {
104 312
        $this->maxLength = $maxLength;
105
106 312
        return $this;
107
    }
108
109
    /**
110
     * Return list of allowed values.
111
     *
112
     * @return null|array
113
     */
114 506
    public function getAllowedValues(): ?array
115
    {
116 506
        return $this->allowedValues;
117
    }
118
119
    /**
120
     * Set list of allowed values.
121
     *
122
     * @param null|array|string $allowedValues
123
     *
124
     * @return \Wszetko\Sitemap\Items\DataTypes\StringType
125
     */
126 450
    public function setAllowedValues($allowedValues): self
127
    {
128 450
        if (is_string($allowedValues)) {
129 362
            $allowedValues = explode(',', $allowedValues);
130
131 362
            foreach ($allowedValues as $allowedValue) {
132 362
                $this->allowedValues[] = trim($allowedValue);
133
            }
134 400
        } elseif (is_array($allowedValues)) {
135 400
            $this->allowedValues = $allowedValues;
136
        }
137
138 450
        return $this;
139
    }
140
141
    /**
142
     * Set regular expression to test value.
143
     *
144
     * @param string $regex
145
     *
146
     * @return \Wszetko\Sitemap\Items\DataTypes\StringType
147
     */
148 388
    public function setValueRegex(string $regex): self
149
    {
150 388
        $this->regex = $regex;
151
152 388
        return $this;
153
    }
154
155
    /**
156
     * Return regular expression to test value.
157
     *
158
     * @return null|string
159
     */
160 506
    public function getValueRegex(): ?string
161
    {
162 506
        if (null !== $this->regex && '' !== $this->regex) {
163 122
            return $this->regex;
164
        }
165
166 504
        return null;
167
    }
168
169
    /**
170
     * Set conversion of value.
171
     *
172
     * @param string $conversion
173
     *
174
     * @return $this
175
     */
176 370
    public function setConversion(string $conversion): self
177
    {
178 370
        if (in_array($conversion, ['upper', 'UPPER', 'Upper'], true)) {
179 312
            $this->conversion = 'upper';
180 370
        } elseif (in_array($conversion, ['lower', 'LOWER', 'Lower'], true)) {
181 370
            $this->conversion = 'lower';
182
        }
183
184 370
        return $this;
185
    }
186
187
    /**
188
     * Return conversion of value.
189
     *
190
     * @return null|string
191
     */
192 506
    public function getConversion(): ?string
193
    {
194 506
        return $this->conversion;
195
    }
196
197
    /**
198
     * @inheritDoc
199
     *
200
     * @throws \InvalidArgumentException
201
     */
202 506
    public function setValue($value, $parameters = []): DataType
203
    {
204 506
        if (null !== $value) {
205 506
            $value = (string) $value;
206 506
            $this->checkValue($value);
207
        }
208
209
        if (
210 506
            (null === $value
211 506
            || '' === $value)
212 506
            && $this->isRequired()
213
        ) {
214 16
            throw new InvalidArgumentException($this->getName() . ' need to be set.');
215
        }
216
217 500
        parent::setValue($value, $parameters);
218
219 500
        return $this;
220
    }
221
222
    /**
223
     * Parse value if is valid one.
224
     *
225
     * @param string $value
226
     * @param-out null|string $value
227
     *
228
     * @return void
229
     */
230 506
    private function checkValue(string &$value): void
231
    {
232 506
        $value = trim($value);
233 506
        $this->checkValueLength($value);
234 506
        $this->convertValue($value);
235 506
        $this->checkIfValueIsInAllowedValues($value);
236 506
        $this->checkValueRegex($value);
237 506
    }
238
239
    /**
240
     * Check if value have valid length.
241
     *
242
     * @param null|string $value
243
     * @param-out null|string $value
244
     *
245
     * @return void
246
     */
247 506
    private function checkValueLength(?string &$value): void
248
    {
249 506
        if (null !== $value) {
250 506
            if (null !== $this->getMinLength() && mb_strlen($value) < $this->getMinLength()) {
251 4
                $value = null;
252
            }
253
254 506
            if (null !== $this->getMaxLength() && null !== $value && mb_strlen($value) > $this->getMaxLength()) {
255 6
                $value = mb_substr($value, 0, $this->getMaxLength());
256
            }
257
        }
258 506
    }
259
260
    /**
261
     * Convert value if needed.
262
     *
263
     * @param null|string $value
264
     * @param-out null|string $value
265
     *
266
     * @return void
267
     */
268 506
    private function convertValue(?string &$value): void
269
    {
270 506
        if (null !== $value) {
271 506
            $conversion = $this->getConversion();
272
273 506
            if (is_string($conversion)) {
274 104
                if ('upper' == $conversion) {
275 38
                    $value = mb_strtoupper($value);
276 90
                } elseif ('lower' == $conversion) {
277 90
                    $value = mb_strtolower($value);
278
                }
279
            }
280
        }
281 506
    }
282
283
    /**
284
     * Check if value is in allowed list.
285
     *
286
     * @param null|string $value
287
     * @param-out null|string $value
288
     *
289
     * @return void
290
     */
291 506
    private function checkIfValueIsInAllowedValues(?string &$value): void
292
    {
293 506
        if (null !== $value) {
294 506
            $allowedValues = $this->getAllowedValues();
295
296 506
            if (null !== $allowedValues) {
297 74
                $match = preg_grep("/{$value}/i", $allowedValues);
298
299 74
                if ([] === $match) {
300 14
                    $value = null;
301
                } else {
302 68
                    $value = array_values($match)[0];
303
                }
304
            }
305
        }
306 506
    }
307
308
    /**
309
     * Test value with provided regular expression.
310
     *
311
     * @param null|string $value
312
     * @param-out null|string $value
313
     *
314
     * @return void
315
     */
316 506
    private function checkValueRegex(?string &$value): void
317
    {
318 506
        if (null !== $value) {
319 506
            $regex = $this->getValueRegex();
320
321 506
            if (null !== $regex && '' !== $regex) {
322 122
                $match = preg_match($regex, $value);
323
324 122
                if (1 !== $match) {
325 6
                    $value = null;
326
                }
327
            }
328
        }
329 506
    }
330
}
331