Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Spatie\FlareClient;
4
 
5
use Spatie\Backtrace\Backtrace;
6
use Spatie\Backtrace\Frame as SpatieFrame;
7
use Spatie\FlareClient\Concerns\HasContext;
8
use Spatie\FlareClient\Concerns\UsesTime;
9
use Spatie\FlareClient\Context\ContextProvider;
10
use Spatie\FlareClient\Contracts\ProvidesFlareContext;
11
use Spatie\FlareClient\Glows\Glow;
12
use Spatie\FlareClient\Solutions\ReportSolution;
13
use Spatie\Ignition\Contracts\Solution;
14
use Spatie\LaravelIgnition\Exceptions\ViewException;
15
use Throwable;
16
 
17
class Report
18
{
19
    use UsesTime;
20
    use HasContext;
21
 
22
    protected Backtrace $stacktrace;
23
 
24
    protected string $exceptionClass = '';
25
 
26
    protected string $message = '';
27
 
28
    /** @var array<int, array{time: int, name: string, message_level: string, meta_data: array, microtime: float}> */
29
    protected array $glows = [];
30
 
31
    /** @var array<int, array<int|string, mixed>> */
32
    protected array $solutions = [];
33
 
34
    /** @var array<int, string> */
35
    public array $documentationLinks = [];
36
 
37
    protected ContextProvider $context;
38
 
39
    protected ?string $applicationPath = null;
40
 
41
    protected ?string $applicationVersion = null;
42
 
43
    /** @var array<int|string, mixed> */
44
    protected array $userProvidedContext = [];
45
 
46
    /** @var array<int|string, mixed> */
47
    protected array $exceptionContext = [];
48
 
49
    protected ?Throwable $throwable = null;
50
 
51
    protected string $notifierName = 'Flare Client';
52
 
53
    protected ?string $languageVersion = null;
54
 
55
    protected ?string $frameworkVersion = null;
56
 
57
    protected ?int $openFrameIndex = null;
58
 
59
    protected string $trackingUuid;
60
 
61
    protected ?View $view;
62
 
63
    public static ?string $fakeTrackingUuid = null;
64
 
65
    public static function createForThrowable(
66
        Throwable $throwable,
67
        ContextProvider $context,
68
        ?string $applicationPath = null,
69
        ?string $version = null
70
    ): self {
71
        return (new self())
72
            ->setApplicationPath($applicationPath)
73
            ->throwable($throwable)
74
            ->useContext($context)
75
            ->exceptionClass(self::getClassForThrowable($throwable))
76
            ->message($throwable->getMessage())
77
            ->stackTrace(Backtrace::createForThrowable($throwable)->applicationPath($applicationPath ?? ''))
78
            ->exceptionContext($throwable)
79
            ->setApplicationVersion($version);
80
    }
81
 
82
    protected static function getClassForThrowable(Throwable $throwable): string
83
    {
84
        /** @phpstan-ignore-next-line */
85
        if ($throwable::class === ViewException::class) {
86
            /** @phpstan-ignore-next-line */
87
            if ($previous = $throwable->getPrevious()) {
88
                return get_class($previous);
89
            }
90
        }
91
 
92
        return get_class($throwable);
93
    }
94
 
95
    public static function createForMessage(
96
        string $message,
97
        string $logLevel,
98
        ContextProvider $context,
99
        ?string $applicationPath = null
100
    ): self {
101
        $stacktrace = Backtrace::create()->applicationPath($applicationPath ?? '');
102
 
103
        return (new self())
104
            ->setApplicationPath($applicationPath)
105
            ->message($message)
106
            ->useContext($context)
107
            ->exceptionClass($logLevel)
108
            ->stacktrace($stacktrace)
109
            ->openFrameIndex($stacktrace->firstApplicationFrameIndex());
110
    }
111
 
112
    public function __construct()
113
    {
114
        $this->trackingUuid = self::$fakeTrackingUuid ?? $this->generateUuid();
115
    }
116
 
117
    public function trackingUuid(): string
118
    {
119
        return $this->trackingUuid;
120
    }
121
 
122
    public function exceptionClass(string $exceptionClass): self
123
    {
124
        $this->exceptionClass = $exceptionClass;
125
 
126
        return $this;
127
    }
128
 
129
    public function getExceptionClass(): string
130
    {
131
        return $this->exceptionClass;
132
    }
133
 
134
    public function throwable(Throwable $throwable): self
135
    {
136
        $this->throwable = $throwable;
137
 
138
        return $this;
139
    }
140
 
141
    public function getThrowable(): ?Throwable
142
    {
143
        return $this->throwable;
144
    }
145
 
146
    public function message(string $message): self
147
    {
148
        $this->message = $message;
149
 
150
        return $this;
151
    }
152
 
153
    public function getMessage(): string
154
    {
155
        return $this->message;
156
    }
157
 
158
    public function stacktrace(Backtrace $stacktrace): self
159
    {
160
        $this->stacktrace = $stacktrace;
161
 
162
        return $this;
163
    }
164
 
165
    public function getStacktrace(): Backtrace
166
    {
167
        return $this->stacktrace;
168
    }
169
 
170
    public function notifierName(string $notifierName): self
171
    {
172
        $this->notifierName = $notifierName;
173
 
174
        return $this;
175
    }
176
 
177
    public function languageVersion(string $languageVersion): self
178
    {
179
        $this->languageVersion = $languageVersion;
180
 
181
        return $this;
182
    }
183
 
184
    public function frameworkVersion(string $frameworkVersion): self
185
    {
186
        $this->frameworkVersion = $frameworkVersion;
187
 
188
        return $this;
189
    }
190
 
191
    public function useContext(ContextProvider $request): self
192
    {
193
        $this->context = $request;
194
 
195
        return $this;
196
    }
197
 
198
    public function openFrameIndex(?int $index): self
199
    {
200
        $this->openFrameIndex = $index;
201
 
202
        return $this;
203
    }
204
 
205
    public function setApplicationPath(?string $applicationPath): self
206
    {
207
        $this->applicationPath = $applicationPath;
208
 
209
        return $this;
210
    }
211
 
212
    public function getApplicationPath(): ?string
213
    {
214
        return $this->applicationPath;
215
    }
216
 
217
    public function setApplicationVersion(?string $applicationVersion): self
218
    {
219
        $this->applicationVersion = $applicationVersion;
220
 
221
        return $this;
222
    }
223
 
224
    public function getApplicationVersion(): ?string
225
    {
226
        return $this->applicationVersion;
227
    }
228
 
229
    public function view(?View $view): self
230
    {
231
        $this->view = $view;
232
 
233
        return $this;
234
    }
235
 
236
    public function addGlow(Glow $glow): self
237
    {
238
        $this->glows[] = $glow->toArray();
239
 
240
        return $this;
241
    }
242
 
243
    public function addSolution(Solution $solution): self
244
    {
245
        $this->solutions[] = ReportSolution::fromSolution($solution)->toArray();
246
 
247
        return $this;
248
    }
249
 
250
    /**
251
     * @param array<int, string> $documentationLinks
252
     *
253
     * @return $this
254
     */
255
    public function addDocumentationLinks(array $documentationLinks): self
256
    {
257
        $this->documentationLinks = $documentationLinks;
258
 
259
        return $this;
260
    }
261
 
262
    /**
263
     * @param array<int|string, mixed> $userProvidedContext
264
     *
265
     * @return $this
266
     */
267
    public function userProvidedContext(array $userProvidedContext): self
268
    {
269
        $this->userProvidedContext = $userProvidedContext;
270
 
271
        return $this;
272
    }
273
 
274
    /**
275
     * @return array<int|string, mixed>
276
    */
277
    public function allContext(): array
278
    {
279
        $context = $this->context->toArray();
280
 
281
        $context = array_merge_recursive_distinct($context, $this->exceptionContext);
282
 
283
        return array_merge_recursive_distinct($context, $this->userProvidedContext);
284
    }
285
 
286
    protected function exceptionContext(Throwable $throwable): self
287
    {
288
        if ($throwable instanceof ProvidesFlareContext) {
289
            $this->exceptionContext = $throwable->context();
290
        }
291
 
292
        return $this;
293
    }
294
 
295
    /**
296
     * @return array<int|string, mixed>
297
     */
298
    protected function stracktraceAsArray(): array
299
    {
300
        return array_map(
301
            fn (SpatieFrame $frame) => Frame::fromSpatieFrame($frame)->toArray(),
302
            $this->stacktrace->frames(),
303
        );
304
    }
305
 
306
    /**
307
     * @return array<string, mixed>
308
     */
309
    public function toArray(): array
310
    {
311
        return [
312
            'notifier' => $this->notifierName ?? 'Flare Client',
313
            'language' => 'PHP',
314
            'framework_version' => $this->frameworkVersion,
315
            'language_version' => $this->languageVersion ?? phpversion(),
316
            'exception_class' => $this->exceptionClass,
317
            'seen_at' => $this->getCurrentTime(),
318
            'message' => $this->message,
319
            'glows' => $this->glows,
320
            'solutions' => $this->solutions,
321
            'documentation_links' => $this->documentationLinks,
322
            'stacktrace' => $this->stracktraceAsArray(),
323
            'context' => $this->allContext(),
324
            'stage' => $this->stage,
325
            'message_level' => $this->messageLevel,
326
            'open_frame_index' => $this->openFrameIndex,
327
            'application_path' => $this->applicationPath,
328
            'application_version' => $this->applicationVersion,
329
            'tracking_uuid' => $this->trackingUuid,
330
        ];
331
    }
332
 
333
    /*
334
     * Found on https://stackoverflow.com/questions/2040240/php-function-to-generate-v4-uuid/15875555#15875555
335
     */
336
    protected function generateUuid(): string
337
    {
338
        // Generate 16 bytes (128 bits) of random data or use the data passed into the function.
339
        $data = random_bytes(16);
340
 
341
        // Set version to 0100
342
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
343
        // Set bits 6-7 to 10
344
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
345
 
346
        // Output the 36 character UUID.
347
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
348
    }
349
}