Passed
Push — MODEL_LIB_240928 ( d6fbb6...55f3e4 )
by Rafael
49:14
created

PhpCollector   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 57
dl 0
loc 163
rs 10
c 0
b 0
f 0
wmc 12

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 3 1
A __construct() 0 4 1
A errorHandler() 0 11 3
A getWidgets() 0 13 1
A collect() 0 6 1
A getMessages() 0 20 3
A friendlyErrorType() 0 26 2
1
<?php
2
3
/* Copyright (C) 2023       Laurent Destailleur         <[email protected]>
4
 * Copyright (C) 2024		MDW							<[email protected]>
5
 * Copyright (C) 2024       Rafael San José             <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
namespace Dolibarr\Tools\DebugBarCollector;
22
23
use DebugBar\DataCollector\DataCollector;
24
use DebugBar\DataCollector\Renderable;
25
26
/**
27
 *  \file       htdocs/debugbar/class/DataCollector/DolPhpCollector.php
28
 *  \brief      Class for debugbar collection
29
 *  \ingroup    debugbar
30
 */
31
32
/**
33
 * Class PhpCollector
34
 *
35
 * This class collects all PHP errors, notice, advices, trigger_error,...
36
 * Supports 15 different types included.
37
 */
38
class PhpCollector extends DataCollector implements Renderable
39
{
40
    /**
41
     * Collector name.
42
     *
43
     * @var string
44
     */
45
    protected $name;
46
47
    /**
48
     * List of messages. Each item includes:
49
     *  'message', 'message_html', 'is_string', 'label', 'time'.
50
     *
51
     * @var array
52
     */
53
    protected $messages = [];
54
55
    /**
56
     * PHPCollector constructor.
57
     *
58
     * @param string $name The name used by this collector widget.
59
     */
60
    public function __construct($name = 'Error handler')
61
    {
62
        $this->name = $name;
63
        set_error_handler([$this, 'errorHandler'], E_ALL);
64
    }
65
66
    /**
67
     * Called by the DebugBar when data needs to be collected.
68
     *
69
     * @return array    Array of collected data
70
     */
71
    public function collect()
72
    {
73
        $messages = $this->getMessages();
74
        return [
75
            'count' => count($messages),
76
            'messages' => $messages,
77
        ];
78
    }
79
80
    /**
81
     * Returns a list of messages ordered by their timestamp.
82
     *
83
     * @return array<array{time:int}> A list of messages ordered by time.
84
     */
85
    public function getMessages()
86
    {
87
        $messages = $this->messages;
88
89
        usort(
90
            $messages,
91
            /**
92
             * @param array{time:int} $itemA Message A information
93
             * @param array{time:int} $itemB Message B information
94
             * @return int<-1,1> -1 if Item A before Item B, 0 if same, 1 if later.
95
             */
96
            static function ($itemA, $itemB) {
97
                if ($itemA['time'] === $itemB['time']) {
98
                    return 0;
99
                }
100
                return $itemA['time'] < $itemB['time'] ? -1 : 1;
101
            }
102
        );
103
104
        return $messages;
105
    }
106
107
    /**
108
     * Returns a hash where keys are control names and their values an array of options as defined in
109
     * {@see DebugBar\JavascriptRenderer::addControl()}
110
     *
111
     * @return array    Array of details to render the widget.
112
     */
113
    public function getWidgets()
114
    {
115
        $name = $this->getName();
116
        return [
117
            $name => [
118
                'icon' => 'list',
119
                'widget' => 'PhpDebugBar.Widgets.MessagesWidget',
120
                'map' => "$name.messages",
121
                'default' => '[]',
122
            ],
123
            "$name:badge" => [
124
                'map' => "$name.count",
125
                'default' => 'null',
126
            ],
127
        ];
128
    }
129
130
    /**
131
     * Returns the unique name of the collector.
132
     *
133
     * @return string The widget name.
134
     */
135
    public function getName()
136
    {
137
        return $this->name;
138
    }
139
140
    /**
141
     * Exception error handler. Called from constructor with set_error_handler to add all details.
142
     *
143
     * @param int $severity Error type.
144
     * @param string $message Message of error.
145
     * @param string $fileName File where error is generated.
146
     * @param int $line Line number where error is generated.
147
     *
148
     * @return void
149
     */
150
    public function errorHandler($severity, $message, $fileName, $line)
151
    {
152
        for ($i = 0; $i < 15; $i++) {
153
            if ($type = $severity & (1 << $i)) {
154
                $label = $this->friendlyErrorType($type);
155
                $this->messages[] = [
156
                    'message' => $message . ' (' . $fileName . ':' . $line . ')',
157
                    'message_html' => null,
158
                    'is_string' => true,
159
                    'label' => $label,
160
                    'time' => microtime(true),
161
                ];
162
            }
163
        }
164
    }
165
166
    /**
167
     * Return error name from error code.
168
     *
169
     * @info http://php.net/manual/es/errorfunc.constants.php
170
     *
171
     * @param int $type Error code.
172
     *
173
     * @return string Error name.
174
     */
175
    private function friendlyErrorType($type)
176
    {
177
        $errors = [
178
            E_ERROR => 'ERROR',
179
            E_WARNING => 'WARNING',
180
            E_PARSE => 'PARSE',
181
            E_NOTICE => 'NOTICE',
182
            E_CORE_ERROR => 'CORE_ERROR',
183
            E_CORE_WARNING => 'CORE_WARNING',
184
            E_COMPILE_ERROR => 'COMPILE_ERROR',
185
            E_COMPILE_WARNING => 'COMPILE_WARNING',
186
            E_USER_ERROR => 'USER_ERROR',
187
            E_USER_WARNING => 'USER_WARNING',
188
            E_USER_NOTICE => 'USER_NOTICE',
189
            E_STRICT => 'STRICT',
190
            E_RECOVERABLE_ERROR => 'RECOVERABLE_ERROR',
191
            E_DEPRECATED => 'DEPRECATED',
192
            E_USER_DEPRECATED => 'USER_DEPRECATED',
193
        ];
194
195
        $result = '';
196
        if (isset($errors[$type])) {
197
            $result = $errors[$type];
198
        }
199
200
        return $result;
201
    }
202
}
203