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
05:02
created

Message::render()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

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