@@ -85,11 +85,19 @@ public static function collect(Query $query)
85
85
if (count (static ::$ queries ) < $ max ) {
86
86
$ queryString = $ query ->getQuery ();
87
87
88
+ $ backtrace = debug_backtrace (DEBUG_BACKTRACE_IGNORE_ARGS );
89
+
90
+ if (! is_cli ()) {
91
+ // when called in the browser, the first two trace arrays
92
+ // are from the DB event trigger, which are unneeded
93
+ $ backtrace = array_slice ($ backtrace , 2 );
94
+ }
95
+
88
96
static ::$ queries [] = [
89
97
'query ' => $ query ,
90
98
'string ' => $ queryString ,
91
99
'duplicate ' => in_array ($ queryString , array_column (static ::$ queries , 'string ' , null ), true ),
92
- 'trace ' => debug_backtrace () ,
100
+ 'trace ' => $ backtrace ,
93
101
];
94
102
}
95
103
}
@@ -134,23 +142,39 @@ public function display(): array
134
142
$ data ['queries ' ] = array_map (static function (array $ query ) {
135
143
$ isDuplicate = $ query ['duplicate ' ] === true ;
136
144
137
- // Find the first line that doesn't include `system` in the backtrace
138
- $ line = [];
145
+ $ firstNonSystemLine = '' ;
146
+
147
+ foreach ($ query ['trace ' ] as $ index => &$ line ) {
148
+ // simplify file and line
149
+ if (isset ($ line ['file ' ])) {
150
+ $ line ['file ' ] = clean_path ($ line ['file ' ]) . ': ' . $ line ['line ' ];
151
+ unset($ line ['line ' ]);
152
+ } else {
153
+ $ line ['file ' ] = '[internal function] ' ;
154
+ }
155
+
156
+ // find the first trace line that does not originate from `system/`
157
+ if ($ firstNonSystemLine === '' && strpos ($ line ['file ' ], 'SYSTEMPATH ' ) === false ) {
158
+ $ firstNonSystemLine = $ line ['file ' ];
159
+ }
139
160
140
- foreach ($ query ['trace ' ] as &$ traceLine ) {
141
- // Clean up the file paths
142
- $ traceLine ['file ' ] = str_ireplace (APPPATH , 'APPPATH/ ' , $ traceLine ['file ' ]);
143
- $ traceLine ['file ' ] = str_ireplace (SYSTEMPATH , 'SYSTEMPATH/ ' , $ traceLine ['file ' ]);
144
- if (defined ('VENDORPATH ' )) {
145
- // VENDORPATH is not defined unless `vendor/autoload.php` exists
146
- $ traceLine ['file ' ] = str_ireplace (VENDORPATH , 'VENDORPATH/ ' , $ traceLine ['file ' ]);
161
+ // simplify function call
162
+ if (isset ($ line ['class ' ])) {
163
+ $ line ['function ' ] = $ line ['class ' ] . $ line ['type ' ] . $ line ['function ' ];
164
+ unset($ line ['class ' ], $ line ['type ' ]);
147
165
}
148
- $ traceLine ['file ' ] = str_ireplace (ROOTPATH , 'ROOTPATH/ ' , $ traceLine ['file ' ]);
149
166
150
- if (strpos ( $ traceLine [ ' file ' ], 'SYSTEMPATH ' ) ! == false ) {
151
- continue ;
167
+ if (strrpos ( $ line [ ' function ' ], '{closure} ' ) = == false ) {
168
+ $ line [ ' function ' ] .= ' () ' ;
152
169
}
153
- $ line = empty ($ line ) ? $ traceLine : $ line ;
170
+
171
+ $ line ['function ' ] = str_repeat (chr (0xC2 ) . chr (0xA0 ), 8 ) . $ line ['function ' ];
172
+
173
+ // add index numbering padded with nonbreaking space
174
+ $ indexPadded = str_pad (sprintf ('%d ' , $ index + 1 ), 3 , ' ' , STR_PAD_LEFT );
175
+ $ indexPadded = preg_replace ('/\s/ ' , chr (0xC2 ) . chr (0xA0 ), $ indexPadded );
176
+
177
+ $ line ['index ' ] = $ indexPadded . str_repeat (chr (0xC2 ) . chr (0xA0 ), 4 );
154
178
}
155
179
156
180
return [
@@ -159,8 +183,7 @@ public function display(): array
159
183
'duration ' => ((float ) $ query ['query ' ]->getDuration (5 ) * 1000 ) . ' ms ' ,
160
184
'sql ' => $ query ['query ' ]->debugToolbarDisplay (),
161
185
'trace ' => $ query ['trace ' ],
162
- 'trace-file ' => str_replace (ROOTPATH , '/ ' , $ line ['file ' ] ?? '' ),
163
- 'trace-line ' => $ line ['line ' ] ?? '' ,
186
+ 'trace-file ' => $ firstNonSystemLine ,
164
187
'qid ' => md5 ($ query ['query ' ] . microtime ()),
165
188
];
166
189
}, static ::$ queries );
0 commit comments