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
04:27
created

Formatter::normalizeObject()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

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