Passed
Push — master ( 8f026b...0fb977 )
by Waaaaaaaaaa
03:29
created

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