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 — master (#1034)
by Henrique
02:29
created

NestedValidationException::getIterator()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 8

Importance

Changes 0
Metric Value
dl 0
loc 44
ccs 28
cts 28
cp 1
rs 7.9715
c 0
b 0
f 0
cc 8
nc 8
nop 0
crap 8
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 136
    public function addRelated(ValidationException $exception)
35
    {
36 136
        $this->getRelated()->attach($exception);
37
38 136
        return $this;
39
    }
40
41
    /**
42
     * @return RecursiveIteratorIterator
43
     */
44 124
    private function getRecursiveIterator()
45
    {
46 124
        $exceptionIterator = new RecursiveExceptionIterator($this);
47 124
        $recursiveIteratorIterator = new RecursiveIteratorIterator(
48 124
            $exceptionIterator,
49 124
            RecursiveIteratorIterator::SELF_FIRST
50
        );
51
52 124
        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 123
    private function isOmissible(Exception $exception)
63
    {
64 123
        if (!$exception instanceof self) {
65 115
            return false;
66
        }
67
68 13
        $relatedExceptions = $exception->getRelated();
69 13
        $relatedExceptions->rewind();
70 13
        $childException = $relatedExceptions->current();
71
72 13
        return 1 === $relatedExceptions->count() && !$childException instanceof NonOmissibleException;
73
    }
74
75
    /**
76
     * @return SplObjectStorage
77
     */
78 124
    public function getIterator()
79
    {
80 124
        $childrenExceptions = new SplObjectStorage();
81
82 124
        $recursiveIteratorIterator = $this->getRecursiveIterator();
83 124
        $exceptionIterator = $recursiveIteratorIterator->getInnerIterator();
84
85 124
        $lastDepth = 0;
86 124
        $lastDepthOriginal = 0;
87 124
        $knownDepths = [];
88 124
        foreach ($recursiveIteratorIterator as $childException) {
89 123
            if ($this->isOmissible($childException)) {
90 5
                continue;
91
            }
92
93 123
            $currentDepth = $lastDepth;
94 123
            $currentDepthOriginal = $recursiveIteratorIterator->getDepth() + 1;
95
96 123
            if (isset($knownDepths[$currentDepthOriginal])) {
97 9
                $currentDepth = $knownDepths[$currentDepthOriginal];
98 123
            } elseif ($currentDepthOriginal > $lastDepthOriginal
99 123
                && ($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 10
                ++$currentDepth;
101
            }
102
103 123
            if (!isset($knownDepths[$currentDepthOriginal])) {
104 123
                $knownDepths[$currentDepthOriginal] = $currentDepth;
105
            }
106
107 123
            $lastDepth = $currentDepth;
108 123
            $lastDepthOriginal = $currentDepthOriginal;
109
110 123
            $childrenExceptions->attach(
111 123
                $childException,
112
                [
113 123
                    'depth' => $currentDepth,
114 123
                    'depth_original' => $currentDepthOriginal,
115 123
                    'previous_depth' => $lastDepth,
116 123
                    'previous_depth_original' => $lastDepthOriginal,
117
                ]
118
            );
119
        }
120
121 124
        return $childrenExceptions;
122
    }
123
124 7
    public function getMessages(array $templates = []): array
125
    {
126 7
        $messages = [$this->getId() => $this->renderMessage($this, $templates)];
127 7
        foreach ($this->getRelated() as $exception) {
128 7
            $id = $exception->getId();
129 7
            if (!$exception instanceof self) {
130 7
                $messages[$id] = $this->renderMessage(
131 7
                    $exception,
132 7
                    $this->findTemplates($templates, $this->getId())
133
                );
134 7
                continue;
135
            }
136
137 4
            $messages[$id] = $exception->getMessages($this->findTemplates($templates, $id, $this->getId()));
138 4
            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 2
                continue;
140
            }
141
142 4
            $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 7
        if (count($messages) > 1) {
146 7
            unset($messages[$this->getId()]);
147
        }
148
149 7
        return $messages;
150
    }
151
152
    /**
153
     * @return string
154
     */
155 124
    public function getFullMessage()
156
    {
157 124
        $marker = '-';
158 124
        $messages = [];
159 124
        $exceptions = $this->getIterator();
160
161 124
        if ($this->hasCustomTemplate() || 1 != count($exceptions)) {
162 11
            $messages[] = sprintf('%s %s', $marker, $this->getMessage());
163
        }
164
165 124
        foreach ($exceptions as $exception) {
166 123
            $depth = $exceptions[$exception]['depth'];
167 123
            $prefix = str_repeat(' ', $depth * 2);
168 123
            $messages[] = sprintf('%s%s %s', $prefix, $marker, $exception->getMessage());
169
        }
170
171 124
        return implode(PHP_EOL, $messages);
172
    }
173
174
    /**
175
     * @return SplObjectStorage|ValidationException[]
176
     */
177 137
    public function getRelated()
178
    {
179 137
        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 137
            $this->exceptions = new SplObjectStorage();
181
        }
182
183 137
        return $this->exceptions;
184
    }
185
186
    /**
187
     * @param array $exceptions
188
     *
189
     * @return self
190
     */
191 134
    public function setRelated(array $exceptions)
192
    {
193 134
        foreach ($exceptions as $exception) {
194 134
            $this->addRelated($exception);
195
        }
196
197 134
        return $this;
198
    }
199
200 7
    private function renderMessage(ValidationException $exception, array $templates): string
201
    {
202 7
        if (isset($templates[$exception->getId()])) {
203 2
            $exception->updateTemplate($templates[$exception->getId()]);
204
        }
205
206 7
        return $exception->getMessage();
207
    }
208
209 7
    private function findTemplates(array $templates, ...$ids): array
210
    {
211 7
        while (count($ids) > 0) {
212 7
            $id = array_shift($ids);
213 7
            if (isset($templates[$id]) && is_array($templates[$id])) {
214 1
                $templates = $templates[$id];
215
            }
216
        }
217
218 7
        return $templates;
219
    }
220
}
221