Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Completed
Pull Request — 1.1 (#1169)
by Henrique
03:00
created

ValidationException   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 325
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 88.89%

Importance

Changes 0
Metric Value
wmc 54
lcom 1
cbo 0
dl 0
loc 325
ccs 120
cts 135
cp 0.8889
rs 6.4799
c 0
b 0
f 0

24 Methods

Rating   Name   Duplication   Size   Complexity  
A format() 0 19 4
A __toString() 0 4 1
A chooseTemplate() 0 4 1
A configure() 0 8 1
A getName() 0 4 1
A getId() 0 4 1
A getParam() 0 4 2
A getParams() 0 4 1
A getTemplate() 0 8 2
A hasParam() 0 4 1
A setId() 0 6 1
A setName() 0 6 1
A setMode() 0 9 1
A setParam() 0 8 1
A hasCustomTemplate() 0 4 1
A buildMessage() 0 4 1
A buildTemplate() 0 6 1
A guessId() 0 13 3
B stringify() 0 30 10
B stringifyArray() 0 33 7
A stringifyObject() 0 32 5
A getMainMessage() 0 11 3
A setParams() 0 10 2
A setTemplate() 0 12 2

How to fix   Complexity   

Complex Class

Complex classes like ValidationException 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 ValidationException, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of Respect/Validation.
5
 *
6
 * (c) Alexandre Gomes Gaigalas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the "LICENSE.md"
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Respect\Validation\Exceptions;
13
14
use DateTime;
15
use Exception;
16
use InvalidArgumentException;
17
use Traversable;
18
19
class ValidationException extends InvalidArgumentException implements ExceptionInterface
20
{
21
    const MODE_DEFAULT = 1;
22
    const MODE_NEGATIVE = 2;
23
    const STANDARD = 0;
24
    public static $defaultTemplates = [
25
        self::MODE_DEFAULT => [
26
            self::STANDARD => 'Data validation failed for %s',
27
        ],
28
        self::MODE_NEGATIVE => [
29
            self::STANDARD => 'Data validation failed for %s',
30
        ],
31
    ];
32
33
    /**
34
     * @var int
35
     */
36
    private static $maxDepthStringify = 5;
37
38
    /**
39
     * @var int
40
     */
41
    private static $maxCountStringify = 10;
42
43
    /**
44
     * @var string
45
     */
46
    private static $maxReplacementStringify = '...';
47
48
    protected $id = 'validation';
49
    protected $mode = self::MODE_DEFAULT;
50
    protected $name = '';
51
    protected $template = '';
52
    protected $params = [];
53
    private $customTemplate = false;
54
55 8
    public static function format($template, array $vars = [])
56
    {
57 8
        return preg_replace_callback(
58 8
            '/{{(\w+)}}/',
59 8
            function ($match) use ($vars) {
60 7
                if (!isset($vars[$match[1]])) {
61 2
                    return $match[0];
62
                }
63
64 7
                $value = $vars[$match[1]];
65 7
                if ('name' == $match[1] && is_string($value)) {
66 4
                    return $value;
67
                }
68
69 4
                return ValidationException::stringify($value);
70 8
            },
71 8
            $template
72
        );
73
    }
74
75
    /**
76
     * @param mixed $value
77
     * @param int   $depth
78
     *
79
     * @return string
80
     */
81 36
    public static function stringify($value, $depth = 1)
82
    {
83 36
        if ($depth >= self::$maxDepthStringify) {
84
            return self::$maxReplacementStringify;
85
        }
86
87 36
        if (is_array($value)) {
88 20
            return static::stringifyArray($value, $depth);
89
        }
90
91 35
        if (is_object($value)) {
92 9
            return static::stringifyObject($value, $depth);
93
        }
94
95 33
        if (is_resource($value)) {
96 4
            return sprintf('`[resource] (%s)`', get_resource_type($value));
97
        }
98
99 30
        if (is_float($value)) {
100 4
            if (is_infinite($value)) {
101 2
                return ($value > 0 ? '' : '-').'INF';
102
            }
103
104 2
            if (is_nan($value)) {
105 1
                return 'NaN';
106
            }
107
        }
108
109 27
        return (@json_encode($value, (JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)) ?: $value);
110
    }
111
112
    /**
113
     * @param array $value
114
     * @param int   $depth
115
     *
116
     * @return string
117
     */
118 20
    public static function stringifyArray(array $value, $depth = 1)
119
    {
120 20
        $nextDepth = ($depth + 1);
121 20
        if ($nextDepth >= self::$maxDepthStringify) {
122 4
            return self::$maxReplacementStringify;
123
        }
124
125 20
        if (empty($value)) {
126 3
            return '{ }';
127
        }
128
129 18
        $total = count($value);
130 18
        $string = '';
131 18
        $current = 0;
132 18
        foreach ($value as $childKey => $childValue) {
133 18
            if ($current++ >= self::$maxCountStringify) {
134 1
                $string .= self::$maxReplacementStringify;
135 1
                break;
136
            }
137
138 18
            if (!is_int($childKey)) {
139 7
                $string .= sprintf('%s: ', static::stringify($childKey, $nextDepth));
140
            }
141
142 18
            $string .= static::stringify($childValue, $nextDepth);
143
144 18
            if ($current !== $total) {
145 18
                $string .= ', ';
146
            }
147
        }
148
149 18
        return sprintf('{ %s }', $string);
150
    }
151
152
    /**
153
     * @param mixed $value
154
     * @param int   $depth
155
     *
156
     * @return string
157
     */
158 9
    public static function stringifyObject($value, $depth = 2)
159
    {
160 9
        $nextDepth = $depth + 1;
161
162 9
        if ($value instanceof DateTime) {
163 1
            return sprintf('"%s"', $value->format('Y-m-d H:i:s'));
164
        }
165
166 8
        $class = get_class($value);
167
168 8
        if ($value instanceof Traversable) {
169 2
            return sprintf('`[traversable] (%s: %s)`', $class, static::stringify(iterator_to_array($value), $nextDepth));
170
        }
171
172 6
        if ($value instanceof Exception) {
173
            $properties = [
174 1
                'message' => $value->getMessage(),
175 1
                'code' => $value->getCode(),
176 1
                'file' => $value->getFile().':'.$value->getLine(),
177
            ];
178
179 1
            return sprintf('`[exception] (%s: %s)`', $class, static::stringify($properties, $nextDepth));
180
        }
181
182 5
        if (method_exists($value, '__toString')) {
183 1
            return static::stringify($value->__toString(), $nextDepth);
184
        }
185
186 4
        $properties = static::stringify(get_object_vars($value), $nextDepth);
187
188 4
        return sprintf('`[object] (%s: %s)`', $class, str_replace('`', '', $properties));
189
    }
190
191 2
    public function __toString()
192
    {
193 2
        return $this->getMainMessage();
194
    }
195
196 4
    public function chooseTemplate()
197
    {
198 4
        return key(static::$defaultTemplates[$this->mode]);
199
    }
200
201 3
    public function configure($name, array $params = [])
202
    {
203 3
        $this->setName($name);
204 3
        $this->setId($this->guessId());
205 3
        $this->setParams($params);
206
207 3
        return $this;
208
    }
209
210 5
    public function getName()
211
    {
212 5
        return $this->name;
213
    }
214
215 1
    public function getId()
216
    {
217 1
        return $this->id;
218
    }
219
220 5
    public function getMainMessage()
221
    {
222 5
        $vars = $this->getParams();
223 5
        $vars['name'] = $this->getName();
224 5
        $template = $this->getTemplate();
225 5
        if (isset($vars['translator']) && is_callable($vars['translator'])) {
226
            $template = call_user_func($vars['translator'], $template);
227
        }
228
229 5
        return static::format($template, $vars);
230
    }
231
232 1
    public function getParam($name)
233
    {
234 1
        return $this->hasParam($name) ? $this->params[$name] : false;
235
    }
236
237 5
    public function getParams()
238
    {
239 5
        return $this->params;
240
    }
241
242 5
    public function getTemplate()
243
    {
244 5
        if (!empty($this->template)) {
245 4
            return $this->template;
246
        } else {
247 5
            return $this->template = $this->buildTemplate();
248
        }
249
    }
250
251 1
    public function hasParam($name)
252
    {
253 1
        return isset($this->params[$name]);
254
    }
255
256 3
    public function setId($id)
257
    {
258 3
        $this->id = $id;
259
260 3
        return $this;
261
    }
262
263 3
    public function setName($name)
264
    {
265 3
        $this->name = $name;
266
267 3
        return $this;
268
    }
269
270
    public function setMode($mode)
271
    {
272
        $this->mode = $mode;
273
        $this->template = $this->buildTemplate();
274
275
        $this->buildMessage();
276
277
        return $this;
278
    }
279
280
    public function setParam($key, $value)
281
    {
282
        $this->params[$key] = $value;
283
284
        $this->buildMessage();
285
286
        return $this;
287
    }
288
289 3
    public function setParams(array $params)
290
    {
291 3
        foreach ($params as $key => $value) {
292 1
            $this->params[$key] = $value;
293
        }
294
295 3
        $this->buildMessage();
296
297 3
        return $this;
298
    }
299
300
    public function hasCustomTemplate()
301
    {
302
        return (true === $this->customTemplate);
303
    }
304
305 2
    public function setTemplate($template)
306
    {
307 2
        $this->customTemplate = true;
308 2
        if (isset(static::$defaultTemplates[$this->mode][$template])) {
309
            $template = static::$defaultTemplates[$this->mode][$template];
310
        }
311 2
        $this->template = $template;
312
313 2
        $this->buildMessage();
314
315 2
        return $this;
316
    }
317
318 3
    private function buildMessage()
319
    {
320 3
        $this->message = $this->getMainMessage();
321 3
    }
322
323 5
    protected function buildTemplate()
324
    {
325 5
        $templateKey = $this->chooseTemplate();
326
327 5
        return static::$defaultTemplates[$this->mode][$templateKey];
328
    }
329
330 3
    public function guessId()
331
    {
332 3
        if (!empty($this->id) && $this->id != 'validation') {
333
            return $this->id;
334
        }
335
336 3
        $pieces = explode('\\', get_called_class());
337 3
        $exceptionClassShortName = end($pieces);
338 3
        $ruleClassShortName = str_replace('Exception', '', $exceptionClassShortName);
339 3
        $ruleName = lcfirst($ruleClassShortName);
340
341 3
        return $ruleName;
342
    }
343
}
344