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

Passed
Pull Request — master (#957)
by Henrique
02:12
created

NestedValidationException::setParam()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 2
nop 2
dl 0
loc 11
ccs 6
cts 6
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
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
declare(strict_types=1);
13
14
namespace Respect\Validation\Exceptions;
15
16
use IteratorAggregate;
17
use RecursiveIteratorIterator;
18
use SplObjectStorage;
19
use function count;
20
use function is_array;
21
22
class NestedValidationException extends ValidationException implements IteratorAggregate
23
{
24
    /**
25
     * @var SplObjectStorage
26
     */
27
    private $exceptions = [];
28
29
    /**
30
     * @param ValidationException $exception
31
     *
32
     * @return self
33
     */
34 2
    public function addRelated(ValidationException $exception)
35
    {
36 2
        $this->getRelated()->attach($exception);
37
38 2
        return $this;
39
    }
40
41
    /**
42
     * @return RecursiveIteratorIterator
43
     */
44
    private function getRecursiveIterator()
45
    {
46
        $exceptionIterator = new RecursiveExceptionIterator($this);
47
        $recursiveIteratorIterator = new RecursiveIteratorIterator(
48
            $exceptionIterator,
49
            RecursiveIteratorIterator::SELF_FIRST
50
        );
51
52
        return $recursiveIteratorIterator;
53
    }
54
55
    /**
56
     * Returns weather an exception should be omitted or not.
57
     *
58
     * @param Exception $exception
59
     *
60
     * @return bool
61
     */
62
    private function isOmissible(Exception $exception)
63
    {
64
        if (!$exception instanceof self) {
65
            return false;
66
        }
67
68
        $relatedExceptions = $exception->getRelated();
69
        $relatedExceptions->rewind();
70
        $childException = $relatedExceptions->current();
71
72
        return 1 === $relatedExceptions->count() && !$childException instanceof NonOmissibleException;
73
    }
74
75
    /**
76
     * @return SplObjectStorage
77
     */
78
    public function getIterator()
79
    {
80
        $childrenExceptions = new SplObjectStorage();
81
82
        $recursiveIteratorIterator = $this->getRecursiveIterator();
83
        $exceptionIterator = $recursiveIteratorIterator->getInnerIterator();
84
85
        $lastDepth = 0;
86
        $lastDepthOriginal = 0;
87
        $knownDepths = [];
88
        foreach ($recursiveIteratorIterator as $childException) {
89
            if ($this->isOmissible($childException)) {
90
                continue;
91
            }
92
93
            $currentDepth = $lastDepth;
94
            $currentDepthOriginal = $recursiveIteratorIterator->getDepth() + 1;
95
96
            if (isset($knownDepths[$currentDepthOriginal])) {
97
                $currentDepth = $knownDepths[$currentDepthOriginal];
98
            } elseif ($currentDepthOriginal > $lastDepthOriginal
99
                && ($this->hasCustomTemplate() || 1 != $exceptionIterator->count())) {
0 ignored issues
show
Bug introduced by
The method count() does not exist on Iterator. It seems like you code against a sub-type of Iterator such as SplDoublyLinkedList or HttpMessage or HttpRequestPool or Zend\Stdlib\PriorityList or Yaf_Config_Simple or SplFixedArray or SplObjectStorage or Yaf\Session or SQLiteResult or Imagick or TheSeer\Tokenizer\TokenCollection or Yaf_Session or SplPriorityQueue or Yaf\Config\Simple or Yaf\Config\Ini or MongoCursor or Zend\Stdlib\FastPriorityQueue or Yaf_Config_Ini or SplHeap or MongoGridFSCursor or CachingIterator or PHP_Token_Stream or Phar or ArrayIterator or GlobIterator or Phar or Phar or Respect\Validation\Excep...ursiveExceptionIterator or RecursiveCachingIterator or RecursiveArrayIterator or SimpleXMLIterator or Phar. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

99
                && ($this->hasCustomTemplate() || 1 != $exceptionIterator->/** @scrutinizer ignore-call */ count())) {
Loading history...
100
                ++$currentDepth;
101
            }
102
103
            if (!isset($knownDepths[$currentDepthOriginal])) {
104
                $knownDepths[$currentDepthOriginal] = $currentDepth;
105
            }
106
107
            $lastDepth = $currentDepth;
108
            $lastDepthOriginal = $currentDepthOriginal;
109
110
            $childrenExceptions->attach(
111
                $childException,
112
                [
113
                    'depth' => $currentDepth,
114
                    'depth_original' => $currentDepthOriginal,
115
                    'previous_depth' => $lastDepth,
116
                    'previous_depth_original' => $lastDepthOriginal,
117
                ]
118
            );
119
        }
120
121
        return $childrenExceptions;
122
    }
123
124
    public function getMessages(array $templates = []): array
125
    {
126
        $messages = [$this->getId() => $this->renderMessage($this, $templates)];
127
        foreach ($this->getRelated() as $exception) {
128
            $id = $exception->getId();
129
            if (!$exception instanceof self) {
130
                $messages[$id] = $this->renderMessage(
131
                    $exception,
132
                    $this->findTemplates($templates, $this->getId())
133
                );
134
                continue;
135
            }
136
137
            $messages[$id] = $exception->getMessages($this->findTemplates($templates, $id, $this->getId()));
138
            if (count($messages[$id]) > 1) {
0 ignored issues
show
Bug introduced by
$messages[$id] of type string is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

138
            if (count(/** @scrutinizer ignore-type */ $messages[$id]) > 1) {
Loading history...
139
                continue;
140
            }
141
142
            $messages[$id] = current($messages[$exception->getId()]);
0 ignored issues
show
Bug introduced by
$messages[$exception->getId()] of type string is incompatible with the type array expected by parameter $array of current(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

142
            $messages[$id] = current(/** @scrutinizer ignore-type */ $messages[$exception->getId()]);
Loading history...
143
        }
144
145
        if (count($messages) > 1) {
146
            unset($messages[$this->getId()]);
147
        }
148
149
        return $messages;
150
    }
151
152
    /**
153
     * @return string
154
     */
155
    public function getFullMessage()
156
    {
157
        $marker = '-';
158
        $messages = [];
159
        $exceptions = $this->getIterator();
160
161
        if ($this->hasCustomTemplate() || 1 != count($exceptions)) {
162
            $messages[] = sprintf('%s %s', $marker, $this->getMessage());
163
        }
164
165
        foreach ($exceptions as $exception) {
166
            $depth = $exceptions[$exception]['depth'];
167
            $prefix = str_repeat(' ', $depth * 2);
168
            $messages[] = sprintf('%s%s %s', $prefix, $marker, $exception->getMessage());
169
        }
170
171
        return implode(PHP_EOL, $messages);
172
    }
173
174
    /**
175
     * @return SplObjectStorage|ValidationException[]
176
     */
177 2
    public function getRelated()
178
    {
179 2
        if (!$this->exceptions instanceof SplObjectStorage) {
0 ignored issues
show
introduced by
$this->exceptions is always a sub-type of SplObjectStorage. If $this->exceptions can have other possible types, add them to library/Exceptions/NestedValidationException.php:25.
Loading history...
180 2
            $this->exceptions = new SplObjectStorage();
181
        }
182
183 2
        return $this->exceptions;
184
    }
185
186
    /**
187
     * @param array $exceptions
188
     *
189
     * @return self
190
     */
191
    public function setRelated(array $exceptions)
192
    {
193
        foreach ($exceptions as $exception) {
194
            $this->addRelated($exception);
195
        }
196
197
        return $this;
198
    }
199
200
    private function renderMessage(ValidationException $exception, array $templates): string
201
    {
202
        if (isset($templates[$exception->getId()])) {
203
            $exception->updateTemplate($templates[$exception->getId()]);
204
        }
205
206
        return $exception->getMessage();
207
    }
208
209
    private function findTemplates(array $templates, ...$ids): array
210
    {
211
        while (count($ids) > 0) {
212
            $id = array_shift($ids);
213
            if (isset($templates[$id]) && is_array($templates[$id])) {
214
                $templates = $templates[$id];
215
            }
216
        }
217
218
        return $templates;
219
    }
220
}
221