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
Push — master ( 92a8ab...51ce46 )
by Henrique
08:30 queued 05:04
created

NestedValidationException::getRelatedByName()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 4
nop 1
dl 0
loc 9
ccs 6
cts 6
cp 1
crap 4
rs 9.2
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
20
class NestedValidationException extends ValidationException implements IteratorAggregate
21
{
22
    /**
23
     * @var SplObjectStorage
24
     */
25
    private $exceptions = [];
26
27
    /**
28
     * @param ValidationException $exception
29
     *
30
     * @return self
31
     */
32 130
    public function addRelated(ValidationException $exception)
33
    {
34 130
        $this->getRelated()->attach($exception);
35
36 130
        return $this;
37
    }
38
39
    /**
40
     * @param string              $path
41
     * @param ValidationException $exception
42
     *
43
     * @return ValidationException
44
     */
45 8
    private function getExceptionForPath($path, ValidationException $exception)
46
    {
47 8
        if ($path === $exception->guessId()) {
48 5
            return $exception;
49
        }
50
51 6
        if (!$exception instanceof self) {
52 2
            return $exception;
53
        }
54
55 4
        foreach ($exception as $subException) {
56 4
            return $subException;
57
        }
58
59 1
        return $exception;
60
    }
61
62
    /**
63
     * @param array $paths
64
     *
65
     * @return string[]
66
     */
67 8
    public function findMessages(array $paths)
68
    {
69 8
        $messages = [];
70
71 8
        foreach ($paths as $key => $value) {
72 8
            $numericKey = is_numeric($key);
73 8
            $path = $numericKey ? $value : $key;
74
75 8
            if (!($exception = $this->getRelatedByName($path))) {
76 4
                $exception = $this->findRelated($path);
77
            }
78
79 8
            $path = str_replace('.', '_', $path);
80
81 8
            if (!$exception) {
82 1
                $messages[$path] = '';
83 1
                continue;
84
            }
85
86 8
            $exception = $this->getExceptionForPath($path, $exception);
87 8
            if (!$numericKey) {
88 4
                $exception->setTemplate($value);
89
            }
90
91 8
            $messages[$path] = $exception->getMainMessage();
92
        }
93
94 8
        return $messages;
95
    }
96
97
    /**
98
     * @return Exception
99
     */
100 5
    public function findRelated($path)
101
    {
102 5
        $target = $this;
103 5
        $pieces = explode('.', $path);
104
105 5
        while (!empty($pieces) && $target) {
106 5
            $piece = array_shift($pieces);
107 5
            $target = $target->getRelatedByName($piece);
108
        }
109
110 5
        return $target;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $target returns the type Respect\Validation\Excep...stedValidationException which is incompatible with the documented return type Respect\Validation\Exceptions\Exception.
Loading history...
111
    }
112
113
    /**
114
     * @return RecursiveIteratorIterator
115
     */
116 125
    private function getRecursiveIterator()
117
    {
118 125
        $exceptionIterator = new RecursiveExceptionIterator($this);
119 125
        $recursiveIteratorIterator = new RecursiveIteratorIterator(
120 125
            $exceptionIterator,
121 125
            RecursiveIteratorIterator::SELF_FIRST
122
        );
123
124 125
        return $recursiveIteratorIterator;
125
    }
126
127
    /**
128
     * Returns weather an exception should be omitted or not.
129
     *
130
     * @param ExceptionInterface $exception
131
     *
132
     * @return bool
133
     */
134 119
    private function isOmissible(ExceptionInterface $exception)
135
    {
136 119
        if (!$exception instanceof self) {
137 117
            return false;
138
        }
139
140 17
        $relatedExceptions = $exception->getRelated();
141 17
        $relatedExceptions->rewind();
142 17
        $childException = $relatedExceptions->current();
143
144 17
        return 1 === $relatedExceptions->count() && !$childException instanceof NonOmissibleExceptionInterface;
145
    }
146
147
    /**
148
     * @return SplObjectStorage
149
     */
150 120
    public function getIterator()
151
    {
152 120
        $childrenExceptions = new SplObjectStorage();
153
154 120
        $recursiveIteratorIterator = $this->getRecursiveIterator();
155 120
        $exceptionIterator = $recursiveIteratorIterator->getInnerIterator();
156
157 120
        $lastDepth = 0;
158 120
        $lastDepthOriginal = 0;
159 120
        $knownDepths = [];
160 120
        foreach ($recursiveIteratorIterator as $childException) {
161 119
            if ($this->isOmissible($childException)) {
162 15
                continue;
163
            }
164
165 119
            $currentDepth = $lastDepth;
166 119
            $currentDepthOriginal = $recursiveIteratorIterator->getDepth() + 1;
167
168 119
            if (isset($knownDepths[$currentDepthOriginal])) {
169 13
                $currentDepth = $knownDepths[$currentDepthOriginal];
170 119
            } elseif ($currentDepthOriginal > $lastDepthOriginal
171 119
                && ($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 SplFixedArray or SplObjectStorage or SQLiteResult or Imagick or TheSeer\Tokenizer\TokenCollection or SplPriorityQueue or MongoCursor or Zend\Stdlib\FastPriorityQueue 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

171
                && ($this->hasCustomTemplate() || 1 != $exceptionIterator->/** @scrutinizer ignore-call */ count())) {
Loading history...
172 13
                ++$currentDepth;
173
            }
174
175 119
            if (!isset($knownDepths[$currentDepthOriginal])) {
176 119
                $knownDepths[$currentDepthOriginal] = $currentDepth;
177
            }
178
179 119
            $lastDepth = $currentDepth;
180 119
            $lastDepthOriginal = $currentDepthOriginal;
181
182 119
            $childrenExceptions->attach(
183 119
                $childException,
184
                [
185 119
                    'depth' => $currentDepth,
186 119
                    'depth_original' => $currentDepthOriginal,
187 119
                    'previous_depth' => $lastDepth,
188 119
                    'previous_depth_original' => $lastDepthOriginal,
189
                ]
190
            );
191
        }
192
193 120
        return $childrenExceptions;
194
    }
195
196
    /**
197
     * @return array
198
     */
199 4
    public function getMessages()
200
    {
201 4
        $messages = [$this->getMessage()];
202 4
        foreach ($this as $exception) {
203 4
            $messages[] = $exception->getMessage();
204
        }
205
206 4
        if (count($messages) > 1) {
207 4
            array_shift($messages);
208
        }
209
210 4
        return $messages;
211
    }
212
213
    /**
214
     * @return string
215
     */
216 113
    public function getFullMessage()
217
    {
218 113
        $marker = '-';
219 113
        $messages = [];
220 113
        $exceptions = $this->getIterator();
221
222 113
        if ($this->hasCustomTemplate() || 1 != count($exceptions)) {
223 11
            $messages[] = sprintf('%s %s', $marker, $this->getMessage());
224
        }
225
226 113
        foreach ($exceptions as $exception) {
227 112
            $depth = $exceptions[$exception]['depth'];
228 112
            $prefix = str_repeat(' ', $depth * 2);
229 112
            $messages[] = sprintf('%s%s %s', $prefix, $marker, $exception->getMessage());
230
        }
231
232 113
        return implode(PHP_EOL, $messages);
233
    }
234
235
    /**
236
     * @return SplObjectStorage
237
     */
238 131
    public function getRelated()
239
    {
240 131
        if (!$this->exceptions instanceof SplObjectStorage) {
0 ignored issues
show
introduced by
The condition ! $this->exceptions instanceof SplObjectStorage can never be true.
Loading history...
241 131
            $this->exceptions = new SplObjectStorage();
242
        }
243
244 131
        return $this->exceptions;
245
    }
246
247
    /**
248
     * @param string $name
249
     * @param mixed  $value
250
     *
251
     * @return self
252
     */
253 1
    public function setParam($name, $value)
254
    {
255 1
        if ('translator' === $name) {
256 1
            foreach ($this->getRelated() as $exception) {
257 1
                $exception->setParam($name, $value);
258
            }
259
        }
260
261 1
        parent::setParam($name, $value);
262
263 1
        return $this;
264
    }
265
266
    /**
267
     * @return bool
268
     */
269 9
    private function isRelated($name, ValidationException $exception)
270
    {
271 9
        return $exception->getId() === $name || $exception->getName() === $name;
272
    }
273
274
    /**
275
     * @return ValidationException
276
     */
277 9
    public function getRelatedByName($name)
278
    {
279 9
        if ($this->isRelated($name, $this)) {
280 2
            return $this;
281
        }
282
283 9
        foreach ($this->getRecursiveIterator() as $exception) {
284 9
            if ($this->isRelated($name, $exception)) {
285 9
                return $exception;
286
            }
287
        }
288 5
    }
289
290
    /**
291
     * @param array $exceptions
292
     *
293
     * @return self
294
     */
295 127
    public function setRelated(array $exceptions)
296
    {
297 127
        foreach ($exceptions as $exception) {
298 127
            $this->addRelated($exception);
299
        }
300
301 127
        return $this;
302
    }
303
}
304