Test Failed
Push — main ( b4a480...c92e2e )
by Rafael
04:40
created

PhpCollector::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Alxarafe\Tools\DebugBarCollector;
4
5
use DebugBar\DataCollector\DataCollector;
6
use DebugBar\DataCollector\Renderable;
7
8
/**
9
 * Class MonologCollector
10
 *
11
 * This class collects all PHP errors, notice, advices, trigger_error, ...
12
 * Supports 15 different types included.
13
 *
14
 * @package Alxarafe\Lib\DebugBarCollector
15
 */
16
class PhpCollector extends DataCollector implements Renderable
17
{
18
    /**
19
     * Collector name.
20
     *
21
     * @var string
22
     */
23
    private static $name;
24
25
    /**
26
     * List of messages. Each item includes:
27
     *  'message', 'message_html', 'is_string', 'label', 'time'.
28
     *
29
     * @var array
30
     */
31
    private static $messages = [];
32
33
    /**
34
     * PHPCollector constructor.
35
     *
36
     * @param string $name The name used by this collector widget.
37
     */
38
    public function __construct(string $name = 'Error handler')
39
    {
40
        self::$name = $name;
41
        set_error_handler([$this, 'errorHandler'], E_ALL);
42
    }
43
44
    /**
45
     * Called by the DebugBar when data needs to be collected.
46
     *
47
     * @return array Collected data.
48
     */
49
    public function collect(): array
50
    {
51
        $messages = $this->getMessages();
52
        return [
53
            'count' => count($messages),
54
            'messages' => $messages,
55
        ];
56
    }
57
58
    /**
59
     * Returns a list of messages ordered by their timestamp.
60
     *
61
     * @return array A list of messages ordered by time.
62
     */
63
    public function getMessages(): array
64
    {
65
        $messages = self::$messages;
66
67
        usort($messages, function ($itemA, $itemB) {
68
            if ($itemA['time'] === $itemB['time']) {
69
                return 0;
70
            }
71
            return $itemA['time'] < $itemB['time'] ? -1 : 1;
72
        });
73
74
        return $messages;
75
    }
76
77
    /**
78
     * Returns a hash where keys are control names and their values an array of options as defined in
79
     * {@see DebugBar\JavascriptRenderer::addControl()}
80
     *
81
     * @return array Needed details to render the widget.
82
     */
83
    public function getWidgets(): array
84
    {
85
        $name = self::$name;
86
        return [
87
            $name => [
88
                'icon' => 'list',
89
                'widget' => 'PhpDebugBar.Widgets.MessagesWidget',
90
                'map' => "$name.messages",
91
                'default' => '[]',
92
            ],
93
            "$name:badge" => [
94
                'map' => "$name.count",
95
                'default' => 'null',
96
            ],
97
        ];
98
    }
99
100
    /**
101
     * Returns the unique name of the collector.
102
     *
103
     * @return string The widget name.
104
     */
105
    public function getName(): string
106
    {
107
        return self::$name;
108
    }
109
110
    /**
111
     * Exception error handler. Called from constructor with set_error_handler to add all details.
112
     *
113
     * @param int    $severity Error type.
114
     * @param string $message  Message of error.
115
     * @param string $fileName File where error is generated.
116
     * @param int    $line     Line number where error is generated.
117
     */
118
    public function errorHandler($severity, $message, $fileName, $line)
119
    {
120
        for ($i = 0; $i < 15; $i++) {
121
            if ($type = $severity & (2 ** $i)) {
122
                $label = self::friendlyErrorType($type);
123
                self::$messages[] = [
124
                    'message' => $message . ' (' . $fileName . ':' . $line . ')',
125
                    'message_html' => null,
126
                    'is_string' => true,
127
                    'label' => $label,
128
                    'time' => microtime(true),
129
                ];
130
            }
131
        }
132
    }
133
134
    /**
135
     * Return error name from error code.
136
     *
137
     * @info http://php.net/manual/es/errorfunc.constants.php
138
     *
139
     * @param int $type Error code.
140
     *
141
     * @return string Error name.
142
     */
143
    private static function friendlyErrorType(int $type): string
144
    {
145
        $errors = [
146
            E_ERROR => 'ERROR',
147
            E_WARNING => 'WARNING',
148
            E_PARSE => 'PARSE',
149
            E_NOTICE => 'NOTICE',
150
            E_CORE_ERROR => 'CORE_ERROR',
151
            E_CORE_WARNING => 'CORE_WARNING',
152
            E_COMPILE_ERROR => 'COMPILE_ERROR',
153
            E_COMPILE_WARNING => 'COMPILE_WARNING',
154
            E_USER_ERROR => 'USER_ERROR',
155
            E_USER_WARNING => 'USER_WARNING',
156
            E_USER_NOTICE => 'USER_NOTICE',
157
            E_STRICT => 'STRICT',
158
            E_RECOVERABLE_ERROR => 'RECOVERABLE_ERROR',
159
            E_DEPRECATED => 'DEPRECATED',
160
            E_USER_DEPRECATED => 'USER_DEPRECATED',
161
        ];
162
163
        return $errors[$type] ?? '';
164
    }
165
}
166