Completed
Push — master ( 16ba6c...34b4d5 )
by Agel_Nash
03:40
created

DebugTrait::getLastQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php namespace AgelxNash\Modx\Evo\Database\Traits;
2
3
use mysqli;
4
use mysqli_result;
5
use AgelxNash\Modx\Evo\Database\Exceptions;
6
7
trait DebugTrait
8
{
9
    protected $debug = false;
10
    protected $queryCollection = [];
11
    protected $queryTime = 0;
12
    protected $executedQueries = 0;
13
    protected $lastQuery = '';
14
    protected $connectionTime = 0;
15
16
    protected $timeFormat = '%2.5f';
17
18
    /**
19
      * @return mysqli
20
      * @throws Exceptions\ConnectException
21
      * @throws Exceptions\QueryException
22
      */
23
    abstract public function getConnect() : mysqli;
24
25
    /**
26
     * @param mysqli_result $result
27
     * @return int
28
     */
29
    abstract public function getRecordCount(mysqli_result $result) : int;
30
31
    /**
32
     * @return int
33
     * @throws Exceptions\ConnectException
34
     * @throws Exceptions\QueryException
35
     */
36
    abstract public function getAffectedRows() : int;
37
38
    /**
39
     * @return string
40
     * @throws Exceptions\ConnectException
41
     * @throws Exceptions\QueryException
42
     */
43
    public function getLastError() : string
44
    {
45
        return $this->getConnect()->error;
46
    }
47
48
    /**
49
     * @return int
50
     * @throws Exceptions\ConnectException
51
     * @throws Exceptions\QueryException
52
     */
53
    public function getLastErrorNo() : int
54
    {
55
        return $this->getConnect()->errno;
56
    }
57
58
    /**
59
     * @param null|string $query
60
     * @throws Exceptions\ConnectException
61
     * @throws Exceptions\QueryException
62
     */
63
    public function checkLastError($query = null) : void
64
    {
65
        switch ($this->getLastErrorNo()) {
66
            case 1054:
67
            case 1060:
68
            case 1061:
69
            case 1062:
70
            case 1091:
71
                break;
72
            default:
73
                throw (new Exceptions\QueryException($this->getLastError()))
74
                    ->setQuery($query);
75
        }
76
    }
77
78
    /**
79
     * @param mysqli_result|bool $result
80
     * @param string $sql
81
     * @param int $iteration
82
     * @param int $time
83
     * @throws Exceptions\ConnectException
84
     * @throws Exceptions\QueryException
85
     */
86
    protected function collectQuery($result, string $sql, int $iteration, int $time) : void
87
    {
88
        $debug = debug_backtrace();
89
        array_shift($debug);
90
        array_shift($debug);
91
        $path = [];
92
        foreach ($debug as $line) {
93
            $path[] = ($line['class'] ? ($line['class'] . '::') : null) . $line['function'];
94
            /*$path[] = [
95
                'method' => ($line['class'] ? ($line['class'] . '::') : null) . $line['function'],
96
                'file' => ($line['file'] ? ($line['file'] . ':') : null) . ($line['line'] ?? 0)
97
            ];*/
98
        }
99
        $path = implode(' > ', array_reverse($path));
100
101
        $this->queryCollection[$iteration] = [
102
            'sql' => $sql,
103
            'time' => sprintf($this->timeFormat, $time),
104
            'rows' => (stripos($sql, 'SELECT') === 0) ? $this->getRecordCount($result) : $this->getAffectedRows(),
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of AgelxNash\Modx\Evo\Datab...Trait::getRecordCount() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

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

104
            'rows' => (stripos($sql, 'SELECT') === 0) ? $this->getRecordCount(/** @scrutinizer ignore-type */ $result) : $this->getAffectedRows(),
Loading history...
105
            'path' => $path,
106
            //'event' => $modx->event->name,
107
            //'element' => [
108
            //      'name' => $modx->event->activePlugin ?? ($modx->currentSnippet ?? null),
109
            //      'type' => $modx->event->activePlugin ? 'Plugin' : ($modx->currentSnippet ? 'Snippet' : 'Source code')
110
            // ]
111
        ];
112
    }
113
114
    /**
115
     * @return string
116
     */
117 1
    public function getLastQuery() : string
118
    {
119 1
        return $this->lastQuery;
120
    }
121
122
    /**
123
     * @return array
124
     */
125 1
    public function getAllExecutedQuery() : array
126
    {
127 1
        return $this->queryCollection;
128
    }
129
130
    /**
131
     * @return $this
132
     */
133
    public function flushExecutedQuery() : self
134
    {
135
        $this->queryCollection = [];
136
        $this->executedQueries = 0;
137
        $this->queryTime = 0;
138
        $this->lastQuery = '';
139
140
        return $this;
141
    }
142
143
    /**
144
     * @return string
145
     */
146
    public function renderExecutedQuery() : string
147
    {
148
        $out = '';
149
150
        foreach ($this->getAllExecutedQuery() as $i => $query) {
151
            $out .= '<fieldset style="text-align:left">';
152
            $out .= '<legend>Query ' . $i . ' - ' . $query['time'] . '</legend>';
153
            $out .= $query['sql'] . '<br><br>';
154
            if (! empty($query['element'])) {
155
                $out .= $query['element']['type'] . '  => ' . $query['element']['name'] . '<br>';
156
            }
157
            if (! empty($query['event'])) {
158
                $out .= 'Current Event  => ' . $query['event'] . '<br>';
159
            }
160
            $out .= 'Affected Rows => ' . $query['rows'] . '<br>';
161
            if (! empty($query['path'])) {
162
                $out .= 'Functions Path => ' . $query['path'] . '<br>';
163
            }
164
            /*$out .= 'Functions Path => ' . $query['path']['method'] . '<br>';
165
            $out .= empty($query['path']['file']) ?: $query['path']['file'] . '<br />';*/
166
            $out .= '</fieldset><br />';
167
        }
168
169
        return $out;
170
    }
171
172
    /**
173
     * @param bool $format
174
     * @return string|int
175
     */
176
    public function getConnectionTime(bool $format = false)
177
    {
178
        return $format ? sprintf($this->timeFormat, $this->connectionTime) : $this->connectionTime;
179
    }
180
181
    /**
182
     * @return string
183
     */
184
    public function renderConnectionTime() : string
185
    {
186
        return '<fieldset style="text-align:left">' .
187
            '<legend>Database connection</legend>' .
188
            'Database connection was created in ' . $this->getConnectionTime(true) . ' s.' .
189
            '</fieldset>' .
190
            '<br />';
191
    }
192
193
    /**
194
     * @param bool $flag
195
     * @return $this
196
     */
197 1
    public function setDebug(bool $flag) : self
198
    {
199 1
        $this->debug = $flag;
200
201 1
        return $this;
202
    }
203
204
    /**
205
     * @return bool
206
     */
207 1
    public function isDebug() : bool
208
    {
209 1
        return $this->debug;
210
    }
211
}
212