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 (#678)
by Henrique
02:58
created

Message::normalizeResource()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
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
namespace Respect\Validation;
13
14
use DateTimeInterface;
15
use Exception;
16
use Respect\Validation\Annotations\Template;
17
use Traversable;
18
19
final class Message
20
{
21
    /**
22
     * @var int
23
     */
24
    const MAX_DEPTH = 3;
25
26
    /**
27
     * @var int
28
     */
29
    const MAX_CHILDREN = 5;
30
31
    /**
32
     * @var string
33
     */
34
    private $ruleName;
35
36
    /**
37
     * @var string
38
     */
39
    private $template;
40
41
    /**
42
     * @var mixed
43
     */
44
    private $input;
45
46
    /**
47
     * @var array
48
     */
49
    private $properties;
50
51
    /**
52
     * @var bool
53
     */
54
    private $isIgnorable;
55
56
    /**
57
     * Initializes the object.
58
     *
59
     * @param string $ruleName
60
     * @param string $template
61
     * @param mixed  $input
62
     * @param array  $properties
63
     * @param bool   $isIgnorable
64
     */
65
    public function __construct(string $ruleName, string $template, $input, array $properties = [], bool $isIgnorable = false)
66
    {
67
        $this->ruleName = $ruleName;
68
        $this->template = $template;
69
        $this->input = $input;
70
        $this->properties = $properties;
71
        $this->isIgnorable = $isIgnorable;
72
    }
73
74
    /**
75
     * @return string
76
     */
77
    public function getRuleName(): string
78
    {
79
        return $this->ruleName;
80
    }
81
82
    /**
83
     * @return bool
84
     */
85
    public function isIgnorable(): bool
86
    {
87
        return $this->isIgnorable;
88
    }
89
90
    public function __toString(): string
91
    {
92
        $properties = $this->properties + ['placeholder' => $this->normalize($this->input)];
93
94
        return preg_replace_callback(
95
            '/{{(\w+)}}/',
96
            function ($matches) use ($properties) {
97
                $value = $matches[0];
98
                if (array_key_exists($matches[1], $properties)) {
99
                    $value = $properties[$matches[1]];
100
                }
101
102
                if ($matches[1] === 'placeholder' && is_string($value)) {
103
                    return $value;
104
                }
105
106
                return $this->normalize($value);
107
            },
108
            $this->template
109
        );
110
    }
111
112
    private function quoteCode(string $string, $currentDepth): string
113
    {
114
        if ($currentDepth === 0) {
115
            $string = sprintf('`%s`', $string);
116
        }
117
118
        return $string;
119
    }
120
121
    private function normalize($raw, int $currentDepth = 0): string
122
    {
123
        if (is_object($raw)) {
124
            return $this->normalizeObject($raw, $currentDepth);
125
        }
126
127
        if (is_array($raw)) {
128
            return $this->normalizeArray($raw, $currentDepth);
129
        }
130
131
        if (is_float($raw)) {
132
            return $this->normalizeFloat($raw, $currentDepth);
133
        }
134
135
        if (is_resource($raw)) {
136
            return $this->normalizeResource($raw, $currentDepth);
137
        }
138
139
        if (is_bool($raw)) {
140
            return $this->normalizeBool($raw, $currentDepth);
141
        }
142
143
        return json_encode($raw, (JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
144
    }
145
146
    private function normalizeObject($object, int $currentDepth): string
147
    {
148
        $nextDepth = $currentDepth + 1;
149
150
        if ($object instanceof Traversable) {
151
            $array = iterator_to_array($object);
152
            $normalized = sprintf('[traversable] (%s: %s)', get_class($object), $this->normalize($array, $nextDepth));
153
154
            return $this->quoteCode($normalized, $currentDepth);
155
        }
156
157
        if ($object instanceof DateTimeInterface) {
158
            return sprintf('"%s"', $object->format('c'));
159
        }
160
161
        if ($object instanceof Exception) {
162
            $normalized = $this->normalizeException($object, $nextDepth);
163
164
            return $this->quoteCode($normalized, $currentDepth);
165
        }
166
167
        if (method_exists($object, '__toString')) {
168
            return $this->normalize($object->__toString(), $nextDepth);
169
        }
170
171
        $normalized = sprintf(
172
            '[object] (%s: %s)',
173
            get_class($object),
174
            $this->normalize(get_object_vars($object), $currentDepth)
175
        );
176
177
        return $this->quoteCode($normalized, $currentDepth);
178
    }
179
180
    private function normalizeException(Exception $exception, int $currentDepth): string
181
    {
182
        $properties = [
183
            'message' => $exception->getMessage(),
184
            'code' => $exception->getCode(),
185
            'file' => str_replace(getcwd().'/', '', $exception->getFile()).':'.$exception->getLine(),
186
        ];
187
188
        return sprintf('[exception] (%s: %s)', get_class($exception), $this->normalize($properties, $currentDepth));
189
    }
190
191
    private function normalizeArray(array $array, int $currentDepth): string
192
    {
193
        if ($currentDepth >= self::MAX_DEPTH) {
194
            return '...';
195
        }
196
197
        if (empty($array)) {
198
            return '{ }';
199
        }
200
201
        $string = '';
202
        $total = count($array);
203
        $current = 0;
204
        $nextDepth = $currentDepth + 1;
205
        foreach ($array as $key => $value) {
206
            if ($current++ >= self::MAX_CHILDREN) {
207
                $string .= ' ... ';
208
                break;
209
            }
210
211
            if (!is_int($key)) {
212
                $string .= sprintf('%s: ', $this->normalize($key, $nextDepth));
213
            }
214
215
            $string .= $this->normalize($value, $nextDepth);
216
217
            if ($current !== $total) {
218
                $string .= ', ';
219
            }
220
        }
221
222
        return sprintf('{ %s }', $string);
223
    }
224
225
    private function normalizeFloat(float $float, int $currentDepth): string
226
    {
227
        if (is_infinite($float)) {
228
            return $this->quoteCode(($float > 0 ? '' : '-').'INF', $currentDepth);
229
        }
230
231
        if (is_nan($float)) {
232
            return $this->quoteCode('NaN', $currentDepth);
233
        }
234
235
        return var_export($float, true);
236
    }
237
238
    private function normalizeResource($raw, int $currentDepth): string
239
    {
240
        return $this->quoteCode(sprintf('[resource] (%s)', get_resource_type($raw)), $currentDepth);
241
    }
242
243
    private function normalizeBool(bool $raw, int $currentDepth): string
244
    {
245
        return $this->quoteCode(var_export($raw, true), $currentDepth);
246
    }
247
}
248