Stacktrace   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 120
rs 10
c 0
b 0
f 0
wmc 22
lcom 2
cbo 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A createForThrowable() 0 4 1
A create() 0 6 1
A __construct() 0 28 4
A frameFromFlare() 0 4 2
A frameFileFromApplication() 0 14 3
A fileBlacklisted() 0 16 3
A firstFrame() 0 4 1
A toArray() 0 6 1
A firstApplicationFrame() 0 10 3
A firstApplicationFrameIndex() 0 10 3
1
<?php
2
3
namespace Facade\FlareClient\Stacktrace;
4
5
use Throwable;
6
7
class Stacktrace
8
{
9
    /** @var \Facade\FlareClient\Stacktrace\Frame[] */
10
    private $frames;
11
12
    /** @var string */
13
    private $applicationPath;
14
15
    public static function createForThrowable(Throwable $throwable, ?string $applicationPath = null): self
16
    {
17
        return new static($throwable->getTrace(),  $applicationPath, $throwable->getFile(), $throwable->getLine());
18
    }
19
20
    public static function create(?string $applicationPath = null): self
21
    {
22
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS & ~DEBUG_BACKTRACE_PROVIDE_OBJECT);
23
24
        return new static($backtrace, $applicationPath);
25
    }
26
27
    public function __construct(array $backtrace, ?string $applicationPath = null, string $topmostFile = null, string $topmostLine = null)
28
    {
29
        $this->applicationPath = $applicationPath;
30
31
        $currentFile = $topmostFile;
32
        $currentLine = $topmostLine;
33
34
        foreach ($backtrace as $rawFrame) {
35
            if (! $this->frameFromFlare($rawFrame) && ! $this->fileBlacklisted($currentFile)) {
36
                $this->frames[] = new Frame(
37
                    $currentFile,
38
                    $currentLine,
39
                    $rawFrame['function'] ?? null,
40
                    $rawFrame['class'] ?? null,
41
                    $this->frameFileFromApplication($currentFile)
42
                );
43
            }
44
45
            $currentFile = $rawFrame['file'] ?? 'unknown';
46
            $currentLine = $rawFrame['line'] ?? 0;
47
        }
48
49
        $this->frames[] = new Frame(
50
            $currentFile,
51
            $currentLine,
52
            '[top]'
53
        );
54
    }
55
56
    protected function frameFromFlare(array $rawFrame): bool
57
    {
58
        return isset($rawFrame['class']) && strpos($rawFrame['class'], 'Facade\\FlareClient\\') === 0;
59
    }
60
61
    protected function frameFileFromApplication(string $frameFilename): bool
62
    {
63
        $relativeFile = str_replace('\\', '/', $frameFilename);
64
65
        if (! empty($this->applicationPath)) {
66
            $relativeFile = array_reverse(explode($this->applicationPath ?? '', $frameFilename, 2))[0];
67
        }
68
69
        if (strpos($relativeFile, '/vendor') === 0) {
70
            return false;
71
        }
72
73
        return true;
74
    }
75
76
    protected function fileBlacklisted(string $currentFile): bool
77
    {
78
        $currentFile = str_replace('\\', '/', $currentFile);
79
80
        $blacklist = [
81
            '/ignition/src/helpers.php',
82
        ];
83
84
        foreach ($blacklist as $blacklistedFile) {
85
            if (strstr($currentFile, $blacklistedFile) !== false) {
86
                return true;
87
            }
88
        }
89
90
        return false;
91
    }
92
93
    public function firstFrame(): Frame
94
    {
95
        return $this->frames[0];
96
    }
97
98
    public function toArray(): array
99
    {
100
        return array_map(function (Frame $frame) {
101
            return $frame->toArray();
102
        }, $this->frames);
103
    }
104
105
    public function firstApplicationFrame(): ?Frame
106
    {
107
        foreach ($this->frames as $index => $frame) {
108
            if ($frame->isApplicationFrame()) {
109
                return $frame;
110
            }
111
        }
112
113
        return null;
114
    }
115
116
    public function firstApplicationFrameIndex(): ?int
117
    {
118
        foreach ($this->frames as $index => $frame) {
119
            if ($frame->isApplicationFrame()) {
120
                return $index;
121
            }
122
        }
123
124
        return null;
125
    }
126
}
127