Passed
Pull Request — master (#853)
by butschster
12:01 queued 05:19
created

PlainRenderer::render()   B

Complexity

Conditions 6
Paths 14

Size

Total Lines 41
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 6.002

Importance

Changes 3
Bugs 2 Features 0
Metric Value
eloc 24
c 3
b 2
f 0
dl 0
loc 41
ccs 25
cts 26
cp 0.9615
rs 8.9137
cc 6
nc 14
nop 3
crap 6.002
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Exceptions\Renderer;
6
7
use Spiral\Exceptions\Style\PlainStyle;
8
use Spiral\Exceptions\Verbosity;
9
10
final class PlainRenderer extends AbstractRenderer
11
{
12
    protected const FORMATS = ['text/plain', 'text', 'plain', 'cli', 'console'];
13
    // Lines to show around targeted line.
14
    private const SHOW_LINES = 2;
15
16
    private array $lines = [];
17
18 9
    public function render(
19
        \Throwable $exception,
20
        ?Verbosity $verbosity = null,
21
        string $format = null
22
    ): string {
23 9
        $verbosity ??= $this->defaultVerbosity;
24 9
        $exceptions = [$exception];
25 9
        while ($exception = $exception->getPrevious()) {
26 1
            $exceptions[] = $exception;
27
        }
28
29 9
        $exceptions = \array_reverse($exceptions);
30
31 9
        $result = [];
32 9
        $rootDir = \getcwd();
33
34 9
        foreach ($exceptions as $exception) {
35 9
            $file = \str_starts_with($exception->getFile(), $rootDir)
36 9
                ? \substr($exception->getFile(), \strlen($rootDir) + 1)
37
                : $exception->getFile();
38
39 9
            $row = \sprintf(
40 9
                "[%s]\n%s in %s:%s\n",
41 9
                $exception::class,
42 9
                $exception->getMessage(),
43 9
                $file,
44 9
                $exception->getLine(),
45 9
            );
46
47 9
            if ($verbosity->value >= Verbosity::DEBUG->value) {
48 3
                $row .= $this->renderTrace($exception, new Highlighter(new PlainStyle()));
49 6
            } elseif ($verbosity->value >= Verbosity::VERBOSE->value) {
50 1
                $row .= $this->renderTrace($exception);
51
            }
52
53 9
            $result[] = $row;
54
        }
55
56 9
        $this->lines = [];
57
58 9
        return \implode('', \array_reverse($result));
59
    }
60
61
    /**
62
     * Render exception call stack.
63
     */
64 4
    private function renderTrace(\Throwable $e, Highlighter $h = null): string
65
    {
66 4
        $stacktrace = $this->getStacktrace($e);
67 4
        if ($stacktrace === []) {
68
            return '';
69
        }
70
71 4
        $result = "\n";
72 4
        $rootDir = \getcwd();
73
74 4
        $pad = \strlen((string)\count($stacktrace));
75
76 4
        foreach ($stacktrace as $i => $trace) {
77 4
            if (isset($trace['type'], $trace['class'])) {
78 4
                $line = \sprintf(
79 4
                    '%s. %s%s%s()',
80 4
                    \str_pad((string)((int) $i + 1), $pad, ' ', \STR_PAD_LEFT),
81 4
                    $trace['class'],
82 4
                    $trace['type'],
83 4
                    $trace['function']
84 4
                );
85
            } else {
86 4
                $line = $trace['function'];
87
            }
88
89 4
            if (isset($trace['file'])) {
90 4
                $file = \str_starts_with($trace['file'], $rootDir)
91 4
                    ? \substr($trace['file'], \strlen($rootDir) + 1)
92
                    : $trace['file'];
93
94 4
                $line .= \sprintf(' at %s:%s', $file, $trace['line']);
95
            }
96
97 4
            if (\in_array($line, $this->lines, true)) {
98 1
                continue;
99
            }
100
101 4
            $this->lines[] = $line;
102
103 4
            $result .= $line . "\n";
104
105 4
            if ($h !== null && !empty($trace['file'])) {
106 3
                $result .= $h->highlightLines(
107 3
                    \file_get_contents($trace['file']),
108 3
                    $trace['line'],
109 3
                    self::SHOW_LINES
110 3
                ) . "\n";
111
            }
112
        }
113
114 4
        return $result . "\n";
115
    }
116
}
117