Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
59 / 59
100.00% covered (success)
100.00%
12 / 12
CRAP
100.00% covered (success)
100.00%
1 / 1
TimeHandler
100.00% covered (success)
100.00%
59 / 59
100.00% covered (success)
100.00%
12 / 12
26
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getStart
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasStarted
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStop
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasStopped
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 start
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 stop
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getElapsed
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 prepare
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 prepareHeaderAsString
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 prepareAsString
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 log
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
10
1<?php
2/**
3 * Pop PHP Framework (https://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@noladev.com>
7 * @copyright  Copyright (c) 2009-2025 NOLA Interactive, LLC.
8 * @license    https://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Debug\Handler;
15
16use Pop\Log\Logger;
17
18/**
19 * Debug time handler class
20 *
21 * @category   Pop
22 * @package    Pop\Debug
23 * @author     Nick Sagona, III <dev@noladev.com>
24 * @copyright  Copyright (c) 2009-2025 NOLA Interactive, LLC.
25 * @license    https://www.popphp.org/license     New BSD License
26 * @version    2.2.2
27 */
28class TimeHandler extends AbstractHandler
29{
30
31    /**
32     * Start time
33     * @var ?float
34     */
35    protected ?float $start = null;
36
37    /**
38     * Stop time
39     * @var ?float
40     */
41    protected ?float $stop = null;
42
43    /**
44     * Constructor
45     *
46     * Instantiate a time handler object
47     *
48     * @param  bool    $start
49     * @param  ?string $name
50     * @param  ?Logger $logger
51     * @param  array   $loggingParams
52     */
53    public function __construct(bool $start = true, ?string $name = null, ?Logger $logger = null, array $loggingParams = [])
54    {
55        parent::__construct($name, $logger, $loggingParams);
56        if ($start) {
57            $this->start();
58        }
59    }
60
61    /**
62     * Get start value
63     *
64     * @return ?float
65     */
66    public function getStart(): ?float
67    {
68        return $this->start;
69    }
70
71    /**
72     * Determined if the timer has started
73     *
74     * @return bool
75     */
76    public function hasStarted(): bool
77    {
78        return ($this->start !== null);
79    }
80
81    /**
82     * Get stop value
83     *
84     * @return float
85     */
86    public function getStop(): float
87    {
88        return $this->stop;
89    }
90
91    /**
92     * Determined if the timer has stopped
93     *
94     * @return bool
95     */
96    public function hasStopped(): bool
97    {
98        return ($this->stop !== null);
99    }
100
101    /**
102     * Start timer
103     *
104     * @return TimeHandler
105     */
106    public function start(): TimeHandler
107    {
108        $this->start = microtime(true);
109        return $this;
110    }
111
112    /**
113     * Stop timer
114     *
115     * @return TimeHandler
116     */
117    public function stop(): TimeHandler
118    {
119        $this->stop = microtime(true);
120        return $this;
121    }
122
123    /**
124     * Get elapsed time
125     *
126     * @return string
127     */
128    public function getElapsed(): string
129    {
130        if ($this->stop === null) {
131            $this->stop();
132        }
133        return number_format(($this->stop - $this->start), 5, '.', '');
134    }
135
136    /**
137     * Prepare handler data for storage
138     *
139     * @return array
140     */
141    public function prepare(): array
142    {
143        if ($this->stop === null) {
144            $this->stop();
145        }
146
147        return [
148            'start'   => number_format($this->start, 5, '.', ''),
149            'stop'    => number_format($this->stop, 5, '.', ''),
150            'elapsed' => $this->getElapsed()
151        ];
152    }
153
154    /**
155     * Prepare header string
156     *
157     * @return string
158     */
159    public function prepareHeaderAsString(): string
160    {
161        $string  = ((!empty($this->name)) ? $this->name . ' ' : '') . 'Time Handler';
162        $string .= PHP_EOL . str_repeat('=', strlen($string)) . PHP_EOL;
163
164        return $string;
165    }
166
167    /**
168     * Prepare handler data as string
169     *
170     * @return string
171     */
172    public function prepareAsString(): string
173    {
174        if ($this->stop === null) {
175            $this->stop();
176        }
177
178        $string  = "Start:\t\t\t" . number_format($this->start, 5, '.', '') . PHP_EOL;
179        $string .= "Stop:\t\t\t" . number_format($this->stop, 5, '.', '') . PHP_EOL;
180        $string .= "Elapsed:\t\t" . $this->getElapsed() . ' seconds' . PHP_EOL . PHP_EOL;
181
182        return $string;
183    }
184
185    /**
186     * Trigger handler logging
187     *
188     * @throws Exception
189     * @return void
190     */
191    public function log(): void
192    {
193        if (($this->hasLogger()) && ($this->hasLoggingParams())) {
194            $logLevel   = $this->loggingParams['level'] ?? null;
195            $useContext = $this->loggingParams['context'] ?? null;
196            $timeLimit  = $this->loggingParams['limit'] ?? null;
197
198            if ($logLevel !== null) {
199                $elapsedTime = $this->getElapsed();
200                $context     = [];
201                if ($timeLimit !== null) {
202                    if ($elapsedTime >= $timeLimit) {
203                        if (!empty($useContext)) {
204                            $context['start']        = $this->start;
205                            $context['stop']         = $this->stop;
206                            $context['time_limit']   = $timeLimit;
207                            $context['elapsed_time'] = $elapsedTime;
208                        }
209                        if (is_string($useContext)) {
210                            $context['format'] = $useContext;
211                        }
212                        $this->logger->log(
213                            $logLevel, 'The time limit of '. $timeLimit . ' second(s) has been exceeded by ' .
214                            $elapsedTime - $timeLimit . ' second(s). The timed event was a total of ' .
215                            $elapsedTime . ' second(s).', $context
216                        );
217                    }
218                } else {
219                    if (!empty($useContext)) {
220                        $context['start']        = $this->start;
221                        $context['stop']         = $this->stop;
222                        $context['elapsed_time'] = $elapsedTime;
223                    }
224                    if (is_string($useContext)) {
225                        $context['format'] = $useContext;
226                    }
227
228                    $this->logger->log($logLevel, 'A new ' . $elapsedTime . ' second event has been triggered.', $context);
229                }
230            } else {
231                throw new Exception('Error: The log level parameter was not set.');
232            }
233        }
234    }
235
236}