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

Debug::addCollector()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
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\Tools;
20
21
use Alxarafe\Base\Config;
22
use Alxarafe\Tools\DebugBarCollector\PhpCollector;
23
use Alxarafe\Tools\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|null
123
     * @throws DebugBarException
124
     */
125
    public static function addCollector(DataCollectorInterface $collector): ?DebugBar
126
    {
127
        return isset(self::$debugBar) ? self::$debugBar->addCollector($collector) : null;
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
        return self::$debugBar ?? null;
138
    }
139
140
    /**
141
     * Stop the timer
142
     *
143
     * @param string $name
144
     * @throws DebugBarException
145
     */
146
    public static function stopTimer(string $name): void
147
    {
148
        if (!isset(self::$debugBar)) {
149
            return;
150
        }
151
        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

151
        self::$debugBar['time']->/** @scrutinizer ignore-call */ 
152
                                 stopMeasure($name);
Loading history...
152
    }
153
154
    /**
155
     * Gets the necessary calls to include the debug bar in the page header
156
     *
157
     * @return string
158
     * @throws DebugBarException
159
     */
160
    public static function getRenderHeader(): string
161
    {
162
        $result = "\n<!-- getRenderHeader -->\n";
163
        if (!isset(self::$render)) {
164
            return $result . '<!-- self::$render is not defined -->';
165
        }
166
167
        return $result . self::$render->renderHead();
168
    }
169
170
    /**
171
     * Gets the necessary calls to include the debug bar in the page footer
172
     *
173
     * @return string
174
     * @throws DebugBarException
175
     */
176
    public static function getRenderFooter(): string
177
    {
178
        $result = "\n<!-- getRenderFooter -->\n";
179
        if (!isset(self::$render)) {
180
            return $result . '<!-- self::$render is not defined -->';
181
        }
182
183
        return $result . self::$render->render();
184
    }
185
186
    /**
187
     * Add an exception to the exceptions tab of the debug bar.
188
     *
189
     * @param $exception
190
     * @throws DebugBarException
191
     */
192
    public static function addException($exception): void
193
    {
194
        if (!isset(self::$debugBar)) {
195
            return;
196
        }
197
        $caller = self::getCaller();
198
        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

198
        self::$debugBar['exceptions']->/** @scrutinizer ignore-call */ 
199
                                       addThrowable($caller['file'] . ' (' . $caller['line'] . '): ' . $exception);
Loading history...
199
    }
200
201
    /**
202
     * Locate last error
203
     *
204
     * @return array
205
     */
206
    private static function getCaller(): array
207
    {
208
        $caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[0];
209
        $caller['file'] = substr($caller['file'], strlen(constant('BASE_PATH')) - 7);
210
        return $caller;
211
    }
212
213
    public static function message(string $message): void
214
    {
215
        self::addMessage('messages', $message);
216
    }
217
218
    /**
219
     * Write a message in a channel (tab) of the debug bar.
220
     *
221
     * @param string $channel
222
     * @param string $message
223
     * @throws DebugBarException
224
     */
225
    private static function addMessage(string $channel, string $message): void
226
    {
227
        if (!isset(self::$debugBar)) {
228
            return;
229
        }
230
231
        if (!isset(self::$debugBar[$channel])) {
232
            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

232
            self::$debugBar->/** @scrutinizer ignore-call */ 
233
                             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...
233
            return;
234
        }
235
236
        $caller = self::getCaller();
237
        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

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