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:42
created

NestedValidationException::renderMessage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 2
crap 6
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 Exception;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Respect\Validation\Exceptions\Exception. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
17
use IteratorAggregate;
18
use RecursiveIteratorIterator;
19
use SplObjectStorage;
20
use function count;
21
use function is_array;
22
23
class NestedValidationException extends ValidationException implements IteratorAggregate
24
{
25
    /**
26
     * @var SplObjectStorage|ValidationException[]
27
     */
28
    private $exceptions = [];
29
30
    /**
31
     * @return SplObjectStorage|ValidationException[]
32
     */
33 2
    public function getRelated(): SplObjectStorage
34
    {
35 2
        if (!$this->exceptions instanceof SplObjectStorage) {
36 2
            $this->exceptions = new SplObjectStorage();
37
        }
38
39 2
        return $this->exceptions;
40
    }
41
42
    /**
43
     * @param array $exceptions
44
     *
45
     * @return self
46
     */
47
    public function setRelated(array $exceptions): self
48
    {
49
        foreach ($exceptions as $exception) {
50
            $this->addRelated($exception);
51
        }
52
53
        return $this;
54
    }
55
56
    /**
57
     * @param ValidationException $exception
58
     *
59
     * @return self
60
     */
61 2
    public function addRelated(ValidationException $exception)
62
    {
63 2
        $this->getRelated()->attach($exception);
64
65 2
        return $this;
66
    }
67
68
    /**
69
     * @return SplObjectStorage|ValidationException[]
70
     */
71
    public function getIterator(): SplObjectStorage
72
    {
73
        $childrenExceptions = new SplObjectStorage();
74
75
        $recursiveIteratorIterator = new RecursiveIteratorIterator(
76
            new RecursiveExceptionIterator($this),
77
            RecursiveIteratorIterator::SELF_FIRST
78
        );
79
        $innerIterator = $recursiveIteratorIterator->getInnerIterator();
80
        $iterator = new OmissibleFilterIterator($recursiveIteratorIterator);
81
82
        $currentDepth = 0;
83
        $originalLastDepth = 0;
84
        $knownDepths = [];
85
        foreach ($iterator as $childException) {
86
            $originalCurrentDepth = $recursiveIteratorIterator->getDepth() + 1;
87
            if (isset($knownDepths[$originalCurrentDepth])) {
88
                $currentDepth = $knownDepths[$originalCurrentDepth];
89
            } elseif ($originalCurrentDepth > $originalLastDepth
90
                && ($this->hasCustomTemplate() || 1 !== $innerIterator->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

90
                && ($this->hasCustomTemplate() || 1 !== $innerIterator->/** @scrutinizer ignore-call */ count())) {
Loading history...
91
                $knownDepths[$originalCurrentDepth] = ++$currentDepth;
92
            }
93
94
            $childrenExceptions->attach($childException, $currentDepth);
95
96
            $originalLastDepth = $originalCurrentDepth;
97
        }
98
99
        return $childrenExceptions;
100
    }
101
102
    public function getMessages(array $templates = []): array
103
    {
104
        $messages = [$this->getId() => $this->renderMessage($this, $templates)];
105
        foreach ($this->getRelated() as $exception) {
106
            $id = $exception->getId();
107
            if (!$exception instanceof self) {
108
                $messages[$id] = $this->renderMessage(
109
                    $exception,
110
                    $this->findTemplates($templates, $this->getId())
111
                );
112
                continue;
113
            }
114
115
            $messages[$id] = $exception->getMessages($this->findTemplates($templates, $id, $this->getId()));
116
            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

116
            if (count(/** @scrutinizer ignore-type */ $messages[$id]) > 1) {
Loading history...
117
                continue;
118
            }
119
120
            $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

120
            $messages[$id] = current(/** @scrutinizer ignore-type */ $messages[$exception->getId()]);
Loading history...
121
        }
122
123
        if (count($messages) > 1) {
124
            unset($messages[$this->getId()]);
125
        }
126
127
        return $messages;
128
    }
129
130
    /**
131
     * @return string
132
     */
133
    public function getFullMessage(): string
134
    {
135
        $marker = '-';
136
        $messages = [];
137
        $exceptions = $this->getIterator();
138
139
        if ($this->hasCustomTemplate() || 1 != count($exceptions)) {
140
            $messages[] = sprintf('%s %s', $marker, $this->getMessage());
141
        }
142
143
        foreach ($exceptions as $exception) {
144
            $prefix = str_repeat(' ', $exceptions[$exception] * 2);
145
            $messages[] = sprintf('%s%s %s', $prefix, $marker, $exception->getMessage());
146
        }
147
148
        return implode(PHP_EOL, $messages);
149
    }
150
151
    private function getRecursiveIterator(): RecursiveIteratorIterator
0 ignored issues
show
Unused Code introduced by
The method getRecursiveIterator() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
152
    {
153
        $exceptionIterator = new RecursiveExceptionIterator($this);
154
        $recursiveIteratorIterator = new RecursiveIteratorIterator(
155
            $exceptionIterator,
156
            RecursiveIteratorIterator::SELF_FIRST
157
        );
158
159
        return $recursiveIteratorIterator;
160
    }
161
162
    private function renderMessage(ValidationException $exception, array $templates): string
163
    {
164
        if (isset($templates[$exception->getId()])) {
165
            $exception->updateTemplate($templates[$exception->getId()]);
166
        }
167
168
        return $exception->getMessage();
169
    }
170
171
    private function findTemplates(array $templates, ...$ids): array
172
    {
173
        while (count($ids) > 0) {
174
            $id = array_shift($ids);
175
            if (isset($templates[$id]) && is_array($templates[$id])) {
176
                $templates = $templates[$id];
177
            }
178
        }
179
180
        return $templates;
181
    }
182
}
183