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 ( 7b5a29...47eaea )
by Henrique
02:52
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 121
    public function addRelated(ValidationException $exception)
33
    {
34 121
        $this->getRelated()->attach($exception);
35
36 121
        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 116
    private function getRecursiveIterator()
117
    {
118 116
        $exceptionIterator = new RecursiveExceptionIterator($this);
119 116
        $recursiveIteratorIterator = new RecursiveIteratorIterator(
120 116
            $exceptionIterator,
121 116
            RecursiveIteratorIterator::SELF_FIRST
122
        );
123
124 116
        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 110
    private function isOmissible(ExceptionInterface $exception)
135
    {
136 110
        if (!$exception instanceof self) {
137 104
            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 111
    public function getIterator()
151
    {
152 111
        $childrenExceptions = new SplObjectStorage();
153
154 111
        $recursiveIteratorIterator = $this->getRecursiveIterator();
155 111
        $exceptionIterator = $recursiveIteratorIterator->getInnerIterator();
156
157 111
        $lastDepth = 0;
158 111
        $lastDepthOriginal = 0;
159 111
        $knownDepths = [];
160 111
        foreach ($recursiveIteratorIterator as $childException) {
161 110
            if ($this->isOmissible($childException)) {
162 11
                continue;
163
            }
164
165 110
            $currentDepth = $lastDepth;
166 110
            $currentDepthOriginal = $recursiveIteratorIterator->getDepth() + 1;
167
168 110
            if (isset($knownDepths[$currentDepthOriginal])) {
169 13
                $currentDepth = $knownDepths[$currentDepthOriginal];
170 110
            } elseif ($currentDepthOriginal > $lastDepthOriginal
171 110
                && ($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

171
                && ($this->hasCustomTemplate() || 1 != $exceptionIterator->/** @scrutinizer ignore-call */ count())) {
Loading history...
172 13
                ++$currentDepth;
173
            }
174
175 110
            if (!isset($knownDepths[$currentDepthOriginal])) {
176 110
                $knownDepths[$currentDepthOriginal] = $currentDepth;
177
            }
178
179 110
            $lastDepth = $currentDepth;
180 110
            $lastDepthOriginal = $currentDepthOriginal;
181
182 110
            $childrenExceptions->attach(
183 110
                $childException,
184
                [
185 110
                    'depth' => $currentDepth,
186 110
                    'depth_original' => $currentDepthOriginal,
187 110
                    'previous_depth' => $lastDepth,
188 110
                    'previous_depth_original' => $lastDepthOriginal,
189
                ]
190
            );
191
        }
192
193 111
        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 104
    public function getFullMessage()
217
    {
218 104
        $marker = '-';
219 104
        $messages = [];
220 104
        $exceptions = $this->getIterator();
221
222 104
        if ($this->hasCustomTemplate() || 1 != count($exceptions)) {
223 11
            $messages[] = sprintf('%s %s', $marker, $this->getMessage());
224
        }
225
226 104
        foreach ($exceptions as $exception) {
227 103
            $depth = $exceptions[$exception]['depth'];
228 103
            $prefix = str_repeat(' ', $depth * 2);
229 103
            $messages[] = sprintf('%s%s %s', $prefix, $marker, $exception->getMessage());
230
        }
231
232 104
        return implode(PHP_EOL, $messages);
233
    }
234
235
    /**
236
     * @return SplObjectStorage
237
     */
238 122
    public function getRelated()
239
    {
240 122
        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:23.
Loading history...
241 122
            $this->exceptions = new SplObjectStorage();
242
        }
243
244 122
        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 118
    public function setRelated(array $exceptions)
296
    {
297 118
        foreach ($exceptions as $exception) {
298 118
            $this->addRelated($exception);
299
        }
300
301 118
        return $this;
302
    }
303
}
304