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 (#1062)
by Henrique
03:30
created

NestedValidationException::renderMessage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
c 0
b 0
f 0
ccs 4
cts 4
cp 1
rs 10
cc 2
nc 2
nop 2
crap 2
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 const PHP_EOL;
20
use function count;
21
use function implode;
22
use function is_array;
23
use function str_repeat;
24
25
class NestedValidationException extends ValidationException implements IteratorAggregate
26
{
27
    /**
28
     * @var SplObjectStorage
29
     */
30
    private $exceptions = [];
31
32
    /**
33
     * @param ValidationException $exception
34
     *
35
     * @return self
36
     */
37 142
    public function addRelated(ValidationException $exception)
38
    {
39 142
        $this->getRelated()->attach($exception);
40
41 142
        return $this;
42
    }
43
44
    /**
45
     * @return RecursiveIteratorIterator
46
     */
47 129
    private function getRecursiveIterator()
48
    {
49 129
        $exceptionIterator = new RecursiveExceptionIterator($this);
50 129
        $recursiveIteratorIterator = new RecursiveIteratorIterator(
51 129
            $exceptionIterator,
52 129
            RecursiveIteratorIterator::SELF_FIRST
53
        );
54
55 129
        return $recursiveIteratorIterator;
56
    }
57
58
    /**
59
     * Returns weather an exception should be omitted or not.
60
     *
61
     * @param Exception $exception
62
     *
63
     * @return bool
64
     */
65 129
    private function isOmissible(Exception $exception): bool
66
    {
67 129
        if (!$exception instanceof self) {
68 121
            return false;
69
        }
70
71 129
        if (1 !== $exception->getRelated()->count()) {
72 19
            return false;
73
        }
74
75 124
        $exception->getRelated()->rewind();
76 124
        $childException = $exception->getRelated()->current();
77 124
        if ($childException->getMessage() === $exception->getMessage()) {
78 2
            return true;
79
        }
80
81 123
        if ($exception->hasCustomTemplate()) {
82
            return $childException->hasCustomTemplate();
83
        }
84
85 123
        return !$childException instanceof NonOmissibleException;
86
    }
87
88
    /**
89
     * @return SplObjectStorage
90
     */
91 129
    public function getIterator()
92
    {
93 129
        $childrenExceptions = new SplObjectStorage();
94
95 129
        $recursiveIteratorIterator = $this->getRecursiveIterator();
96
97 129
        $lastDepth = 0;
98 129
        $lastDepthOriginal = 0;
99 129
        $knownDepths = [];
100 129
        foreach ($recursiveIteratorIterator as $childException) {
101 128
            if ($this->isOmissible($childException)) {
102 6
                continue;
103
            }
104
105 128
            $currentDepth = $lastDepth;
106 128
            $currentDepthOriginal = $recursiveIteratorIterator->getDepth() + 1;
107
108 128
            if (isset($knownDepths[$currentDepthOriginal])) {
109 10
                $currentDepth = $knownDepths[$currentDepthOriginal];
110 128
            } elseif ($currentDepthOriginal > $lastDepthOriginal) {
111 128
                ++$currentDepth;
112
            }
113
114 128
            if (!isset($knownDepths[$currentDepthOriginal])) {
115 128
                $knownDepths[$currentDepthOriginal] = $currentDepth;
116
            }
117
118 128
            $lastDepth = $currentDepth;
119 128
            $lastDepthOriginal = $currentDepthOriginal;
120
121 128
            $childrenExceptions->attach(
122 128
                $childException,
123
                [
124 128
                    'depth' => $currentDepth,
125 128
                    'depth_original' => $currentDepthOriginal,
126 128
                    'previous_depth' => $lastDepth,
127 128
                    'previous_depth_original' => $lastDepthOriginal,
128
                ]
129
            );
130
        }
131
132 129
        return $childrenExceptions;
133
    }
134
135 8
    public function getMessages(array $templates = []): array
136
    {
137 8
        $messages = [$this->getId() => $this->renderMessage($this, $templates)];
138 8
        foreach ($this->getRelated() as $exception) {
139 8
            $id = $exception->getId();
140 8
            if (!$exception instanceof self) {
141 8
                $messages[$id] = $this->renderMessage(
142 8
                    $exception,
143 8
                    $this->findTemplates($templates, $this->getId())
144
                );
145 8
                continue;
146
            }
147
148 5
            $messages[$id] = $exception->getMessages($this->findTemplates($templates, $id, $this->getId()));
149 5
            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

149
            if (count(/** @scrutinizer ignore-type */ $messages[$id]) > 1) {
Loading history...
150 2
                continue;
151
            }
152
153 5
            $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

153
            $messages[$id] = current(/** @scrutinizer ignore-type */ $messages[$exception->getId()]);
Loading history...
154
        }
155
156 8
        if (count($messages) > 1) {
157 8
            unset($messages[$this->getId()]);
158
        }
159
160 8
        return $messages;
161
    }
162
163
    /**
164
     * @return string
165
     */
166 129
    public function getFullMessage()
167
    {
168 129
        $messages = [];
169 129
        $leveler = 1;
170
171 129
        if (!$this->isOmissible($this)) {
172 11
            $leveler = 0;
173 11
            $messages[] = sprintf('- %s', $this->getMessage());
174
        }
175
176 129
        $exceptions = $this->getIterator();
177 129
        foreach ($exceptions as $exception) {
178 128
            $messages[] = sprintf(
179 128
                '%s- %s',
180 128
                str_repeat(' ', ($exceptions[$exception]['depth'] - $leveler) * 2),
181 128
                $exception->getMessage()
182
            );
183
        }
184
185 129
        return implode(PHP_EOL, $messages);
186
    }
187
188
    /**
189
     * @return SplObjectStorage|ValidationException[]
190
     */
191 143
    public function getRelated()
192
    {
193 143
        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:28.
Loading history...
194 143
            $this->exceptions = new SplObjectStorage();
195
        }
196
197 143
        return $this->exceptions;
198
    }
199
200
    /**
201
     * @param array $exceptions
202
     *
203
     * @return self
204
     */
205 140
    public function setRelated(array $exceptions)
206
    {
207 140
        foreach ($exceptions as $exception) {
208 140
            $this->addRelated($exception);
209
        }
210
211 140
        return $this;
212
    }
213
214 8
    private function renderMessage(ValidationException $exception, array $templates): string
215
    {
216 8
        if (isset($templates[$exception->getId()])) {
217 2
            $exception->updateTemplate($templates[$exception->getId()]);
218
        }
219
220 8
        return $exception->getMessage();
221
    }
222
223 8
    private function findTemplates(array $templates, ...$ids): array
224
    {
225 8
        while (count($ids) > 0) {
226 8
            $id = array_shift($ids);
227 8
            if (isset($templates[$id]) && is_array($templates[$id])) {
228 1
                $templates = $templates[$id];
229
            }
230
        }
231
232 8
        return $templates;
233
    }
234
}
235