Test Failed
Push — master ( 90252a...135589 )
by Waaaaaaaaaa
02:31
created

Payload::getMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Logfile;
4
5
use Throwable;
6
7
class Payload
8
{
9
    protected $message;
10
11
    protected $config;
12
13
    protected $id;
14
15
    protected $context;
16
17
    public function __construct(string $message, Config $config)
18
    {
19
        $this->message = $message;
20
        $this->config = $config;
21
        $this->id = $this->uuid4();
22
    }
23
24
    public function getMessage(): string
25
    {
26
        return $this->message;
27
    }
28
29
    public function setContext(array $context): void
30
    {
31
        $this->context = $context;
32
    }
33
34
    public function hasContext(): bool
35
    {
36
        return !empty($this->context);
37
    }
38
39
    public function getContext(): array
40
    {
41
        return $this->context;
42
    }
43
44
    public static function createFromException(Throwable $exception, Config $config): self
45
    {
46
        $payload = new Payload($exception->getMessage(), $config);
47
        $trace = new Stacktrace($exception);
48
        $trace->setPath($config->getPath());
49
        $context = $trace->getFrames();
50
        $payload->setContext($context);
51
        return $payload;
52
    }
53
54
    public function setId(string $id): void
55
    {
56
        $this->id = $id;
57
    }
58
59
    public function getId(): string
60
    {
61
        return $this->id;
62
    }
63
64
    /**
65
     * Get payload data
66
     *
67
     * @return array
68
     */
69
    public function getData(): array
70
    {
71
        $extra = [
72
            'id' => $this->getId(),
73
        ];
74
75
        if ($this->config->hasTags()) {
76
            $extra['tags'] = $this->config->getTags();
77
        }
78
79
        if ($this->config->hasUser()) {
80
            $extra['user'] = $this->config->getUser();
81
        }
82
83
        if ($this->config->hasRelease()) {
84
            $extra['release'] = $this->config->getRelease();
85
        }
86
87
        $data = [
88
            'message' => $this->getMessage(),
89
            'extra' => $extra,
90
        ];
91
92
        if ($this->hasContext()) {
93
            $data['context'] = $this->getContext();
94
        }
95
96
        return $data;
97
    }
98
99
    /**
100
     * Get payload json encoded
101
     *
102
     * @return string
103
     */
104
    public function getEncodedData(): string
105
    {
106
        $data = $this->getData();
107
        $encoded = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
108
109
        if (JSON_ERROR_UTF8 === json_last_error()) {
110
            if (is_string($data)) {
0 ignored issues
show
introduced by
The condition is_string($data) is always false.
Loading history...
111
                $this->detectAndCleanUtf8($data);
112
            } elseif (is_array($data)) {
0 ignored issues
show
introduced by
The condition is_array($data) is always true.
Loading history...
113
                array_walk_recursive($data, array($this, 'detectAndCleanUtf8'));
114
            }
115
            $encoded = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
116
        }
117
118
        if (JSON_ERROR_NONE !== json_last_error()) {
119
            $error = json_last_error_msg();
120
            throw new \LogicException(sprintf('Failed to encode json data: %s.', $error));
121
        }
122
123
        return $encoded;
124
    }
125
126
    /**
127
     * Detect invalid UTF-8 string characters and convert to valid UTF-8.
128
     * @see https://github.com/Seldaek/monolog/blob/master/src/Monolog/Formatter/NormalizerFormatter.php
129
     */
130
    public function detectAndCleanUtf8(&$data)
131
    {
132
        if (is_string($data) && !preg_match('//u', $data)) {
133
            $data = preg_replace_callback(
134
                '/[\x80-\xFF]+/',
135
                function ($m) {
136
                    return utf8_encode($m[0]);
137
                },
138
                $data
139
            );
140
            $data = str_replace(
141
                array('¤', '¦', '¨', '´', '¸', '¼', '½', '¾'),
142
                array('€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'),
143
                $data
144
            );
145
        }
146
    }
147
148
    /**
149
     * Get uuid v4
150
     *
151
     * @see http://www.php.net/manual/en/function.uniqid.php#94959
152
     * @return string
153
     */
154
    protected function uuid4(): string
155
    {
156
        mt_srand();
157
        return sprintf(
158
            '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
159
            // 32 bits for "time_low"
160
            mt_rand(0, 0xffff),
161
            mt_rand(0, 0xffff),
162
            // 16 bits for "time_mid"
163
            mt_rand(0, 0xffff),
164
            // 16 bits for "time_hi_and_version",
165
            // four most significant bits holds version number 4
166
            mt_rand(0, 0x0fff) | 0x4000,
167
            // 16 bits, 8 bits for "clk_seq_hi_res",
168
            // 8 bits for "clk_seq_low",
169
            // two most significant bits holds zero and one for variant DCE1.1
170
            mt_rand(0, 0x3fff) | 0x8000,
171
            // 48 bits for "node"
172
            mt_rand(0, 0xffff),
173
            mt_rand(0, 0xffff),
174
            mt_rand(0, 0xffff)
175
        );
176
    }
177
}
178