Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
25 / 25
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractHandler
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
25 / 25
31
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 setName
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setData
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 start
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 stop
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setStart
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getStart
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasStart
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setEnd
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getEnd
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasEnd
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setElapsed
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getElapsed
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasElapsed
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLogger
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLogger
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasLogger
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLoggingParams
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLoggingParams
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasLoggingParams
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 resolveLogLevel
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 prepare
n/a
0 / 0
n/a
0 / 0
0
 prepareMessage
n/a
0 / 0
n/a
0 / 0
0
 log
n/a
0 / 0
n/a
0 / 0
0
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <dev@noladev.com>
8 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Debug\Handler;
16
17use Pop\Utils\DebuggerHandlerInterface;
18use Psr\Log\LoggerInterface;
19
20/**
21 * Debug handler abstract class
22 *
23 * @category   Pop
24 * @package    Pop\Debug
25 * @author     Nick Sagona, III <dev@noladev.com>
26 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
27 * @license    https://www.popphp.org/license     New BSD License
28 * @version    4.0.0
29 */
30abstract class AbstractHandler implements DebuggerHandlerInterface
31{
32
33    /**
34     * Name of handler
35     * @var ?string
36     */
37    protected ?string $name = null;
38
39
40    /**
41     * Data
42     * @var array
43     */
44    protected array $data = [];
45
46    /**
47     * Start time
48     * @var ?float
49     */
50    protected ?float $start = null;
51
52    /**
53     * End time
54     * @var ?float
55     */
56    protected ?float $end = null;
57
58    /**
59     * Elapsed time
60     * @var ?float
61     */
62    protected ?float $elapsed = null;
63
64    /**
65     * Logger object
66     * @var ?LoggerInterface
67     */
68    protected ?LoggerInterface $logger = null;
69
70    /**
71     * Logging params
72     * @var array
73     */
74    protected array $loggingParams = [];
75
76    /**
77     * Constructor
78     *
79     * Instantiate a handler object
80     *
81     * @param ?string         $name
82     * @param ?LoggerInterface $logger
83     * @param array           $loggingParams
84     */
85    public function __construct(?string $name = null, ?LoggerInterface $logger = null, array $loggingParams = [])
86    {
87        $this->setStart();
88        if ($name !== null) {
89            $this->setName($name);
90        }
91        if ($logger !== null) {
92            $this->setLogger($logger);
93            $this->setLoggingParams($loggingParams);
94        }
95    }
96
97    /**
98     * Set name
99     *
100     * @param  string $name
101     * @return AbstractHandler
102     */
103    public function setName(string $name): AbstractHandler
104    {
105        $this->name = $name;
106        return $this;
107    }
108
109    /**
110     * Get name
111     *
112     * @return ?string
113     */
114    public function getName(): ?string
115    {
116        return $this->name;
117    }
118
119    /**
120     * Has name
121     *
122     * @return bool
123     */
124    public function hasName(): bool
125    {
126        return !empty($this->name);
127    }
128
129    /**
130     * Set data
131     *
132     * @param  array $data
133     * @return AbstractHandler
134     */
135    public function setData(array $data = []): AbstractHandler
136    {
137        $this->data = $data;
138        return $this;
139    }
140
141    /**
142     * Get data
143     *
144     * @return array
145     */
146    public function getData(): array
147    {
148        return $this->data;
149    }
150
151    /**
152     * Has data
153     *
154     * @return bool
155     */
156    public function hasData(): bool
157    {
158        return !empty($this->data);
159    }
160
161    /**
162     * Start
163     *
164     * @return AbstractHandler
165     */
166    public function start(): AbstractHandler
167    {
168        return $this->setStart();
169    }
170
171    /**
172     * Stop
173     *
174     * @return AbstractHandler
175     */
176    public function stop(): AbstractHandler
177    {
178        return $this->setEnd();
179    }
180
181    /**
182     * Set start
183     *
184     * @param  ?float $start
185     * @return AbstractHandler
186     */
187    public function setStart(?float $start = null): AbstractHandler
188    {
189        $this->start = $start ?? microtime(true);
190        return $this;
191    }
192
193    /**
194     * Get start
195     *
196     * @return ?float
197     */
198    public function getStart(): ?float
199    {
200        return $this->start;
201    }
202
203    /**
204     * Has start
205     *
206     * @return bool
207     */
208    public function hasStart(): bool
209    {
210        return !empty($this->start);
211    }
212
213    /**
214     * Set end
215     *
216     * @param  ?float $end
217     * @return AbstractHandler
218     */
219    public function setEnd(?float $end = null): AbstractHandler
220    {
221        $this->end = $end ?? microtime(true);
222        if (!empty($this->start)) {
223            $this->setElapsed(($this->end - $this->start));
224        }
225        return $this;
226    }
227
228    /**
229     * Get end
230     *
231     * @return ?float
232     */
233    public function getEnd(): ?float
234    {
235        return $this->end;
236    }
237
238    /**
239     * Has end
240     *
241     * @return bool
242     */
243    public function hasEnd(): bool
244    {
245        return !empty($this->end);
246    }
247
248    /**
249     * Set elapsed
250     *
251     * @param  float $elapsed
252     * @return AbstractHandler
253     */
254    public function setElapsed(float $elapsed): AbstractHandler
255    {
256        $this->elapsed = $elapsed;
257        return $this;
258    }
259
260    /**
261     * Get elapsed
262     *
263     * @return ?float
264     */
265    public function getElapsed(): ?float
266    {
267        return $this->elapsed;
268    }
269
270    /**
271     * Has elapsed
272     *
273     * @return bool
274     */
275    public function hasElapsed(): bool
276    {
277        return !empty($this->elapsed);
278    }
279
280    /**
281     * Set logger
282     *
283     * @param  LoggerInterface $logger
284     * @return AbstractHandler
285     */
286    public function setLogger(LoggerInterface $logger): AbstractHandler
287    {
288        $this->logger = $logger;
289        return $this;
290    }
291
292    /**
293     * Get logger
294     *
295     * @return ?LoggerInterface
296     */
297    public function getLogger(): ?LoggerInterface
298    {
299        return $this->logger;
300    }
301
302    /**
303     * Has logger
304     *
305     * @return bool
306     */
307    public function hasLogger(): bool
308    {
309        return !empty($this->logger);
310    }
311
312    /**
313     * Set logger
314     *
315     * @param  array $loggingParams
316     * @return AbstractHandler
317     */
318    public function setLoggingParams(array $loggingParams): AbstractHandler
319    {
320        $this->loggingParams = $loggingParams;
321        return $this;
322    }
323
324    /**
325     * Get logging params
326     *
327     * @return array
328     */
329    public function getLoggingParams(): array
330    {
331        return $this->loggingParams;
332    }
333
334    /**
335     * Has logging parameters
336     *
337     * @return bool
338     */
339    public function hasLoggingParams(): bool
340    {
341        return !empty($this->loggingParams);
342    }
343
344    /**
345     * Resolve the configured log level, guarding the shared log() preconditions
346     *
347     * Returns null (and does nothing else) when no logger or logging params are set, so
348     * subclasses can bail out of log() early without duplicating that check. Throws when a
349     * logger and logging params are present but no 'level' param was configured.
350     *
351     * @throws Exception
352     * @return mixed
353     */
354    protected function resolveLogLevel(): mixed
355    {
356        if (!$this->hasLogger() || !$this->hasLoggingParams()) {
357            return null;
358        }
359
360        $logLevel = $this->loggingParams['level'] ?? null;
361
362        if ($logLevel === null) {
363            throw new Exception('Error: The log level parameter was not set.');
364        }
365
366        return $logLevel;
367    }
368
369    /**
370     * Prepare handler data for storage
371     *
372     * @return array
373     */
374    abstract public function prepare(): array;
375
376    /**
377     * Prepare handler message
378     *
379     * @param  ?array $context
380     * @return string
381     */
382    abstract public function prepareMessage(?array $context = null): string;
383
384    /**
385     * Trigger handle logging
386     *
387     * @return void
388     */
389    abstract public function log(): void;
390
391}