@@ -85,11 +85,19 @@ public static function collect(Query $query)
8585 if (count (static ::$ queries ) < $ max ) {
8686 $ queryString = $ query ->getQuery ();
8787
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+
8896 static ::$ queries [] = [
8997 'query ' => $ query ,
9098 'string ' => $ queryString ,
9199 'duplicate ' => in_array ($ queryString , array_column (static ::$ queries , 'string ' , null ), true ),
92- 'trace ' => debug_backtrace () ,
100+ 'trace ' => $ backtrace ,
93101 ];
94102 }
95103 }
@@ -134,23 +142,39 @@ public function display(): array
134142 $ data ['queries ' ] = array_map (static function (array $ query ) {
135143 $ isDuplicate = $ query ['duplicate ' ] === true ;
136144
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+ }
139160
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 ' ]);
147165 }
148- $ traceLine ['file ' ] = str_ireplace (ROOTPATH , 'ROOTPATH/ ' , $ traceLine ['file ' ]);
149166
150- if (strpos ( $ traceLine [ ' file ' ], 'SYSTEMPATH ' ) ! == false ) {
151- continue ;
167+ if (strrpos ( $ line [ ' function ' ], '{closure} ' ) = == false ) {
168+ $ line [ ' function ' ] .= ' () ' ;
152169 }
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 );
154178 }
155179
156180 return [
@@ -159,8 +183,7 @@ public function display(): array
159183 'duration ' => ((float ) $ query ['query ' ]->getDuration (5 ) * 1000 ) . ' ms ' ,
160184 'sql ' => $ query ['query ' ]->debugToolbarDisplay (),
161185 'trace ' => $ query ['trace ' ],
162- 'trace-file ' => str_replace (ROOTPATH , '/ ' , $ line ['file ' ] ?? '' ),
163- 'trace-line ' => $ line ['line ' ] ?? '' ,
186+ 'trace-file ' => $ firstNonSystemLine ,
164187 'qid ' => md5 ($ query ['query ' ] . microtime ()),
165188 ];
166189 }, static ::$ queries );
0 commit comments