Test Failed
Push — main ( 6ea9a3...5960f6 )
by Rafael
04:57
created

Debug   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 211
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 23
eloc 56
dl 0
loc 211
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A load() 0 27 2
A addCollector() 0 3 1
A initialize() 0 7 3
A addException() 0 7 2
A message() 0 3 1
A addMessage() 0 13 3
A getRenderHeader() 0 8 2
A startTimer() 0 6 2
A getCaller() 0 5 1
A getDebugBar() 0 6 2
A stopTimer() 0 6 2
A getRenderFooter() 0 8 2
1
<?php
2
3
/* Copyright (C) 2024      Rafael San José      <[email protected]>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 3 of the License, or
8
 * any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
 */
18
19
namespace Alxarafe\Lib;
20
21
use Alxarafe\Base\Config;
22
use Alxarafe\Lib\DebugBarCollector\PhpCollector;
23
use Alxarafe\Lib\DebugBarCollector\TranslatorCollector;
24
use DebugBar\DataCollector\DataCollectorInterface;
25
use DebugBar\DebugBar;
26
use DebugBar\DebugBarException;
27
use DebugBar\JavascriptRenderer;
28
use DebugBar\StandardDebugBar;
29
30
abstract class Debug
31
{
32
    /**
33
     * True if debugbar is enabled.
34
     *
35
     * @var bool
36
     */
37
    private static bool $enabled;
38
39
    /**
40
     * Private render instance
41
     *
42
     * @var JavascriptRenderer|null
43
     */
44
    private static JavascriptRenderer|null $render;
45
46
    /**
47
     * DebugBar instance
48
     *
49
     * @var StandardDebugBar|null
50
     */
51
    private static StandardDebugBar|null $debugBar;
52
53
    /**
54
     * Initializes the Debug
55
     *
56
     * @return bool
57
     * @throws DebugBarException
58
     */
59
    public static function initialize(bool $reload = false)
60
    {
61
        if (!$reload && isset(self::$debugBar)) {
62
            return true;
63
        }
64
65
        return self::load();
66
    }
67
68
    /**
69
     * Load the debugbar and collectors.
70
     *
71
     * @return bool
72
     * @throws DebugBarException
73
     */
74
    private static function load(): bool
75
    {
76
        self::$debugBar = null;
77
        self::$render = null;
78
79
        $config = Config::getConfig();
80
        self::$enabled = $config->security->debug ?? false;
81
        if (!self::$enabled) {
82
            return false;
83
        }
84
85
        self::$debugBar = new StandardDebugBar();
86
87
        $shortName = 'Debug';
88
        self::startTimer($shortName, $shortName . ' DebugTool Constructor');
89
90
        self::addCollector(new PhpCollector());
91
        self::addCollector(new TranslatorCollector());
92
93
        $baseUrl = constant('BASE_URL') . '/alxarafe/assets/debugbar';
94
        $basePath = realpath(constant('BASE_PATH') . '/..') . '/';
95
96
        self::$render = self::getDebugBar()->getJavascriptRenderer($baseUrl, $basePath);
97
98
        self::stopTimer($shortName);
99
100
        return isset(self::$render);
101
    }
102
103
    /**
104
     * Initialize the timer
105
     *
106
     * @param string $name
107
     * @param string $message
108
     * @throws DebugBarException
109
     */
110
    public static function startTimer(string $name, string $message): void
111
    {
112
        if (!isset(self::$debugBar)) {
113
            return;
114
        }
115
        self::$debugBar['time']->startMeasure($name, $message);
0 ignored issues
show
Bug introduced by
The method startMeasure() does not exist on DebugBar\DataCollector\DataCollectorInterface. It seems like you code against a sub-type of DebugBar\DataCollector\DataCollectorInterface such as DebugBar\DataCollector\TimeDataCollector. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
        self::$debugBar['time']->/** @scrutinizer ignore-call */ 
116
                                 startMeasure($name, $message);
Loading history...
116
    }
117
118
    /**
119
     * Add a new debugbar collector
120
     *
121
     * @param DataCollectorInterface $collector
122
     * @return DebugBar
123
     * @throws DebugBarException
124
     */
125
    public static function addCollector(DataCollectorInterface $collector): DebugBar
126
    {
127
        return self::$debugBar->addCollector($collector);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::debugBar->addCollector($collector) could return the type null which is incompatible with the type-hinted return DebugBar\DebugBar. Consider adding an additional type-check to rule them out.
Loading history...
Bug introduced by
The method addCollector() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

127
        return self::$debugBar->/** @scrutinizer ignore-call */ addCollector($collector);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
128
    }
129
130
    /**
131
     * Return the internal debug instance for get the html code.
132
     *
133
     * @return StandardDebugBar|null
134
     */
135
    public static function getDebugBar(): ?StandardDebugBar
136
    {
137
        if (!isset(self::$debugBar)) {
138
            return null;
139
        }
140
        return self::$debugBar;
141
    }
142
143
    /**
144
     * Stop the timer
145
     *
146
     * @param string $name
147
     * @throws DebugBarException
148
     */
149
    public static function stopTimer(string $name): void
150
    {
151
        if (!isset(self::$debugBar)) {
152
            return;
153
        }
154
        self::$debugBar['time']->stopMeasure($name);
0 ignored issues
show
Bug introduced by
The method stopMeasure() does not exist on DebugBar\DataCollector\DataCollectorInterface. It seems like you code against a sub-type of DebugBar\DataCollector\DataCollectorInterface such as DebugBar\DataCollector\TimeDataCollector. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

154
        self::$debugBar['time']->/** @scrutinizer ignore-call */ 
155
                                 stopMeasure($name);
Loading history...
155
    }
156
157
    /**
158
     * Gets the necessary calls to include the debug bar in the page header
159
     *
160
     * @return string
161
     * @throws DebugBarException
162
     */
163
    public static function getRenderHeader(): string
164
    {
165
        $result = "\n<!-- getRenderHeader -->\n";
166
        if (!isset(self::$render)) {
167
            return $result . '<!-- self::$render is not defined -->';
168
        }
169
170
        return $result . self::$render->renderHead();
171
    }
172
173
    /**
174
     * Gets the necessary calls to include the debug bar in the page footer
175
     *
176
     * @return string
177
     * @throws DebugBarException
178
     */
179
    public static function getRenderFooter(): string
180
    {
181
        $result = "\n<!-- getRenderFooter -->\n";
182
        if (!isset(self::$render)) {
183
            return $result . '<!-- self::$render is not defined -->';
184
        }
185
186
        return $result . self::$render->render();
187
    }
188
189
    /**
190
     * Add an exception to the exceptions tab of the debug bar.
191
     *
192
     * @param $exception
193
     * @throws DebugBarException
194
     */
195
    public static function addException($exception): void
196
    {
197
        if (!isset(self::$debugBar)) {
198
            return;
199
        }
200
        $caller = self::getCaller();
201
        self::$debugBar['exceptions']->addThrowable($caller['file'] . ' (' . $caller['line'] . '): ' . $exception);
0 ignored issues
show
Bug introduced by
The method addThrowable() does not exist on DebugBar\DataCollector\DataCollectorInterface. It seems like you code against a sub-type of DebugBar\DataCollector\DataCollectorInterface such as DebugBar\DataCollector\ExceptionsCollector. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

201
        self::$debugBar['exceptions']->/** @scrutinizer ignore-call */ 
202
                                       addThrowable($caller['file'] . ' (' . $caller['line'] . '): ' . $exception);
Loading history...
202
    }
203
204
    /**
205
     * Locate last error
206
     *
207
     * @return array
208
     */
209
    private static function getCaller(): array
210
    {
211
        $caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[0];
212
        $caller['file'] = substr($caller['file'], strlen(constant('BASE_PATH')) - 7);
213
        return $caller;
214
    }
215
216
    public static function message(string $message): void
217
    {
218
        self::addMessage('messages', $message);
219
    }
220
221
    /**
222
     * Write a message in a channel (tab) of the debug bar.
223
     *
224
     * @param string $channel
225
     * @param string $message
226
     * @throws DebugBarException
227
     */
228
    private static function addMessage(string $channel, string $message): void
229
    {
230
        if (!isset(self::$debugBar)) {
231
            return;
232
        }
233
234
        if (!isset(self::$debugBar[$channel])) {
235
            self::$debugBar->addMessage('channel ' . $channel . ' does not exist. Message: ' . $message);
0 ignored issues
show
Bug introduced by
The method addMessage() does not exist on DebugBar\StandardDebugBar. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

235
            self::$debugBar->/** @scrutinizer ignore-call */ 
236
                             addMessage('channel ' . $channel . ' does not exist. Message: ' . $message);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
236
            return;
237
        }
238
239
        $caller = self::getCaller();
240
        self::$debugBar[$channel]->addMessage($caller['file'] . ' (' . $caller['line'] . '): ' . $message);
0 ignored issues
show
Bug introduced by
The method addMessage() does not exist on DebugBar\DataCollector\DataCollectorInterface. It seems like you code against a sub-type of DebugBar\DataCollector\DataCollectorInterface such as DebugBar\DataCollector\MessagesCollector. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

240
        self::$debugBar[$channel]->/** @scrutinizer ignore-call */ 
241
                                   addMessage($caller['file'] . ' (' . $caller['line'] . '): ' . $message);
Loading history...
241
    }
242
}
243