Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.14% covered (success)
82.14%
46 / 56
88.89% covered (success)
88.89%
8 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
QueryHandler
82.14% covered (success)
82.14%
46 / 56
88.89% covered (success)
88.89%
8 / 9
22.28
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setProfiler
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 hasProfiler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getProfiler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 profiler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 prepare
100.00% covered (success)
100.00%
17 / 17
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
58.33% covered (warning)
58.33%
14 / 24
0.00% covered (danger)
0.00%
0 / 1
14.86
 __get
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Debug\Handler;
15
16use Pop\Db\Adapter\Profiler\Profiler;
17
18/**
19 * Debug query handler class
20 *
21 * @category   Pop
22 * @package    Pop\Debug
23 * @author     Nick Sagona, III <dev@nolainteractive.com>
24 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
25 * @license    http://www.popphp.org/license     New BSD License
26 * @version    2.0.0
27 */
28class QueryHandler extends AbstractHandler
29{
30
31    /**
32     * Profiler
33     * @var ?Profiler
34     */
35    protected ?Profiler $profiler = null;
36
37    /**
38     * Constructor
39     *
40     * Instantiate a query handler object
41     *
42     * @param  ?Profiler $profiler
43     * @param  ?string   $name
44     */
45    public function __construct(?Profiler $profiler = null, ?string $name = null)
46    {
47        parent::__construct($name);
48
49        if ($profiler !== null) {
50            $this->setProfiler($profiler);
51        }
52    }
53
54    /**
55     * Set profiler
56     *
57     * @param  Profiler $profiler
58     * @return QueryHandler
59     */
60    public function setProfiler(Profiler $profiler): QueryHandler
61    {
62        $this->profiler = $profiler;
63        return $this;
64    }
65
66    /**
67     * Determine if the handler has a profiler
68     *
69     * @return bool
70     */
71    public function hasProfiler(): bool
72    {
73        return ($this->profiler !== null);
74    }
75
76    /**
77     * Get profiler
78     *
79     * @return Profiler
80     */
81    public function getProfiler(): Profiler
82    {
83        return $this->profiler;
84    }
85
86    /**
87     * Get profiler (alias method)
88     *
89     * @return Profiler
90     */
91    public function profiler(): Profiler
92    {
93        return $this->profiler;
94    }
95
96    /**
97     * Prepare handler data for storage
98     *
99     * @return array
100     */
101    public function prepare(): array
102    {
103        $elapsed = $this->profiler->getElapsed();
104        $data    = [
105            'start'   => number_format((float)$this->profiler->getStart(), 5, '.', ''),
106            'finish'  => number_format((float)$this->profiler->getFinish(), 5, '.', ''),
107            'elapsed' => $elapsed,
108            'steps'   => []
109        ];
110
111        foreach ($this->profiler->getSteps() as $step) {
112            $data['steps'][] = [
113                'start'   => number_format($step->getStart(), 5, '.', ''),
114                'finish'  => number_format($step->getFinish(), 5, '.', ''),
115                'elapsed' => $step->getElapsed(),
116                'query'   => $step->getQuery(),
117                'params'  => $step->getParams(),
118                'errors'  => $step->getErrors()
119            ];
120        }
121
122        return $data;
123    }
124
125    /**
126     * Prepare header string
127     *
128     * @return string
129     */
130    public function prepareHeaderAsString(): string
131    {
132        $string  = ((!empty($this->name)) ? $this->name . ' ' : '') . 'Query Handler';
133        $string .= PHP_EOL . str_repeat('=', strlen($string)) . PHP_EOL;
134
135        return $string;
136    }
137
138    /**
139     * Prepare handler data as string
140     *
141     * @return string
142     */
143    public function prepareAsString(): string
144    {
145        $elapsed = $this->profiler->getElapsed();
146        $string  = "Start:\t\t\t" . number_format((float)$this->profiler->getStart(), 5, '.', '') . PHP_EOL;
147        $string .= "Finish:\t\t\t" . number_format((float)$this->profiler->getFinish(), 5, '.', '') . PHP_EOL;
148        $string .= "Elapsed:\t\t" . $elapsed . ' seconds' . PHP_EOL . PHP_EOL;
149
150        $string .= "Queries:" . PHP_EOL;
151        $string .= "--------" . PHP_EOL;
152        foreach ($this->profiler->getSteps() as $step) {
153            $string .= $step->getQuery() . ' [' . $step->getElapsed() . ']' . PHP_EOL;
154            $string .= "Start:\t\t\t" . number_format($step->getStart(), 5, '.', '') . PHP_EOL;
155            $string .= "Finish:\t\t\t" . number_format($step->getFinish(), 5, '.', '') . PHP_EOL;
156            if ($step->hasParams()) {
157                $string .= "Params:" . PHP_EOL;
158                foreach ($step->getParams() as $name => $value) {
159                    if (is_array($value)) {
160                        foreach ($value as $v) {
161                            $string .= "\t" . $name . ' => ' . $v . PHP_EOL;
162                        }
163                    } else {
164                        $string .= "\t" . $name . ' => ' . $value . PHP_EOL;
165                    }
166                }
167            }
168            if ($step->hasErrors()) {
169                $string .= "Errors:" . PHP_EOL;
170                foreach ($step->getErrors() as $time => $error) {
171                    $string .= "\t[" . number_format($time, 5, '.', '') . "]" . $error['error'] .
172                        ((!empty($error['number'])) ? ' [' . $error['number'] . ']' : '') . PHP_EOL;
173                }
174
175            }
176            $string .= PHP_EOL;
177        }
178
179        return $string;
180    }
181
182    /**
183     * Magic get method to return the profiler.
184     *
185     * @param  string $name
186     * @return mixed
187     */
188    public function __get(string $name): mixed
189    {
190        return match ($name) {
191            'profiler' => $this->profiler,
192            default    => null,
193        };
194    }
195
196}