Query Monitor - Version 3.3.0

Version Description

Download this release

Release Info

Developer johnbillion
Plugin Icon 128x128 Query Monitor
Version 3.3.0
Comparing to
See all releases

Code changes from version 3.2.2 to 3.3.0

Files changed (52) hide show
  1. assets/query-monitor-dark.css +520 -549
  2. assets/query-monitor.css +520 -549
  3. assets/query-monitor.js +101 -38
  4. classes/Backtrace.php +33 -24
  5. classes/Collector.php +129 -0
  6. classes/Collectors.php +1 -0
  7. classes/Dispatcher.php +1 -1
  8. classes/Util.php +27 -0
  9. collectors/admin.php +23 -0
  10. collectors/assets.php +154 -53
  11. collectors/assets_scripts.php +42 -0
  12. collectors/assets_styles.php +35 -0
  13. collectors/block_editor.php +57 -6
  14. collectors/cache.php +14 -4
  15. collectors/caps.php +30 -0
  16. collectors/hooks.php +7 -14
  17. collectors/http.php +66 -28
  18. collectors/languages.php +73 -3
  19. collectors/logger.php +11 -5
  20. collectors/php_errors.php +1 -2
  21. collectors/redirects.php +1 -1
  22. collectors/request.php +72 -0
  23. collectors/theme.php +37 -5
  24. composer.json +15 -10
  25. dispatchers/Html.php +51 -19
  26. dispatchers/Redirect.php +1 -1
  27. dispatchers/WP_Die.php +143 -0
  28. output/Html.php +73 -6
  29. output/html/assets.php +112 -243
  30. output/html/assets_scripts.php +28 -0
  31. output/html/assets_styles.php +28 -0
  32. output/html/block_editor.php +29 -16
  33. output/html/caps.php +2 -2
  34. output/html/conditionals.php +11 -5
  35. output/html/db_callers.php +7 -7
  36. output/html/db_components.php +5 -5
  37. output/html/db_dupes.php +15 -2
  38. output/html/db_queries.php +53 -24
  39. output/html/environment.php +5 -32
  40. output/html/hooks.php +32 -41
  41. output/html/http.php +4 -13
  42. output/html/languages.php +11 -6
  43. output/html/logger.php +3 -3
  44. output/html/overview.php +51 -18
  45. output/html/php_errors.php +3 -3
  46. output/html/request.php +2 -2
  47. output/html/theme.php +4 -4
  48. output/html/timing.php +3 -2
  49. output/html/transients.php +1 -1
  50. query-monitor.php +3 -3
  51. readme.txt +103 -103
  52. wp-content/db.php +1 -1
assets/query-monitor-dark.css CHANGED
@@ -10,7 +10,6 @@
10
  * The colours below are loosely based on the WordPress branding colours.
11
  * https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
12
  */
13
- /* === Admin Toolbar === */
14
  #wpadminbar .quicklinks .menupop ul li.qm-true > a {
15
  color: #8c8 !important;
16
  }
@@ -84,987 +83,959 @@ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover
84
  }
85
 
86
  #wpadminbar #wp-admin-bar-query-monitor .ab-icon {
87
- font: 18px/44px 'Open Sans', sans-serif !important;
88
- /* @todo remove open sans */
89
- width: auto !important;
90
- padding: 0 10px !important;
91
  color: #aaa !important;
92
  display: none !important;
 
 
 
93
  }
94
 
95
  @media screen and (max-width: 782px) {
96
- /* force menu icon to show up */
97
  #wpadminbar #wp-admin-bar-query-monitor .ab-icon {
98
  display: block !important;
99
  }
100
 
101
- /* hide menu text */
102
  #wpadminbar #wp-admin-bar-query-monitor .ab-label {
103
  display: none !important;
104
  }
105
  }
106
- /* === Main QM Panel === */
107
- #query-monitor,
108
- #query-monitor dl,
109
- #query-monitor dt,
110
- #query-monitor dd,
111
- #query-monitor button,
112
- #query-monitor label,
113
- #query-monitor select,
114
- #query-monitor table,
115
- #query-monitor td,
116
- #query-monitor th,
117
- #query-monitor ul,
118
- #query-monitor ol,
119
- #query-monitor li,
120
- #query-monitor code,
121
- #query-monitor a,
122
- #query-monitor h1,
123
- #query-monitor h2,
124
- #query-monitor h3,
125
- #query-monitor h4,
126
- #query-monitor h5,
127
- #query-monitor h6,
128
- #query-monitor section,
129
- #query-monitor nav,
130
- #query-monitor p {
131
- /* reset */
132
  background: transparent !important;
133
- color: #bbc8d4 !important;
 
 
134
  box-sizing: border-box !important;
135
- text-align: left !important;
 
 
 
 
 
136
  font-style: normal !important;
137
  font-weight: normal !important;
138
- font-size: 12px !important;
139
  line-height: 18px !important;
140
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
141
- border: none !important;
142
- padding: 0 !important;
143
  margin: 0 !important;
144
- vertical-align: baseline !important;
 
 
 
 
145
  text-shadow: none !important;
146
  text-transform: none !important;
147
- text-decoration: none !important;
148
- -webkit-font-smoothing: auto !important;
149
- letter-spacing: normal !important;
150
- border-radius: 0 !important;
151
  transition: none !important;
152
- word-wrap: normal !important;
153
  word-break: normal !important;
154
- outline: none !important;
155
- box-shadow: none !important;
156
- text-indent: 0 !important;
157
- float: none !important;
158
- clear: both !important;
159
  }
160
- #query-monitor::before, #query-monitor::after,
161
- #query-monitor dl::before,
162
- #query-monitor dl::after,
163
- #query-monitor dt::before,
164
- #query-monitor dt::after,
165
- #query-monitor dd::before,
166
- #query-monitor dd::after,
167
- #query-monitor button::before,
168
- #query-monitor button::after,
169
- #query-monitor label::before,
170
- #query-monitor label::after,
171
- #query-monitor select::before,
172
- #query-monitor select::after,
173
- #query-monitor table::before,
174
- #query-monitor table::after,
175
- #query-monitor td::before,
176
- #query-monitor td::after,
177
- #query-monitor th::before,
178
- #query-monitor th::after,
179
- #query-monitor ul::before,
180
- #query-monitor ul::after,
181
- #query-monitor ol::before,
182
- #query-monitor ol::after,
183
- #query-monitor li::before,
184
- #query-monitor li::after,
185
- #query-monitor code::before,
186
- #query-monitor code::after,
187
- #query-monitor a::before,
188
- #query-monitor a::after,
189
- #query-monitor h1::before,
190
- #query-monitor h1::after,
191
- #query-monitor h2::before,
192
- #query-monitor h2::after,
193
- #query-monitor h3::before,
194
- #query-monitor h3::after,
195
- #query-monitor h4::before,
196
- #query-monitor h4::after,
197
- #query-monitor h5::before,
198
- #query-monitor h5::after,
199
- #query-monitor h6::before,
200
- #query-monitor h6::after,
201
- #query-monitor section::before,
202
- #query-monitor section::after,
203
- #query-monitor nav::before,
204
- #query-monitor nav::after,
205
- #query-monitor p::before,
206
- #query-monitor p::after {
207
  display: none !important;
208
  }
209
-
210
- #query-monitor {
211
  background: #23282d !important;
212
- margin: 0 !important;
213
  border-top: 1px solid #bbc8d4 !important;
214
- text-align: left !important;
215
- display: none;
216
- position: fixed;
217
- z-index: 99998 !important;
218
  bottom: 0 !important;
 
 
219
  left: 0 !important;
 
 
220
  right: 0 !important;
221
- width: 100% !important;
222
- direction: ltr !important;
223
  }
224
- #query-monitor ::selection {
225
  background-color: #B9D6FB !important;
226
  color: #bbc8d4 !important;
227
  }
228
- #query-monitor strong,
229
- #query-monitor b {
230
  font-weight: bold !important;
231
  }
232
- #query-monitor em,
233
- #query-monitor i {
234
  font-style: italic !important;
235
  }
236
-
237
- #query-monitor.qm-show,
238
- #query-monitor.qm-peek {
239
- height: 27px;
240
  display: flex;
241
  flex-direction: column !important;
 
242
  }
243
-
244
- #query-monitor.qm-show {
245
  height: 40%;
 
246
  }
247
-
248
- #query-monitor #qm-wrapper {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  display: flex;
250
  flex-grow: 1 !important;
251
  /* Fix nested scrolling in Firefox. See https://bugzilla.mozilla.org/show_bug.cgi?id=1043520: */
252
  min-height: 0;
253
  }
254
- #query-monitor #qm-title {
 
255
  background: #32373c !important;
256
  border-bottom: 1px solid #bbc8d4 !important;
257
  cursor: ns-resize !important;
258
- align-items: center !important;
259
  display: flex !important;
260
- padding: 0 0 0 5px !important;
261
- height: 27px !important;
262
  flex-shrink: 0 !important;
 
 
263
  -moz-user-select: none !important;
264
  -ms-user-select: none !important;
265
  -webkit-user-select: none !important;
266
  user-select: none !important;
267
  }
268
- #query-monitor #qm-title .qm-title-heading {
269
- flex-grow: 1 !important;
270
  border-right: 1px solid #bbb !important;
 
271
  margin-right: 6px !important;
272
  }
273
- #query-monitor #qm-title div.qm-title-heading {
274
  display: none;
275
  }
276
- #query-monitor #qm-title .qm-title-button {
277
  flex-shrink: 0 !important;
278
  }
279
- #query-monitor #qm-title .dashicons {
280
  transition: none !important;
281
  }
282
- #query-monitor #qm-title .qm-button-container-settings .dashicons {
283
  font-size: 17px !important;
284
  margin: 3px 0 2px !important;
285
  }
286
- #query-monitor #qm-title .qm-button-container-close .dashicons {
 
 
 
 
 
 
 
287
  margin: 2px 0 3px !important;
288
  }
289
- #query-monitor #qm-title button {
290
- color: #bbc8d4 !important;
 
 
 
 
291
  background: transparent !important;
 
292
  cursor: pointer !important;
293
- margin: 0 0 0 0px !important;
294
  display: inline-block !important;
295
- padding: 0px 4px !important;
296
  min-width: auto !important;
 
297
  }
298
- #query-monitor #qm-title button:focus,
299
- #query-monitor #qm-title button:hover {
300
- color: #32373c !important;
301
  background: #bbc8d4 !important;
 
302
  }
303
- #query-monitor #qm-title button:active {
304
  background: #ccc !important;
305
  }
306
- #query-monitor #qm-title button.qm-button-active {
307
  color: #3879d9 !important;
308
  }
309
- #query-monitor .qm {
310
  display: none !important;
311
  }
312
- #query-monitor #qm-panel-menu {
313
- overflow-y: scroll !important;
314
- flex-shrink: 0 !important;
315
  background: #23282d !important;
 
 
316
  overscroll-behavior: contain !important;
317
  }
318
- #query-monitor #qm-panel-menu ul {
319
- padding: 0 !important;
320
- margin: 0 !important;
321
  list-style: none !important;
322
- }
323
- #query-monitor #qm-panel-menu li {
324
  padding: 0 !important;
 
 
 
325
  margin: 0 !important;
 
326
  }
327
- #query-monitor #qm-panel-menu li button {
 
 
 
 
 
328
  display: block !important;
329
  padding: 8px 28px 8px 6px !important;
330
- color: #bbc8d4 !important;
331
- text-decoration: none !important;
332
- border-bottom: 1px solid #32373c !important;
333
  position: relative !important;
334
- border-right: 1px solid #bbc8d4 !important;
335
- background: #23282d !important;
336
  width: 100% !important;
337
- cursor: pointer !important;
338
  }
339
- #query-monitor #qm-panel-menu li button:focus,
340
- #query-monitor #qm-panel-menu li button:hover {
341
  background: #def !important;
342
  color: #222 !important;
343
  }
344
- #query-monitor #qm-panel-menu li button:focus {
345
  text-decoration: underline !important;
346
  }
347
- #query-monitor #qm-panel-menu li button.qm-selected-menu {
 
 
 
 
348
  background: #0073aa !important;
349
  color: #fff !important;
350
  text-shadow: 0 -1px 1px #006291, 1px 0 1px #006291, 0 1px 1px #006291, -1px 0 1px #006291 !important;
351
  }
352
- #query-monitor #qm-panel-menu li button.qm-selected-menu:focus {
353
  background: #0084c4 !important;
354
  color: #fff !important;
355
  }
356
- #query-monitor #qm-panel-menu li button.qm-selected-menu:after {
357
- right: -1px;
358
  border: solid 8px transparent;
 
359
  content: " ";
 
360
  height: 0;
361
- width: 0;
362
- position: absolute;
363
  pointer-events: none;
364
- border-right-color: #23282d;
 
365
  top: 50%;
366
- margin-top: -8px;
367
  }
368
- #query-monitor #qm-panels {
369
  flex-grow: 1 !important;
370
  overflow-y: scroll !important;
371
  overscroll-behavior: contain !important;
372
  }
373
- #query-monitor .qm.qm-panel-show {
374
  display: block !important;
375
  }
376
- #query-monitor .qm:focus {
377
  outline: 0 !important;
378
  /* @TODO might not need this any more */
379
  }
380
- #query-monitor .qm-non-tabular {
381
  padding: 10px 20px !important;
382
  }
383
- #query-monitor .qm-boxed {
384
  display: flex !important;
385
  flex-wrap: wrap !important;
386
  }
387
- #query-monitor .qm-boxed:not(#qm-broken) + .qm-boxed {
388
  border-top: 1px solid #bbc8d4 !important;
389
  padding-top: 10px !important;
390
  }
391
- #query-monitor .qm-boxed-wrap {
392
  flex-wrap: wrap !important;
393
  }
394
- #query-monitor .qm .qm-none {
395
  margin: 2em !important;
396
  }
397
- #query-monitor .qm .qm-none p {
398
- text-align: center !important;
399
  font-style: italic !important;
 
400
  }
401
- #query-monitor .qm table {
402
- color: #bbc8d4 !important;
 
403
  border-collapse: collapse !important;
404
  box-shadow: none !important;
405
- width: 100% !important;
406
- table-layout: auto !important;
407
  margin: 0 !important;
408
- border: none !important;
409
- border-bottom: 1px solid #23282d !important;
410
  }
411
- #query-monitor .qm table + table {
412
- margin-top: 5px !important;
413
  border-top: 1px solid #23282d !important;
 
414
  }
415
- #query-monitor #qm-conditionals table,
416
- #query-monitor #qm-overview table {
417
- table-layout: fixed !important;
418
- }
419
- #query-monitor .qm tr {
420
  border: none !important;
421
  }
422
- #query-monitor .qm tbody th,
423
- #query-monitor .qm tbody td,
424
- #query-monitor .qm tfoot th,
425
- #query-monitor .qm tfoot td {
426
  border: 1px solid #23282d !important;
427
  padding: 5px 5px 4px 5px !important;
428
  }
429
- #query-monitor .qm tbody th,
430
- #query-monitor .qm tbody td {
431
- border-top: none !important;
432
  border-bottom: none !important;
 
433
  }
434
- #query-monitor .qm thead th {
435
- box-shadow: 0px 1px 0px #23282d !important;
436
  border: 1px solid #23282d !important;
437
  border-top: none !important;
 
438
  padding: 5px !important;
439
  position: -webkit-sticky !important;
440
  position: sticky !important;
441
  top: 0 !important;
442
- background: #32373c !important;
443
  z-index: 1 !important;
444
  }
445
- #query-monitor .qm thead .qm-th {
446
  display: flex !important;
447
  }
448
- #query-monitor .qm tfoot tr td,
449
- #query-monitor .qm tfoot tr th {
450
- box-shadow: inset 0px 1px 0px #23282d !important;
451
  border: 1px solid #23282d !important;
452
  border-bottom: none !important;
453
- background: #32373c !important;
 
454
  position: -webkit-sticky !important;
455
  position: sticky !important;
456
- bottom: 0 !important;
457
  }
458
- #query-monitor .qm th:first-child,
459
- #query-monitor .qm td:first-child {
460
  border-left: none !important;
461
  }
462
- #query-monitor .qm th:last-child,
463
- #query-monitor .qm td:last-child {
464
  border-right: none !important;
465
  }
466
- #query-monitor .qm tfoot td.qm-num,
467
- #query-monitor .qm tfoot th.qm-num,
468
- #query-monitor .qm thead td.qm-num,
469
- #query-monitor .qm thead th.qm-num {
470
  width: 5.5em !important;
471
  }
472
- #query-monitor .qm th.qm-num,
473
- #query-monitor .qm td.qm-num {
474
  text-align: right !important;
475
  }
476
- #query-monitor .qm td.qm-row-sql {
477
  min-width: 25em !important;
478
  }
479
- #query-monitor .qm td.qm-row-block-html {
480
  max-width: 40em !important;
481
  }
482
- #query-monitor .qm tr.qm-warn td.qm-col-status,
483
- #query-monitor .qm td.qm-url,
484
- #query-monitor .qm th.qm-col-message,
485
- #query-monitor .qm td.qm-row-component {
486
  min-width: 15em !important;
487
  }
488
- #query-monitor .qm td.qm-has-toggle p,
489
- #query-monitor .qm td .qm-toggler {
490
  padding: 0 22px 0 0 !important;
491
  position: relative !important;
492
  }
493
- #query-monitor .qm td.qm-has-toggle:not(.qm-toggled-on) .qm-supplemental {
494
  display: none;
495
  }
496
- #query-monitor .qm .qm-inner-toggle {
497
  padding: 4px 6px !important;
498
  }
499
-
500
- .qm-has-inner .qm-toggled > table {
501
  border-top: 1px solid #23282d !important;
502
  }
503
-
504
- .qm-inner {
505
- border-collapse: collapse !important;
506
- margin: 0 !important;
507
- border-style: hidden !important;
508
- width: 100% !important;
509
- }
510
-
511
- #query-monitor .qm td.qm-has-inner .qm-toggler,
512
- #query-monitor .qm td.qm-has-inner {
513
  padding: 0 !important;
514
  }
515
- #query-monitor .qm-non-tabular h3 {
516
- margin: 0 0 15px 0 !important;
517
  font-size: 14px !important;
 
518
  }
519
- #query-monitor .qm-non-tabular h4 {
520
- margin: 20px 0 10px !important;
 
 
 
 
 
 
 
521
  font-size: 12px !important;
 
522
  }
523
- #query-monitor .qm-non-tabular p {
524
  margin-bottom: 10px !important;
525
  }
526
- #query-monitor .qm-non-tabular dd {
527
  margin: 0 0 10px 10px !important;
528
  }
529
- #query-monitor .qm-non-tabular h3 a {
530
  float: right !important;
531
  }
532
- #query-monitor .qm-non-tabular .qm-item {
533
  display: inline-block !important;
534
  margin: 0 20px 5px 0 !important;
535
  }
536
- #query-monitor .qm-non-tabular section,
537
- #query-monitor .qm-non-tabular .qm-section {
538
  margin: 0 0 30px 0 !important;
539
  }
540
- #query-monitor .qm-non-tabular .qm-boxed section,
541
- #query-monitor .qm-non-tabular .qm-boxed .qm-section {
542
- margin: 0 20px 10px 0 !important;
543
  border-right: 1px solid #bbc8d4 !important;
 
544
  padding: 10px 20px 10px 0 !important;
545
  }
546
- #query-monitor .qm-non-tabular .qm-boxed section:last-child,
547
- #query-monitor .qm-non-tabular .qm-boxed .qm-section:last-child {
548
- margin-right: 0 !important;
549
  border-right: none !important;
 
550
  padding-right: 20px !important;
551
  }
552
- #query-monitor .qm-non-tabular table {
553
  border-bottom-color: #23282d !important;
554
  }
555
- #query-monitor .qm ol,
556
- #query-monitor .qm ul {
557
  list-style: none !important;
558
  }
559
- #query-monitor .qm li {
560
  display: list-item !important;
561
  list-style: none !important;
562
  }
563
- #query-monitor .qm li::before {
564
  content: '' !important;
565
  }
566
- #query-monitor .qm .qm-has-toggle ol.qm-numbered li {
567
  list-style: none !important;
568
  }
569
- #query-monitor .qm .qm-toggled-on ol.qm-numbered li,
570
- #query-monitor .qm ol.qm-numbered li {
571
  list-style: decimal inside !important;
572
  }
573
- #query-monitor .qm code,
574
- #query-monitor .qm pre {
 
575
  font-size: 11px !important;
576
  line-height: 18px !important;
577
- font-family: Menlo, Monaco, Consolas, monospace !important;
578
  }
579
- #query-monitor .qm pre {
580
  background: transparent !important;
581
- margin: 0 !important;
582
- width: auto !important;
583
  height: auto !important;
 
584
  padding: 0 !important;
 
585
  }
586
- #query-monitor .qm .qm-true code,
587
- #query-monitor .qm p.qm-true,
588
- #query-monitor .qm span.qm-true,
589
- #query-monitor .qm td.qm-true {
590
  color: #4a4 !important;
591
  }
592
- #query-monitor .qm .qm-false code,
593
- #query-monitor .qm span.qm-false,
594
- #query-monitor .qm td.qm-false {
595
  color: #999 !important;
596
  }
597
- #query-monitor .qm .qm-num,
598
- #query-monitor .qm code,
599
- #query-monitor .qm .qm-nowrap {
600
  white-space: nowrap !important;
601
  }
602
- #query-monitor .qm .qm-wrap code,
603
- #query-monitor .qm .qm-wrap {
604
- word-wrap: break-word !important;
605
- word-break: break-all !important;
606
  white-space: normal !important;
607
- }
608
- #query-monitor .qm .qm-pre-wrap code {
609
- word-wrap: break-word !important;
610
  word-break: break-all !important;
 
 
 
611
  white-space: pre-wrap !important;
 
 
612
  }
613
- #query-monitor .qm .qm-sticky {
614
  position: sticky !important;
615
  top: 36px !important;
616
  }
617
- #query-monitor .qm .qm-current,
618
- #query-monitor .qm td.qm-has-toggle p,
619
- #query-monitor .qm .qm-nonselectsql code,
620
- #query-monitor .qm .qm-nonselectsql {
621
  color: #a6a !important;
622
  }
623
- #query-monitor .qm .qm-info {
624
  color: #777 !important;
625
  }
626
- #query-monitor .qm .qm-supplemental {
627
- margin-right: 0.75em !important;
628
  margin-left: 0.75em !important;
 
629
  }
630
- #query-monitor .qm td.qm-toggled-on .qm-inverse-toggled,
631
- #query-monitor .qm td .qm-toggled {
632
  display: none;
633
  }
634
- #query-monitor .qm button.qm-button,
635
- #query-monitor .qm .qm-toggle {
636
- color: #fff !important;
637
- font-weight: normal !important;
638
  background: #0085ba !important;
639
- cursor: pointer !important;
640
  border: 1px solid #0073a1 !important;
641
  border-radius: 2px !important;
 
 
 
642
  text-shadow: 0 -1px 1px #0073a1, 1px 0 1px #0073a1, 0 1px 1px #0073a1, -1px 0 1px #0073a1 !important;
643
  }
644
- #query-monitor .qm .qm-toggle {
645
- padding: 0 !important;
646
  font-family: Menlo, Monaco, Consolas, monospace !important;
 
 
 
 
647
  position: absolute !important;
648
- top: 0 !important;
649
  right: 0 !important;
650
- left: auto !important;
651
- bottom: auto !important;
652
  text-align: center !important;
653
- line-height: 16px !important;
654
- height: 18px !important;
655
  width: 18px !important;
656
  }
657
- #query-monitor .qm button {
658
  cursor: pointer !important;
659
  }
660
- #query-monitor .qm button.qm-button {
661
  padding: 4px 10px !important;
662
  }
663
- #query-monitor .qm .qm-has-inner .qm-toggle {
664
- top: 5px !important;
665
  right: 5px !important;
 
666
  }
667
- #query-monitor .qm button.qm-button:hover,
668
- #query-monitor .qm button.qm-button:focus,
669
- #query-monitor .qm .qm-toggle:focus,
670
- #query-monitor .qm .qm-toggle:hover {
671
- text-decoration: none !important;
672
- color: #fff !important;
673
  background: #0094ce !important;
 
 
674
  }
675
- #query-monitor .qm tbody tr.qm-odd td,
676
- #query-monitor .qm tbody tr.qm-odd th {
677
  background: #32373c !important;
678
  }
679
-
680
- .qm-debug-bar tbody tr:hover th,
681
- .qm-debug-bar tbody tr:hover td {
682
- background: #fff !important;
683
- /* transparent? */
684
- }
685
-
686
- #query-monitor .qm-non-tabular .qm-warn,
687
- #query-monitor .qm thead tr .qm-warn,
688
- #query-monitor .qm tbody tr .qm-warn {
689
  background-color: #800 !important;
690
  color: #fff0f0 !important;
691
  }
692
- #query-monitor .qm tbody tr th.qm-warn,
693
- #query-monitor .qm tbody tr td.qm-warn,
694
- #query-monitor .qm tbody tr.qm-warn td,
695
- #query-monitor .qm tbody tr.qm-warn th {
696
  background-color: #800 !important;
697
- box-shadow: inset 0 -1px #ffd6d6 !important;
698
  border-color: #ffd6d6 !important;
 
699
  color: #fff0f0 !important;
700
  }
701
- #query-monitor .qm-non-tabular .qm-warn code,
702
- #query-monitor .qm tbody .qm-warn li,
703
- #query-monitor .qm tbody .qm-warn .qm-info,
704
- #query-monitor .qm tbody .qm-warn code {
705
- color: #fff0f0 !important;
706
  background-color: transparent !important;
 
707
  }
708
- #query-monitor .qm .qm-notice {
709
  background: #def !important;
710
  border: 1px solid #aad5ff !important;
711
- padding: 10px 20px 0 !important;
712
  margin: 0 0 10px 0 !important;
 
713
  }
714
- #query-monitor .qm .dashicons {
715
  font-size: 16px !important;
716
- width: 16px !important;
717
  height: 16px !important;
718
  margin-right: 0.3em !important;
719
  transition: none !important;
 
720
  }
721
- #query-monitor .qm .qm-dashicons-yes {
722
- color: #fff !important;
723
  background-color: #0a0 !important;
724
  border-radius: 50% !important;
 
725
  }
726
- #query-monitor .qm tbody tr.qm-hovered th,
727
- #query-monitor .qm tbody tr.qm-hovered td,
728
- #query-monitor .qm tbody tr:hover th,
729
- #query-monitor .qm tbody tr:hover td {
730
  background: #3e444a !important;
731
  }
732
- #query-monitor .qm thead th.qm-filtered select.qm-filter {
733
  background-color: #57572a !important;
734
  color: #bbc8d4 !important;
735
  }
736
- #query-monitor .qm tbody tr td.qm-highlight,
737
- #query-monitor .qm tbody tr.qm-highlight td {
738
  background-color: #57572a !important;
739
- box-shadow: inset 0 -1px #660 !important;
740
  border-color: #660 !important;
 
741
  color: #bbc8d4 !important;
742
  }
743
-
744
- #query-monitor .qm tbody .qm-warn a code,
745
- #qm-title a,
746
- #query-monitor .qm a code,
747
- #query-monitor .qm a {
748
  color: #30ceff !important;
749
- text-decoration: none !important;
750
  cursor: pointer !important;
 
751
  }
752
- #query-monitor .qm tbody .qm-warn a code:after, #query-monitor .qm tbody .qm-warn a code:focus, #query-monitor .qm tbody .qm-warn a code:hover,
753
- #qm-title a:after,
754
- #qm-title a:focus,
755
- #qm-title a:hover,
756
- #query-monitor .qm a code:after,
757
- #query-monitor .qm a code:focus,
758
- #query-monitor .qm a code:hover,
759
- #query-monitor .qm a:after,
760
- #query-monitor .qm a:focus,
761
- #query-monitor .qm a:hover {
762
- text-decoration: underline !important;
 
 
763
  color: #4092d2 !important;
 
764
  }
765
-
766
- #query-monitor .qm a.qm-external-link:after,
767
- #query-monitor .qm a.qm-link:after,
768
- #query-monitor .qm a.qm-edit-link:after,
769
- #query-monitor .qm a.qm-filter-trigger:after {
770
- font-family: dashicons !important;
771
- text-decoration: none !important;
772
- visibility: hidden !important;
773
  display: inline-block !important;
 
774
  font-size: 13px !important;
 
775
  line-height: 15px !important;
776
  position: relative !important;
 
777
  top: 2px !important;
778
- left: 2px !important;
779
  }
780
-
781
- #query-monitor .qm a.qm-external-link:after,
782
- #query-monitor.qm-touch .qm a.qm-link:after,
783
- #query-monitor .qm a.qm-link:hover:after,
784
- #query-monitor .qm a.qm-link:focus:after,
785
- #query-monitor.qm-touch .qm a.qm-edit-link:after,
786
- #query-monitor .qm a.qm-edit-link:hover:after,
787
- #query-monitor .qm a.qm-edit-link:focus:after,
788
- #query-monitor.qm-touch .qm a.qm-filter-trigger:after,
789
- #query-monitor .qm a.qm-filter-trigger:hover:after,
790
- #query-monitor .qm a.qm-filter-trigger:focus:after {
791
  visibility: visible !important;
792
  }
793
-
794
- #query-monitor .qm a.qm-filter-trigger:after {
795
  content: '\f536' !important;
796
  }
797
-
798
- #query-monitor .qm a.qm-edit-link:after {
799
  content: '\f464' !important;
800
  }
801
-
802
- #query-monitor .qm a.qm-external-link:after,
803
- #query-monitor .qm a.qm-link:after {
804
  content: '\f504' !important;
805
  }
806
-
807
- #query-monitor #qm-ajax-errors {
808
  display: none;
809
  }
810
-
811
- /* Filters */
812
- #query-monitor button,
813
- #query-monitor select {
814
- margin: 0 !important;
815
  height: auto !important;
 
816
  width: auto !important;
817
- background: none !important;
818
  }
819
-
820
- #query-monitor .qm label {
821
- cursor: pointer !important;
822
  color: #bbc8d4 !important;
823
- font-weight: normal !important;
824
  font-size: 12px !important;
825
  font-style: normal !important;
 
826
  margin: 0 !important;
827
  }
828
-
829
- #query-monitor .qm thead label {
830
  flex-grow: 1 !important;
831
  }
832
-
833
- #query-monitor .qm .qm-filter-container {
834
  display: flex !important;
835
  }
836
-
837
- #query-monitor .qm .qm-filter-container label {
838
  cursor: default !important;
 
839
  }
840
-
841
- #query-monitor .qm .qm-filter-container div {
842
  /* Some themes use Select2 etc on all selects. This hides that. */
843
  display: none !important;
844
  }
845
-
846
- #query-monitor .qm select.qm-filter {
847
- display: block !important;
848
- margin: 0 0 0 5px !important;
849
- outline: 1px solid #bbc8d4 !important;
850
- border: none !important;
851
- padding: 0 !important;
852
- background: #32373c !important;
853
- color: #bbc8d4 !important;
854
- height: auto !important;
855
- width: auto !important;
856
- float: none !important;
857
- cursor: pointer !important;
858
  -webkit-appearance: menulist !important;
859
  -moz-appearance: menulist !important;
860
  appearance: menulist !important;
 
 
 
 
 
 
 
861
  letter-spacing: normal !important;
 
862
  max-width: 10em !important;
 
 
 
863
  }
864
-
865
- #query-monitor .qm select.qm-filter:hover {
866
  background: #32373c !important;
867
  }
868
-
869
- .qm-hide,
870
- .qm-hide-scripts-dependencies,
871
- .qm-hide-styles-dependencies,
872
- .qm-hide-scripts-dependents,
873
- .qm-hide-styles-dependents,
874
- .qm-hide-scripts-host,
875
- .qm-hide-styles-host,
876
- .qm-hide-user,
877
- .qm-hide-result,
878
- .qm-hide-name,
879
- .qm-hide-type,
880
- .qm-hide-caller,
881
- .qm-hide-component {
882
  display: none !important;
883
  }
884
-
885
- /* Sorters */
886
- #query-monitor .qm thead th.qm-sortable-column {
887
  cursor: pointer !important;
888
  }
889
-
890
- #query-monitor .qm thead th.qm-sortable-column:hover {
891
  background: #32373c !important;
892
  }
893
-
894
- #query-monitor .qm .qm-sort-heading {
895
  flex-grow: 1 !important;
896
  }
897
-
898
- #query-monitor .qm .qm-sort-controls {
899
- text-align: right !important;
900
  flex-shrink: 0 !important;
 
901
  }
902
-
903
- #query-monitor .qm .qm-sortable-column .qm-sort-arrow {
 
904
  font-family: dashicons !important;
905
  font-size: 23px !important;
906
- color: #ccc !important;
907
  margin: 0 !important;
908
  width: 16px !important;
909
- height: 10px !important;
910
- display: block !important;
911
  }
912
-
913
- #query-monitor .qm .qm-sorted-desc .qm-sort-arrow,
914
- #query-monitor .qm .qm-sorted-asc .qm-sort-arrow {
915
  color: #bbc8d4 !important;
916
  }
917
-
918
- #query-monitor .qm thead th.qm-sortable-column:hover .qm-sort-arrow {
919
  color: #0073aa !important;
920
  }
921
-
922
- #query-monitor .qm .qm-sortable-column .qm-sort-arrow::before {
923
  content: "\f140" !important;
924
- top: 4px !important;
925
- right: 0 !important;
926
  position: absolute !important;
 
 
927
  }
928
-
929
- #query-monitor .qm .qm-sortable-column.qm-sorted-asc .qm-sort-arrow::before {
930
  content: "\f142" !important;
931
  }
932
-
933
- #query-monitor .qm button:focus,
934
- #query-monitor .qm a:focus,
935
- #query-monitor .qm select:focus {
936
  box-shadow: 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, 0.8) !important;
937
  }
938
-
939
- #query-monitor .qm-screen-reader-text,
940
- #query-monitor .screen-reader-text {
941
- position: absolute !important;
 
942
  margin: -1px !important;
 
943
  padding: 0 !important;
944
- height: 1px !important;
945
  width: 1px !important;
946
- overflow: hidden !important;
947
- clip: rect(0 0 0 0) !important;
948
- border: 0 !important;
949
  }
950
-
951
  @media screen and (max-width: 782px) {
952
- #query-monitor #qm-panel-menu,
953
- #query-monitor #qm-title h1.qm-title-heading {
954
  display: none;
955
  }
956
-
957
- #query-monitor #qm-title div.qm-title-heading {
958
  display: block;
959
  }
960
  }
961
- /* State Toggle */
962
- #query-monitor [data-qm-state="off"] [data-qm-state-visibility="on"],
963
- #query-monitor [data-qm-state="on"] [data-qm-state-visibility="off"] {
964
  display: none;
965
  }
966
-
967
- /* No-JS tweaks */
968
- .qm-no-js .qm-sort-controls,
969
- .qm-no-js .qm-toggle,
970
- .qm-no-js select.qm-filter {
971
  display: none !important;
972
  }
973
-
974
- /* Debug bar add-ons */
975
- #query-monitor .qm.qm-debug-bar textarea,
976
- #query-monitor .qm.qm-debug-bar pre {
977
- padding: 10px !important;
978
  border: 1px solid #bbc8d4 !important;
979
  margin: 4px 0 !important;
 
980
  }
981
-
982
- #query-monitor .qm.qm-debug-bar textarea {
983
  resize: vertical !important;
984
  }
985
-
986
- #query-monitor .qm.qm-debug-bar .left {
987
  float: left !important;
988
  }
989
-
990
- #query-monitor .qm.qm-debug-bar .right {
991
  float: right !important;
992
  }
993
-
994
- #query-monitor .qm.qm-debug-bar h2 {
995
  font-size: 14px !important;
996
  margin: 4px 6px 15px !important;
997
  }
998
-
999
- #query-monitor .qm.qm-debug-bar h3 {
1000
  float: left !important;
1001
  /* why */
 
 
1002
  min-width: 150px !important;
1003
  padding: 5px 10px 15px !important;
1004
- clear: none !important;
1005
  text-align: center !important;
1006
- font-size: 14px !important;
1007
- margin: 3px 8px 15px 0 !important;
1008
  }
1009
-
1010
- #query-monitor .qm.qm-debug-bar h3 small {
1011
  font-size: 14px !important;
1012
  }
1013
-
1014
- #query-monitor .qm.qm-debug-bar h3 span {
1015
- white-space: nowrap !important;
1016
  display: block !important;
1017
  margin-bottom: 8px !important;
 
1018
  }
1019
-
1020
- #query-monitor .qm.qm-debug-bar h4 {
1021
- margin: 15px 6px 5px !important;
1022
  font-size: 13px !important;
 
1023
  }
1024
-
1025
- #query-monitor .qm.qm-debug-bar .qm-debug-bar-output {
1026
  position: relative !important;
1027
  }
1028
-
1029
- #query-monitor .qm.qm-debug-bar .qm-debug-bar-output table {
1030
- margin-top: 4px !important;
1031
  margin-bottom: 4px !important;
 
1032
  }
1033
-
1034
- #query-monitor #debug-menu-target-Debug_Bar_Console {
1035
  min-height: 400px !important;
1036
  }
1037
-
1038
- #query-monitor #debug-menu-target-Debug_Bar_Cache_Lookup,
1039
- #query-monitor #debug-menu-target-Debug_Bar_Rewrite_Rules,
1040
- #query-monitor #debug-menu-target-Debug_Bar_Widgets {
1041
  margin: 4px 6px !important;
1042
  }
1043
-
1044
- #query-monitor #debug-menu-target-Debug_Bar_Rewrite_Rules_Panel .filterui,
1045
- #query-monitor #debug-menu-target-Debug_Bar_Rewrite_Rules_Panel .dbrr {
1046
  margin: 0 !important;
1047
  }
1048
-
1049
- /* Broken output handling */
1050
- #query-monitor.qm-broken #qm-title {
1051
  cursor: default !important;
1052
  }
1053
-
1054
- #query-monitor #qm-broken,
1055
- #query-monitor.qm-broken .qm-title-button {
1056
  display: none !important;
1057
  }
1058
-
1059
- #query-monitor.qm-broken #qm-broken,
1060
- #query-monitor.qm-broken .qm {
1061
  display: block !important;
1062
  }
1063
-
1064
- #query-monitor.qm-broken .qm {
1065
  margin-bottom: 50px !important;
1066
  }
1067
-
1068
- #query-monitor.qm-broken #qm-broken h2 {
1069
  padding: 20px !important;
1070
  }
10
  * The colours below are loosely based on the WordPress branding colours.
11
  * https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
12
  */
 
13
  #wpadminbar .quicklinks .menupop ul li.qm-true > a {
14
  color: #8c8 !important;
15
  }
83
  }
84
 
85
  #wpadminbar #wp-admin-bar-query-monitor .ab-icon {
 
 
 
 
86
  color: #aaa !important;
87
  display: none !important;
88
+ font: 18px/44px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
89
+ padding: 0 10px !important;
90
+ width: auto !important;
91
  }
92
 
93
  @media screen and (max-width: 782px) {
 
94
  #wpadminbar #wp-admin-bar-query-monitor .ab-icon {
95
  display: block !important;
96
  }
97
 
 
98
  #wpadminbar #wp-admin-bar-query-monitor .ab-label {
99
  display: none !important;
100
  }
101
  }
102
+ #query-monitor-main,
103
+ #query-monitor-main dl,
104
+ #query-monitor-main dt,
105
+ #query-monitor-main dd,
106
+ #query-monitor-main button,
107
+ #query-monitor-main label,
108
+ #query-monitor-main select,
109
+ #query-monitor-main table,
110
+ #query-monitor-main td,
111
+ #query-monitor-main th,
112
+ #query-monitor-main ul,
113
+ #query-monitor-main ol,
114
+ #query-monitor-main li,
115
+ #query-monitor-main code,
116
+ #query-monitor-main a,
117
+ #query-monitor-main h1,
118
+ #query-monitor-main h2,
119
+ #query-monitor-main h3,
120
+ #query-monitor-main h4,
121
+ #query-monitor-main h5,
122
+ #query-monitor-main h6,
123
+ #query-monitor-main section,
124
+ #query-monitor-main nav,
125
+ #query-monitor-main p {
 
 
126
  background: transparent !important;
127
+ border: none !important;
128
+ border-radius: 0 !important;
129
+ box-shadow: none !important;
130
  box-sizing: border-box !important;
131
+ clear: both !important;
132
+ color: #bbc8d4 !important;
133
+ float: none !important;
134
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
135
+ font-size: 12px !important;
136
+ -webkit-font-smoothing: auto !important;
137
  font-style: normal !important;
138
  font-weight: normal !important;
139
+ letter-spacing: normal !important;
140
  line-height: 18px !important;
 
 
 
141
  margin: 0 !important;
142
+ outline: none !important;
143
+ padding: 0 !important;
144
+ text-align: left !important;
145
+ text-decoration: none !important;
146
+ text-indent: 0 !important;
147
  text-shadow: none !important;
148
  text-transform: none !important;
 
 
 
 
149
  transition: none !important;
150
+ vertical-align: baseline !important;
151
  word-break: normal !important;
152
+ word-wrap: normal !important;
 
 
 
 
153
  }
154
+ #query-monitor-main::before, #query-monitor-main::after,
155
+ #query-monitor-main dl::before,
156
+ #query-monitor-main dl::after,
157
+ #query-monitor-main dt::before,
158
+ #query-monitor-main dt::after,
159
+ #query-monitor-main dd::before,
160
+ #query-monitor-main dd::after,
161
+ #query-monitor-main button::before,
162
+ #query-monitor-main button::after,
163
+ #query-monitor-main label::before,
164
+ #query-monitor-main label::after,
165
+ #query-monitor-main select::before,
166
+ #query-monitor-main select::after,
167
+ #query-monitor-main table::before,
168
+ #query-monitor-main table::after,
169
+ #query-monitor-main td::before,
170
+ #query-monitor-main td::after,
171
+ #query-monitor-main th::before,
172
+ #query-monitor-main th::after,
173
+ #query-monitor-main ul::before,
174
+ #query-monitor-main ul::after,
175
+ #query-monitor-main ol::before,
176
+ #query-monitor-main ol::after,
177
+ #query-monitor-main li::before,
178
+ #query-monitor-main li::after,
179
+ #query-monitor-main code::before,
180
+ #query-monitor-main code::after,
181
+ #query-monitor-main a::before,
182
+ #query-monitor-main a::after,
183
+ #query-monitor-main h1::before,
184
+ #query-monitor-main h1::after,
185
+ #query-monitor-main h2::before,
186
+ #query-monitor-main h2::after,
187
+ #query-monitor-main h3::before,
188
+ #query-monitor-main h3::after,
189
+ #query-monitor-main h4::before,
190
+ #query-monitor-main h4::after,
191
+ #query-monitor-main h5::before,
192
+ #query-monitor-main h5::after,
193
+ #query-monitor-main h6::before,
194
+ #query-monitor-main h6::after,
195
+ #query-monitor-main section::before,
196
+ #query-monitor-main section::after,
197
+ #query-monitor-main nav::before,
198
+ #query-monitor-main nav::after,
199
+ #query-monitor-main p::before,
200
+ #query-monitor-main p::after {
201
  display: none !important;
202
  }
203
+ #query-monitor-main {
 
204
  background: #23282d !important;
 
205
  border-top: 1px solid #bbc8d4 !important;
 
 
 
 
206
  bottom: 0 !important;
207
+ direction: ltr !important;
208
+ display: none;
209
  left: 0 !important;
210
+ margin: 0 !important;
211
+ position: fixed;
212
  right: 0 !important;
213
+ text-align: left !important;
214
+ z-index: 99998 !important;
215
  }
216
+ #query-monitor-main ::selection {
217
  background-color: #B9D6FB !important;
218
  color: #bbc8d4 !important;
219
  }
220
+ #query-monitor-main strong,
221
+ #query-monitor-main b {
222
  font-weight: bold !important;
223
  }
224
+ #query-monitor-main em,
225
+ #query-monitor-main i {
226
  font-style: italic !important;
227
  }
228
+ #query-monitor-main.qm-show, #query-monitor-main.qm-peek {
 
 
 
229
  display: flex;
230
  flex-direction: column !important;
231
+ height: 27px;
232
  }
233
+ #query-monitor-main.qm-show {
 
234
  height: 40%;
235
+ width: 40%;
236
  }
237
+ #query-monitor-main:not(.qm-show-right) {
238
+ width: 100% !important;
239
+ }
240
+ #query-monitor-main.qm-show-right {
241
+ height: calc( 100vh - 32px ) !important;
242
+ top: 32px !important;
243
+ left: unset !important;
244
+ border-top: 0 !important;
245
+ border-left: 1px solid #bbc8d4 !important;
246
+ }
247
+ #query-monitor-main.qm-show-right #qm-panel-menu,
248
+ #query-monitor-main.qm-show-right #qm-title h1.qm-title-heading {
249
+ display: none;
250
+ }
251
+ #query-monitor-main.qm-show-right #qm-title div.qm-title-heading {
252
+ display: block;
253
+ }
254
+ #query-monitor-main.qm-show-right #qm-title {
255
+ cursor: default !important;
256
+ }
257
+ #query-monitor-main.qm-show-right #qm-side-resizer {
258
+ background: transparent !important;
259
+ cursor: ew-resize !important;
260
+ display: block !important;
261
+ height: 100% !important;
262
+ position: absolute !important;
263
+ left: -2px !important;
264
+ top: 0 !important;
265
+ width: 4px !important;
266
+ z-index: 2 !important;
267
+ }
268
+ #query-monitor-main #qm-wrapper {
269
  display: flex;
270
  flex-grow: 1 !important;
271
  /* Fix nested scrolling in Firefox. See https://bugzilla.mozilla.org/show_bug.cgi?id=1043520: */
272
  min-height: 0;
273
  }
274
+ #query-monitor-main #qm-title {
275
+ align-items: center !important;
276
  background: #32373c !important;
277
  border-bottom: 1px solid #bbc8d4 !important;
278
  cursor: ns-resize !important;
 
279
  display: flex !important;
 
 
280
  flex-shrink: 0 !important;
281
+ height: 27px !important;
282
+ padding: 0 0 0 5px !important;
283
  -moz-user-select: none !important;
284
  -ms-user-select: none !important;
285
  -webkit-user-select: none !important;
286
  user-select: none !important;
287
  }
288
+ #query-monitor-main #qm-title .qm-title-heading {
 
289
  border-right: 1px solid #bbb !important;
290
+ flex-grow: 1 !important;
291
  margin-right: 6px !important;
292
  }
293
+ #query-monitor-main #qm-title div.qm-title-heading {
294
  display: none;
295
  }
296
+ #query-monitor-main #qm-title .qm-title-button {
297
  flex-shrink: 0 !important;
298
  }
299
+ #query-monitor-main #qm-title .dashicons {
300
  transition: none !important;
301
  }
302
+ #query-monitor-main #qm-title .qm-button-container-settings .dashicons {
303
  font-size: 17px !important;
304
  margin: 3px 0 2px !important;
305
  }
306
+ #query-monitor-main #qm-title .qm-button-container-position .dashicons {
307
+ font-size: 15px !important;
308
+ margin: 4px 0 1px !important;
309
+ }
310
+ #query-monitor-main #qm-title .qm-button-container-close {
311
+ margin-right: 5px !important;
312
+ }
313
+ #query-monitor-main #qm-title .qm-button-container-close .dashicons {
314
  margin: 2px 0 3px !important;
315
  }
316
+ @media screen and (max-width: 960px) {
317
+ #query-monitor-main #qm-title .qm-button-container-position {
318
+ display: none !important;
319
+ }
320
+ }
321
+ #query-monitor-main #qm-title button {
322
  background: transparent !important;
323
+ color: #bbc8d4 !important;
324
  cursor: pointer !important;
 
325
  display: inline-block !important;
326
+ margin: 0 0 0 0px !important;
327
  min-width: auto !important;
328
+ padding: 0px 4px !important;
329
  }
330
+ #query-monitor-main #qm-title button:focus,
331
+ #query-monitor-main #qm-title button:hover {
 
332
  background: #bbc8d4 !important;
333
+ color: #32373c !important;
334
  }
335
+ #query-monitor-main #qm-title button:active {
336
  background: #ccc !important;
337
  }
338
+ #query-monitor-main #qm-title button.qm-button-active {
339
  color: #3879d9 !important;
340
  }
341
+ #query-monitor-main .qm {
342
  display: none !important;
343
  }
344
+ #query-monitor-main #qm-panel-menu {
 
 
345
  background: #23282d !important;
346
+ flex-shrink: 0 !important;
347
+ overflow-y: scroll !important;
348
  overscroll-behavior: contain !important;
349
  }
350
+ #query-monitor-main #qm-panel-menu ul {
351
+ display: block !important;
 
352
  list-style: none !important;
353
+ margin: 0 !important;
 
354
  padding: 0 !important;
355
+ }
356
+ #query-monitor-main #qm-panel-menu li {
357
+ display: list-item !important;
358
  margin: 0 !important;
359
+ padding: 0 !important;
360
  }
361
+ #query-monitor-main #qm-panel-menu li button {
362
+ background: #23282d !important;
363
+ border-bottom: 1px solid #32373c !important;
364
+ border-right: 1px solid #bbc8d4 !important;
365
+ color: #bbc8d4 !important;
366
+ cursor: pointer !important;
367
  display: block !important;
368
  padding: 8px 28px 8px 6px !important;
 
 
 
369
  position: relative !important;
370
+ text-decoration: none !important;
 
371
  width: 100% !important;
 
372
  }
373
+ #query-monitor-main #qm-panel-menu li button:focus,
374
+ #query-monitor-main #qm-panel-menu li button:hover {
375
  background: #def !important;
376
  color: #222 !important;
377
  }
378
+ #query-monitor-main #qm-panel-menu li button:focus {
379
  text-decoration: underline !important;
380
  }
381
+ #query-monitor-main #qm-panel-menu li.qm-current-menu button {
382
+ background: #def !important;
383
+ color: #222 !important;
384
+ }
385
+ #query-monitor-main #qm-panel-menu li button.qm-selected-menu {
386
  background: #0073aa !important;
387
  color: #fff !important;
388
  text-shadow: 0 -1px 1px #006291, 1px 0 1px #006291, 0 1px 1px #006291, -1px 0 1px #006291 !important;
389
  }
390
+ #query-monitor-main #qm-panel-menu li button.qm-selected-menu:focus {
391
  background: #0084c4 !important;
392
  color: #fff !important;
393
  }
394
+ #query-monitor-main #qm-panel-menu li button.qm-selected-menu:after {
 
395
  border: solid 8px transparent;
396
+ border-right-color: #23282d;
397
  content: " ";
398
+ display: inline-block !important;
399
  height: 0;
400
+ margin-top: -8px;
 
401
  pointer-events: none;
402
+ position: absolute;
403
+ right: -1px;
404
  top: 50%;
405
+ width: 0;
406
  }
407
+ #query-monitor-main #qm-panels {
408
  flex-grow: 1 !important;
409
  overflow-y: scroll !important;
410
  overscroll-behavior: contain !important;
411
  }
412
+ #query-monitor-main .qm.qm-panel-show {
413
  display: block !important;
414
  }
415
+ #query-monitor-main .qm:focus {
416
  outline: 0 !important;
417
  /* @TODO might not need this any more */
418
  }
419
+ #query-monitor-main .qm-non-tabular {
420
  padding: 10px 20px !important;
421
  }
422
+ #query-monitor-main .qm-boxed {
423
  display: flex !important;
424
  flex-wrap: wrap !important;
425
  }
426
+ #query-monitor-main .qm-boxed:not(#qm-broken) + .qm-boxed {
427
  border-top: 1px solid #bbc8d4 !important;
428
  padding-top: 10px !important;
429
  }
430
+ #query-monitor-main .qm-boxed-wrap {
431
  flex-wrap: wrap !important;
432
  }
433
+ #query-monitor-main .qm .qm-none {
434
  margin: 2em !important;
435
  }
436
+ #query-monitor-main .qm .qm-none p {
 
437
  font-style: italic !important;
438
+ text-align: center !important;
439
  }
440
+ #query-monitor-main .qm table {
441
+ border: none !important;
442
+ border-bottom: 1px solid #23282d !important;
443
  border-collapse: collapse !important;
444
  box-shadow: none !important;
445
+ color: #bbc8d4 !important;
 
446
  margin: 0 !important;
447
+ table-layout: auto !important;
448
+ width: 100% !important;
449
  }
450
+ #query-monitor-main .qm table + table {
 
451
  border-top: 1px solid #23282d !important;
452
+ margin-top: 5px !important;
453
  }
454
+ #query-monitor-main .qm tr {
 
 
 
 
455
  border: none !important;
456
  }
457
+ #query-monitor-main .qm tbody th,
458
+ #query-monitor-main .qm tbody td,
459
+ #query-monitor-main .qm tfoot th,
460
+ #query-monitor-main .qm tfoot td {
461
  border: 1px solid #23282d !important;
462
  padding: 5px 5px 4px 5px !important;
463
  }
464
+ #query-monitor-main .qm tbody th,
465
+ #query-monitor-main .qm tbody td {
 
466
  border-bottom: none !important;
467
+ border-top: none !important;
468
  }
469
+ #query-monitor-main .qm thead th {
470
+ background: #32373c !important;
471
  border: 1px solid #23282d !important;
472
  border-top: none !important;
473
+ box-shadow: 0px 1px 0px #23282d !important;
474
  padding: 5px !important;
475
  position: -webkit-sticky !important;
476
  position: sticky !important;
477
  top: 0 !important;
 
478
  z-index: 1 !important;
479
  }
480
+ #query-monitor-main .qm thead .qm-th {
481
  display: flex !important;
482
  }
483
+ #query-monitor-main .qm tfoot tr td,
484
+ #query-monitor-main .qm tfoot tr th {
485
+ background: #32373c !important;
486
  border: 1px solid #23282d !important;
487
  border-bottom: none !important;
488
+ bottom: 0 !important;
489
+ box-shadow: inset 0px 1px 0px #23282d !important;
490
  position: -webkit-sticky !important;
491
  position: sticky !important;
 
492
  }
493
+ #query-monitor-main .qm th:first-child,
494
+ #query-monitor-main .qm td:first-child {
495
  border-left: none !important;
496
  }
497
+ #query-monitor-main .qm th:last-child,
498
+ #query-monitor-main .qm td:last-child {
499
  border-right: none !important;
500
  }
501
+ #query-monitor-main .qm tfoot td.qm-num,
502
+ #query-monitor-main .qm tfoot th.qm-num,
503
+ #query-monitor-main .qm thead td.qm-num,
504
+ #query-monitor-main .qm thead th.qm-num {
505
  width: 5.5em !important;
506
  }
507
+ #query-monitor-main .qm th.qm-num,
508
+ #query-monitor-main .qm td.qm-num {
509
  text-align: right !important;
510
  }
511
+ #query-monitor-main .qm td.qm-row-sql {
512
  min-width: 25em !important;
513
  }
514
+ #query-monitor-main .qm td.qm-row-block-html {
515
  max-width: 40em !important;
516
  }
517
+ #query-monitor-main .qm tr.qm-warn td.qm-col-status,
518
+ #query-monitor-main .qm td.qm-url,
519
+ #query-monitor-main .qm th.qm-col-message,
520
+ #query-monitor-main .qm td.qm-row-component {
521
  min-width: 15em !important;
522
  }
523
+ #query-monitor-main .qm td .qm-toggler {
 
524
  padding: 0 22px 0 0 !important;
525
  position: relative !important;
526
  }
527
+ #query-monitor-main .qm td.qm-has-toggle:not(.qm-toggled-on) .qm-supplemental {
528
  display: none;
529
  }
530
+ #query-monitor-main .qm .qm-inner-toggle {
531
  padding: 4px 6px !important;
532
  }
533
+ #query-monitor-main .qm-has-inner .qm-toggled > table {
534
+ border-bottom: none !important;
535
  border-top: 1px solid #23282d !important;
536
  }
537
+ #query-monitor-main .qm td.qm-has-inner .qm-toggler,
538
+ #query-monitor-main .qm td.qm-has-inner {
 
 
 
 
 
 
 
 
539
  padding: 0 !important;
540
  }
541
+ #query-monitor-main .qm caption h2 {
 
542
  font-size: 14px !important;
543
+ margin: 20px !important;
544
  }
545
+ #query-monitor-main .qm-concerns table {
546
+ border-top: 1px solid #23282d !important;
547
+ margin-bottom: 20px !important;
548
+ }
549
+ #query-monitor-main .qm-non-tabular h3 {
550
+ font-size: 14px !important;
551
+ margin: 0 0 15px 0 !important;
552
+ }
553
+ #query-monitor-main .qm-non-tabular h4 {
554
  font-size: 12px !important;
555
+ margin: 20px 0 10px !important;
556
  }
557
+ #query-monitor-main .qm-non-tabular p {
558
  margin-bottom: 10px !important;
559
  }
560
+ #query-monitor-main .qm-non-tabular dd {
561
  margin: 0 0 10px 10px !important;
562
  }
563
+ #query-monitor-main .qm-non-tabular h3 a {
564
  float: right !important;
565
  }
566
+ #query-monitor-main #qm-conditionals li {
567
  display: inline-block !important;
568
  margin: 0 20px 5px 0 !important;
569
  }
570
+ #query-monitor-main .qm-non-tabular section,
571
+ #query-monitor-main .qm-non-tabular .qm-section {
572
  margin: 0 0 30px 0 !important;
573
  }
574
+ #query-monitor-main .qm-non-tabular .qm-boxed section,
575
+ #query-monitor-main .qm-non-tabular .qm-boxed .qm-section {
 
576
  border-right: 1px solid #bbc8d4 !important;
577
+ margin: 0 20px 10px 0 !important;
578
  padding: 10px 20px 10px 0 !important;
579
  }
580
+ #query-monitor-main .qm-non-tabular .qm-boxed section:last-child,
581
+ #query-monitor-main .qm-non-tabular .qm-boxed .qm-section:last-child {
 
582
  border-right: none !important;
583
+ margin-right: 0 !important;
584
  padding-right: 20px !important;
585
  }
586
+ #query-monitor-main .qm-non-tabular table {
587
  border-bottom-color: #23282d !important;
588
  }
589
+ #query-monitor-main .qm ol,
590
+ #query-monitor-main .qm ul {
591
  list-style: none !important;
592
  }
593
+ #query-monitor-main .qm li {
594
  display: list-item !important;
595
  list-style: none !important;
596
  }
597
+ #query-monitor-main .qm li::before {
598
  content: '' !important;
599
  }
600
+ #query-monitor-main .qm .qm-has-toggle ol.qm-numbered li {
601
  list-style: none !important;
602
  }
603
+ #query-monitor-main .qm .qm-toggled-on ol.qm-numbered li,
604
+ #query-monitor-main .qm ol.qm-numbered li {
605
  list-style: decimal inside !important;
606
  }
607
+ #query-monitor-main .qm code,
608
+ #query-monitor-main .qm pre {
609
+ font-family: Menlo, Monaco, Consolas, monospace !important;
610
  font-size: 11px !important;
611
  line-height: 18px !important;
 
612
  }
613
+ #query-monitor-main .qm pre {
614
  background: transparent !important;
 
 
615
  height: auto !important;
616
+ margin: 0 !important;
617
  padding: 0 !important;
618
+ width: auto !important;
619
  }
620
+ #query-monitor-main .qm .qm-true code,
621
+ #query-monitor-main .qm p.qm-true,
622
+ #query-monitor-main .qm span.qm-true,
623
+ #query-monitor-main .qm td.qm-true {
624
  color: #4a4 !important;
625
  }
626
+ #query-monitor-main .qm .qm-false code,
627
+ #query-monitor-main .qm span.qm-false,
628
+ #query-monitor-main .qm td.qm-false {
629
  color: #999 !important;
630
  }
631
+ #query-monitor-main .qm .qm-num,
632
+ #query-monitor-main .qm code,
633
+ #query-monitor-main .qm .qm-nowrap {
634
  white-space: nowrap !important;
635
  }
636
+ #query-monitor-main .qm .qm-wrap code,
637
+ #query-monitor-main .qm .qm-wrap {
 
 
638
  white-space: normal !important;
 
 
 
639
  word-break: break-all !important;
640
+ word-wrap: break-word !important;
641
+ }
642
+ #query-monitor-main .qm .qm-pre-wrap code {
643
  white-space: pre-wrap !important;
644
+ word-break: break-all !important;
645
+ word-wrap: break-word !important;
646
  }
647
+ #query-monitor-main .qm .qm-sticky {
648
  position: sticky !important;
649
  top: 36px !important;
650
  }
651
+ #query-monitor-main .qm .qm-current,
652
+ #query-monitor-main .qm td.qm-has-toggle p,
653
+ #query-monitor-main .qm .qm-nonselectsql code,
654
+ #query-monitor-main .qm .qm-nonselectsql {
655
  color: #a6a !important;
656
  }
657
+ #query-monitor-main .qm .qm-info {
658
  color: #777 !important;
659
  }
660
+ #query-monitor-main .qm .qm-supplemental {
 
661
  margin-left: 0.75em !important;
662
+ margin-right: 0.75em !important;
663
  }
664
+ #query-monitor-main .qm td.qm-toggled-on .qm-inverse-toggled,
665
+ #query-monitor-main .qm td .qm-toggled {
666
  display: none;
667
  }
668
+ #query-monitor-main .qm button.qm-button,
669
+ #query-monitor-main .qm .qm-toggle {
 
 
670
  background: #0085ba !important;
 
671
  border: 1px solid #0073a1 !important;
672
  border-radius: 2px !important;
673
+ color: #fff !important;
674
+ cursor: pointer !important;
675
+ font-weight: normal !important;
676
  text-shadow: 0 -1px 1px #0073a1, 1px 0 1px #0073a1, 0 1px 1px #0073a1, -1px 0 1px #0073a1 !important;
677
  }
678
+ #query-monitor-main .qm .qm-toggle {
679
+ bottom: auto !important;
680
  font-family: Menlo, Monaco, Consolas, monospace !important;
681
+ height: 18px !important;
682
+ left: auto !important;
683
+ line-height: 16px !important;
684
+ padding: 0 !important;
685
  position: absolute !important;
 
686
  right: 0 !important;
 
 
687
  text-align: center !important;
688
+ top: 0 !important;
 
689
  width: 18px !important;
690
  }
691
+ #query-monitor-main .qm button {
692
  cursor: pointer !important;
693
  }
694
+ #query-monitor-main .qm button.qm-button {
695
  padding: 4px 10px !important;
696
  }
697
+ #query-monitor-main .qm .qm-has-inner .qm-toggle {
 
698
  right: 5px !important;
699
+ top: 5px !important;
700
  }
701
+ #query-monitor-main .qm button.qm-button:hover,
702
+ #query-monitor-main .qm button.qm-button:focus,
703
+ #query-monitor-main .qm .qm-toggle:focus,
704
+ #query-monitor-main .qm .qm-toggle:hover {
 
 
705
  background: #0094ce !important;
706
+ color: #fff !important;
707
+ text-decoration: none !important;
708
  }
709
+ #query-monitor-main .qm tbody tr.qm-odd td,
710
+ #query-monitor-main .qm tbody tr.qm-odd th {
711
  background: #32373c !important;
712
  }
713
+ #query-monitor-main .qm-non-tabular .qm-warn,
714
+ #query-monitor-main .qm thead tr .qm-warn,
715
+ #query-monitor-main .qm tbody tr .qm-warn {
 
 
 
 
 
 
 
716
  background-color: #800 !important;
717
  color: #fff0f0 !important;
718
  }
719
+ #query-monitor-main .qm tbody tr th.qm-warn,
720
+ #query-monitor-main .qm tbody tr td.qm-warn,
721
+ #query-monitor-main .qm tbody tr.qm-warn td,
722
+ #query-monitor-main .qm tbody tr.qm-warn th {
723
  background-color: #800 !important;
 
724
  border-color: #ffd6d6 !important;
725
+ box-shadow: inset 0 -1px #ffd6d6 !important;
726
  color: #fff0f0 !important;
727
  }
728
+ #query-monitor-main .qm-non-tabular .qm-warn code,
729
+ #query-monitor-main .qm tbody .qm-warn li,
730
+ #query-monitor-main .qm tbody .qm-warn .qm-info,
731
+ #query-monitor-main .qm tbody .qm-warn code {
 
732
  background-color: transparent !important;
733
+ color: #fff0f0 !important;
734
  }
735
+ #query-monitor-main .qm .qm-notice {
736
  background: #def !important;
737
  border: 1px solid #aad5ff !important;
 
738
  margin: 0 0 10px 0 !important;
739
+ padding: 10px 20px 0 !important;
740
  }
741
+ #query-monitor-main .qm .dashicons {
742
  font-size: 16px !important;
 
743
  height: 16px !important;
744
  margin-right: 0.3em !important;
745
  transition: none !important;
746
+ width: 16px !important;
747
  }
748
+ #query-monitor-main .qm .qm-dashicons-yes {
 
749
  background-color: #0a0 !important;
750
  border-radius: 50% !important;
751
+ color: #fff !important;
752
  }
753
+ #query-monitor-main .qm tbody tr.qm-hovered th,
754
+ #query-monitor-main .qm tbody tr.qm-hovered td,
755
+ #query-monitor-main .qm tbody tr:hover th,
756
+ #query-monitor-main .qm tbody tr:hover td {
757
  background: #3e444a !important;
758
  }
759
+ #query-monitor-main .qm thead th.qm-filtered select.qm-filter {
760
  background-color: #57572a !important;
761
  color: #bbc8d4 !important;
762
  }
763
+ #query-monitor-main .qm tbody tr td.qm-highlight,
764
+ #query-monitor-main .qm tbody tr.qm-highlight td {
765
  background-color: #57572a !important;
 
766
  border-color: #660 !important;
767
+ box-shadow: inset 0 -1px #660 !important;
768
  color: #bbc8d4 !important;
769
  }
770
+ #query-monitor-main .qm button.qm-filter-trigger,
771
+ #query-monitor-main .qm button.qm-filter-trigger code,
772
+ #query-monitor-main .qm tbody .qm-warn a code,
773
+ #query-monitor-main .qm a code,
774
+ #query-monitor-main .qm a {
775
  color: #30ceff !important;
 
776
  cursor: pointer !important;
777
+ text-decoration: none !important;
778
  }
779
+ #query-monitor-main .qm button.qm-filter-trigger:after, #query-monitor-main .qm button.qm-filter-trigger:focus, #query-monitor-main .qm button.qm-filter-trigger:hover,
780
+ #query-monitor-main .qm button.qm-filter-trigger code:after,
781
+ #query-monitor-main .qm button.qm-filter-trigger code:focus,
782
+ #query-monitor-main .qm button.qm-filter-trigger code:hover,
783
+ #query-monitor-main .qm tbody .qm-warn a code:after,
784
+ #query-monitor-main .qm tbody .qm-warn a code:focus,
785
+ #query-monitor-main .qm tbody .qm-warn a code:hover,
786
+ #query-monitor-main .qm a code:after,
787
+ #query-monitor-main .qm a code:focus,
788
+ #query-monitor-main .qm a code:hover,
789
+ #query-monitor-main .qm a:after,
790
+ #query-monitor-main .qm a:focus,
791
+ #query-monitor-main .qm a:hover {
792
  color: #4092d2 !important;
793
+ text-decoration: underline !important;
794
  }
795
+ #query-monitor-main .qm a.qm-external-link:after,
796
+ #query-monitor-main .qm a.qm-link:after,
797
+ #query-monitor-main .qm a.qm-edit-link:after,
798
+ #query-monitor-main .qm button.qm-filter-trigger:after {
 
 
 
 
799
  display: inline-block !important;
800
+ font-family: dashicons !important;
801
  font-size: 13px !important;
802
+ left: 2px !important;
803
  line-height: 15px !important;
804
  position: relative !important;
805
+ text-decoration: none !important;
806
  top: 2px !important;
807
+ visibility: hidden !important;
808
  }
809
+ #query-monitor-main .qm a.qm-external-link:after,
810
+ #query-monitor-main .qm a.qm-link:hover:after,
811
+ #query-monitor-main .qm a.qm-link:focus:after,
812
+ #query-monitor-main .qm a.qm-edit-link:hover:after,
813
+ #query-monitor-main .qm a.qm-edit-link:focus:after,
814
+ #query-monitor-main .qm button.qm-filter-trigger:hover:after,
815
+ #query-monitor-main .qm button.qm-filter-trigger:focus:after {
 
 
 
 
816
  visibility: visible !important;
817
  }
818
+ #query-monitor-main .qm button.qm-filter-trigger:after {
 
819
  content: '\f536' !important;
820
  }
821
+ #query-monitor-main .qm a.qm-edit-link:after {
 
822
  content: '\f464' !important;
823
  }
824
+ #query-monitor-main .qm a.qm-external-link:after,
825
+ #query-monitor-main .qm a.qm-link:after {
 
826
  content: '\f504' !important;
827
  }
828
+ #query-monitor-main #qm-ajax-errors {
 
829
  display: none;
830
  }
831
+ #query-monitor-main button,
832
+ #query-monitor-main select {
833
+ background: none !important;
834
+ cursor: pointer !important;
 
835
  height: auto !important;
836
+ margin: 0 !important;
837
  width: auto !important;
 
838
  }
839
+ #query-monitor-main .qm label {
 
 
840
  color: #bbc8d4 !important;
841
+ cursor: pointer !important;
842
  font-size: 12px !important;
843
  font-style: normal !important;
844
+ font-weight: normal !important;
845
  margin: 0 !important;
846
  }
847
+ #query-monitor-main .qm thead label {
 
848
  flex-grow: 1 !important;
849
  }
850
+ #query-monitor-main .qm .qm-filter-container {
 
851
  display: flex !important;
852
  }
853
+ #query-monitor-main .qm .qm-filter-container label {
 
854
  cursor: default !important;
855
+ white-space: nowrap !important;
856
  }
857
+ #query-monitor-main .qm .qm-filter-container div {
 
858
  /* Some themes use Select2 etc on all selects. This hides that. */
859
  display: none !important;
860
  }
861
+ #query-monitor-main .qm select.qm-filter {
 
 
 
 
 
 
 
 
 
 
 
 
862
  -webkit-appearance: menulist !important;
863
  -moz-appearance: menulist !important;
864
  appearance: menulist !important;
865
+ background: #32373c !important;
866
+ border: none !important;
867
+ color: #bbc8d4 !important;
868
+ cursor: pointer !important;
869
+ display: block !important;
870
+ float: none !important;
871
+ height: auto !important;
872
  letter-spacing: normal !important;
873
+ margin: 0 0 0 5px !important;
874
  max-width: 10em !important;
875
+ outline: 1px solid #bbc8d4 !important;
876
+ padding: 0 !important;
877
+ width: auto !important;
878
  }
879
+ #query-monitor-main .qm select.qm-filter:hover {
 
880
  background: #32373c !important;
881
  }
882
+ #query-monitor-main .qm-hide,
883
+ #query-monitor-main .qm-hide-scripts-dependencies,
884
+ #query-monitor-main .qm-hide-styles-dependencies,
885
+ #query-monitor-main .qm-hide-scripts-dependents,
886
+ #query-monitor-main .qm-hide-styles-dependents,
887
+ #query-monitor-main .qm-hide-scripts-host,
888
+ #query-monitor-main .qm-hide-styles-host,
889
+ #query-monitor-main .qm-hide-user,
890
+ #query-monitor-main .qm-hide-result,
891
+ #query-monitor-main .qm-hide-name,
892
+ #query-monitor-main .qm-hide-type,
893
+ #query-monitor-main .qm-hide-caller,
894
+ #query-monitor-main .qm-hide-component {
 
895
  display: none !important;
896
  }
897
+ #query-monitor-main .qm thead th.qm-sortable-column {
 
 
898
  cursor: pointer !important;
899
  }
900
+ #query-monitor-main .qm thead th.qm-sortable-column:hover {
 
901
  background: #32373c !important;
902
  }
903
+ #query-monitor-main .qm .qm-sort-heading {
 
904
  flex-grow: 1 !important;
905
  }
906
+ #query-monitor-main .qm .qm-sort-controls {
 
 
907
  flex-shrink: 0 !important;
908
+ text-align: right !important;
909
  }
910
+ #query-monitor-main .qm .qm-sortable-column .qm-sort-arrow {
911
+ color: #ccc !important;
912
+ display: block !important;
913
  font-family: dashicons !important;
914
  font-size: 23px !important;
915
+ height: 10px !important;
916
  margin: 0 !important;
917
  width: 16px !important;
 
 
918
  }
919
+ #query-monitor-main .qm .qm-sorted-desc .qm-sort-arrow,
920
+ #query-monitor-main .qm .qm-sorted-asc .qm-sort-arrow {
 
921
  color: #bbc8d4 !important;
922
  }
923
+ #query-monitor-main .qm thead th.qm-sortable-column:hover .qm-sort-arrow {
 
924
  color: #0073aa !important;
925
  }
926
+ #query-monitor-main .qm .qm-sortable-column .qm-sort-arrow::before {
 
927
  content: "\f140" !important;
 
 
928
  position: absolute !important;
929
+ right: 0 !important;
930
+ top: 4px !important;
931
  }
932
+ #query-monitor-main .qm .qm-sortable-column.qm-sorted-asc .qm-sort-arrow::before {
 
933
  content: "\f142" !important;
934
  }
935
+ #query-monitor-main .qm button:focus,
936
+ #query-monitor-main .qm a:focus,
937
+ #query-monitor-main .qm select:focus {
 
938
  box-shadow: 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, 0.8) !important;
939
  }
940
+ #query-monitor-main .qm-screen-reader-text,
941
+ #query-monitor-main .screen-reader-text {
942
+ border: 0 !important;
943
+ clip: rect(0 0 0 0) !important;
944
+ height: 1px !important;
945
  margin: -1px !important;
946
+ overflow: hidden !important;
947
  padding: 0 !important;
948
+ position: absolute !important;
949
  width: 1px !important;
 
 
 
950
  }
 
951
  @media screen and (max-width: 782px) {
952
+ #query-monitor-main #qm-panel-menu,
953
+ #query-monitor-main #qm-title h1.qm-title-heading {
954
  display: none;
955
  }
956
+ #query-monitor-main #qm-title div.qm-title-heading {
 
957
  display: block;
958
  }
959
  }
960
+ #query-monitor-main [data-qm-state="off"] [data-qm-state-visibility="on"],
961
+ #query-monitor-main [data-qm-state="on"] [data-qm-state-visibility="off"] {
 
962
  display: none;
963
  }
964
+ #query-monitor-main.qm-no-js .qm-sort-controls, #query-monitor-main.qm-no-js .qm-toggle, #query-monitor-main.qm-no-js select.qm-filter {
 
 
 
 
965
  display: none !important;
966
  }
967
+ #query-monitor-main .qm.qm-debug-bar textarea,
968
+ #query-monitor-main .qm.qm-debug-bar pre {
 
 
 
969
  border: 1px solid #bbc8d4 !important;
970
  margin: 4px 0 !important;
971
+ padding: 10px !important;
972
  }
973
+ #query-monitor-main .qm.qm-debug-bar textarea {
 
974
  resize: vertical !important;
975
  }
976
+ #query-monitor-main .qm.qm-debug-bar .left {
 
977
  float: left !important;
978
  }
979
+ #query-monitor-main .qm.qm-debug-bar .right {
 
980
  float: right !important;
981
  }
982
+ #query-monitor-main .qm.qm-debug-bar h2 {
 
983
  font-size: 14px !important;
984
  margin: 4px 6px 15px !important;
985
  }
986
+ #query-monitor-main .qm.qm-debug-bar h3 {
987
+ clear: none !important;
988
  float: left !important;
989
  /* why */
990
+ font-size: 14px !important;
991
+ margin: 3px 8px 15px 0 !important;
992
  min-width: 150px !important;
993
  padding: 5px 10px 15px !important;
 
994
  text-align: center !important;
 
 
995
  }
996
+ #query-monitor-main .qm.qm-debug-bar h3 small {
 
997
  font-size: 14px !important;
998
  }
999
+ #query-monitor-main .qm.qm-debug-bar h3 span {
 
 
1000
  display: block !important;
1001
  margin-bottom: 8px !important;
1002
+ white-space: nowrap !important;
1003
  }
1004
+ #query-monitor-main .qm.qm-debug-bar h4 {
 
 
1005
  font-size: 13px !important;
1006
+ margin: 15px 6px 5px !important;
1007
  }
1008
+ #query-monitor-main .qm.qm-debug-bar .qm-debug-bar-output {
 
1009
  position: relative !important;
1010
  }
1011
+ #query-monitor-main .qm.qm-debug-bar .qm-debug-bar-output table {
 
 
1012
  margin-bottom: 4px !important;
1013
+ margin-top: 4px !important;
1014
  }
1015
+ #query-monitor-main #debug-menu-target-Debug_Bar_Console {
 
1016
  min-height: 400px !important;
1017
  }
1018
+ #query-monitor-main #debug-menu-target-Debug_Bar_Cache_Lookup,
1019
+ #query-monitor-main #debug-menu-target-Debug_Bar_Rewrite_Rules,
1020
+ #query-monitor-main #debug-menu-target-Debug_Bar_Widgets {
 
1021
  margin: 4px 6px !important;
1022
  }
1023
+ #query-monitor-main #debug-menu-target-Debug_Bar_Rewrite_Rules_Panel .filterui,
1024
+ #query-monitor-main #debug-menu-target-Debug_Bar_Rewrite_Rules_Panel .dbrr {
 
1025
  margin: 0 !important;
1026
  }
1027
+ #query-monitor-main.qm-broken #qm-title {
 
 
1028
  cursor: default !important;
1029
  }
1030
+ #query-monitor-main #qm-broken, #query-monitor-main.qm-broken .qm-title-button {
 
 
1031
  display: none !important;
1032
  }
1033
+ #query-monitor-main.qm-broken #qm-broken, #query-monitor-main.qm-broken .qm {
 
 
1034
  display: block !important;
1035
  }
1036
+ #query-monitor-main.qm-broken .qm {
 
1037
  margin-bottom: 50px !important;
1038
  }
1039
+ #query-monitor-main.qm-broken #qm-broken h2 {
 
1040
  padding: 20px !important;
1041
  }
assets/query-monitor.css CHANGED
@@ -3,7 +3,6 @@
3
  *
4
  * @package query-monitor
5
  */
6
- /* === Admin Toolbar === */
7
  #wpadminbar .quicklinks .menupop ul li.qm-true > a {
8
  color: #8c8 !important;
9
  }
@@ -77,987 +76,959 @@ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover
77
  }
78
 
79
  #wpadminbar #wp-admin-bar-query-monitor .ab-icon {
80
- font: 18px/44px 'Open Sans', sans-serif !important;
81
- /* @todo remove open sans */
82
- width: auto !important;
83
- padding: 0 10px !important;
84
  color: #aaa !important;
85
  display: none !important;
 
 
 
86
  }
87
 
88
  @media screen and (max-width: 782px) {
89
- /* force menu icon to show up */
90
  #wpadminbar #wp-admin-bar-query-monitor .ab-icon {
91
  display: block !important;
92
  }
93
 
94
- /* hide menu text */
95
  #wpadminbar #wp-admin-bar-query-monitor .ab-label {
96
  display: none !important;
97
  }
98
  }
99
- /* === Main QM Panel === */
100
- #query-monitor,
101
- #query-monitor dl,
102
- #query-monitor dt,
103
- #query-monitor dd,
104
- #query-monitor button,
105
- #query-monitor label,
106
- #query-monitor select,
107
- #query-monitor table,
108
- #query-monitor td,
109
- #query-monitor th,
110
- #query-monitor ul,
111
- #query-monitor ol,
112
- #query-monitor li,
113
- #query-monitor code,
114
- #query-monitor a,
115
- #query-monitor h1,
116
- #query-monitor h2,
117
- #query-monitor h3,
118
- #query-monitor h4,
119
- #query-monitor h5,
120
- #query-monitor h6,
121
- #query-monitor section,
122
- #query-monitor nav,
123
- #query-monitor p {
124
- /* reset */
125
  background: transparent !important;
126
- color: #222 !important;
 
 
127
  box-sizing: border-box !important;
128
- text-align: left !important;
 
 
 
 
 
129
  font-style: normal !important;
130
  font-weight: normal !important;
131
- font-size: 12px !important;
132
  line-height: 18px !important;
133
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
134
- border: none !important;
135
- padding: 0 !important;
136
  margin: 0 !important;
137
- vertical-align: baseline !important;
 
 
 
 
138
  text-shadow: none !important;
139
  text-transform: none !important;
140
- text-decoration: none !important;
141
- -webkit-font-smoothing: auto !important;
142
- letter-spacing: normal !important;
143
- border-radius: 0 !important;
144
  transition: none !important;
145
- word-wrap: normal !important;
146
  word-break: normal !important;
147
- outline: none !important;
148
- box-shadow: none !important;
149
- text-indent: 0 !important;
150
- float: none !important;
151
- clear: both !important;
152
  }
153
- #query-monitor::before, #query-monitor::after,
154
- #query-monitor dl::before,
155
- #query-monitor dl::after,
156
- #query-monitor dt::before,
157
- #query-monitor dt::after,
158
- #query-monitor dd::before,
159
- #query-monitor dd::after,
160
- #query-monitor button::before,
161
- #query-monitor button::after,
162
- #query-monitor label::before,
163
- #query-monitor label::after,
164
- #query-monitor select::before,
165
- #query-monitor select::after,
166
- #query-monitor table::before,
167
- #query-monitor table::after,
168
- #query-monitor td::before,
169
- #query-monitor td::after,
170
- #query-monitor th::before,
171
- #query-monitor th::after,
172
- #query-monitor ul::before,
173
- #query-monitor ul::after,
174
- #query-monitor ol::before,
175
- #query-monitor ol::after,
176
- #query-monitor li::before,
177
- #query-monitor li::after,
178
- #query-monitor code::before,
179
- #query-monitor code::after,
180
- #query-monitor a::before,
181
- #query-monitor a::after,
182
- #query-monitor h1::before,
183
- #query-monitor h1::after,
184
- #query-monitor h2::before,
185
- #query-monitor h2::after,
186
- #query-monitor h3::before,
187
- #query-monitor h3::after,
188
- #query-monitor h4::before,
189
- #query-monitor h4::after,
190
- #query-monitor h5::before,
191
- #query-monitor h5::after,
192
- #query-monitor h6::before,
193
- #query-monitor h6::after,
194
- #query-monitor section::before,
195
- #query-monitor section::after,
196
- #query-monitor nav::before,
197
- #query-monitor nav::after,
198
- #query-monitor p::before,
199
- #query-monitor p::after {
200
  display: none !important;
201
  }
202
-
203
- #query-monitor {
204
  background: #fff !important;
205
- margin: 0 !important;
206
  border-top: 1px solid #aaa !important;
207
- text-align: left !important;
208
- display: none;
209
- position: fixed;
210
- z-index: 99998 !important;
211
  bottom: 0 !important;
 
 
212
  left: 0 !important;
 
 
213
  right: 0 !important;
214
- width: 100% !important;
215
- direction: ltr !important;
216
  }
217
- #query-monitor ::selection {
218
  background-color: #B9D6FB !important;
219
  color: #222 !important;
220
  }
221
- #query-monitor strong,
222
- #query-monitor b {
223
  font-weight: bold !important;
224
  }
225
- #query-monitor em,
226
- #query-monitor i {
227
  font-style: italic !important;
228
  }
229
-
230
- #query-monitor.qm-show,
231
- #query-monitor.qm-peek {
232
- height: 27px;
233
  display: flex;
234
  flex-direction: column !important;
 
235
  }
236
-
237
- #query-monitor.qm-show {
238
  height: 40%;
 
239
  }
240
-
241
- #query-monitor #qm-wrapper {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  display: flex;
243
  flex-grow: 1 !important;
244
  /* Fix nested scrolling in Firefox. See https://bugzilla.mozilla.org/show_bug.cgi?id=1043520: */
245
  min-height: 0;
246
  }
247
- #query-monitor #qm-title {
 
248
  background: #f3f3f3 !important;
249
  border-bottom: 1px solid #aaa !important;
250
  cursor: ns-resize !important;
251
- align-items: center !important;
252
  display: flex !important;
253
- padding: 0 0 0 5px !important;
254
- height: 27px !important;
255
  flex-shrink: 0 !important;
 
 
256
  -moz-user-select: none !important;
257
  -ms-user-select: none !important;
258
  -webkit-user-select: none !important;
259
  user-select: none !important;
260
  }
261
- #query-monitor #qm-title .qm-title-heading {
262
- flex-grow: 1 !important;
263
  border-right: 1px solid #bbb !important;
 
264
  margin-right: 6px !important;
265
  }
266
- #query-monitor #qm-title div.qm-title-heading {
267
  display: none;
268
  }
269
- #query-monitor #qm-title .qm-title-button {
270
  flex-shrink: 0 !important;
271
  }
272
- #query-monitor #qm-title .dashicons {
273
  transition: none !important;
274
  }
275
- #query-monitor #qm-title .qm-button-container-settings .dashicons {
276
  font-size: 17px !important;
277
  margin: 3px 0 2px !important;
278
  }
279
- #query-monitor #qm-title .qm-button-container-close .dashicons {
 
 
 
 
 
 
 
280
  margin: 2px 0 3px !important;
281
  }
282
- #query-monitor #qm-title button {
283
- color: #666 !important;
 
 
 
 
284
  background: transparent !important;
 
285
  cursor: pointer !important;
286
- margin: 0 0 0 0px !important;
287
  display: inline-block !important;
288
- padding: 0px 4px !important;
289
  min-width: auto !important;
 
290
  }
291
- #query-monitor #qm-title button:focus,
292
- #query-monitor #qm-title button:hover {
293
- color: #000 !important;
294
  background: #e6e6e6 !important;
 
295
  }
296
- #query-monitor #qm-title button:active {
297
  background: #ccc !important;
298
  }
299
- #query-monitor #qm-title button.qm-button-active {
300
  color: #3879d9 !important;
301
  }
302
- #query-monitor .qm {
303
  display: none !important;
304
  }
305
- #query-monitor #qm-panel-menu {
306
- overflow-y: scroll !important;
307
- flex-shrink: 0 !important;
308
  background: #ececec !important;
 
 
309
  overscroll-behavior: contain !important;
310
  }
311
- #query-monitor #qm-panel-menu ul {
312
- padding: 0 !important;
313
- margin: 0 !important;
314
  list-style: none !important;
315
- }
316
- #query-monitor #qm-panel-menu li {
317
  padding: 0 !important;
 
 
 
318
  margin: 0 !important;
 
319
  }
320
- #query-monitor #qm-panel-menu li button {
 
 
 
 
 
321
  display: block !important;
322
  padding: 8px 28px 8px 6px !important;
323
- color: #333 !important;
324
- text-decoration: none !important;
325
- border-bottom: 1px solid #ddd !important;
326
  position: relative !important;
327
- border-right: 1px solid #aaa !important;
328
- background: #f3f3f3 !important;
329
  width: 100% !important;
330
- cursor: pointer !important;
331
  }
332
- #query-monitor #qm-panel-menu li button:focus,
333
- #query-monitor #qm-panel-menu li button:hover {
334
  background: #def !important;
335
  color: #222 !important;
336
  }
337
- #query-monitor #qm-panel-menu li button:focus {
338
  text-decoration: underline !important;
339
  }
340
- #query-monitor #qm-panel-menu li button.qm-selected-menu {
 
 
 
 
341
  background: #0073aa !important;
342
  color: #fff !important;
343
  text-shadow: 0 -1px 1px #006291, 1px 0 1px #006291, 0 1px 1px #006291, -1px 0 1px #006291 !important;
344
  }
345
- #query-monitor #qm-panel-menu li button.qm-selected-menu:focus {
346
  background: #0084c4 !important;
347
  color: #fff !important;
348
  }
349
- #query-monitor #qm-panel-menu li button.qm-selected-menu:after {
350
- right: -1px;
351
  border: solid 8px transparent;
 
352
  content: " ";
 
353
  height: 0;
354
- width: 0;
355
- position: absolute;
356
  pointer-events: none;
357
- border-right-color: #fff;
 
358
  top: 50%;
359
- margin-top: -8px;
360
  }
361
- #query-monitor #qm-panels {
362
  flex-grow: 1 !important;
363
  overflow-y: scroll !important;
364
  overscroll-behavior: contain !important;
365
  }
366
- #query-monitor .qm.qm-panel-show {
367
  display: block !important;
368
  }
369
- #query-monitor .qm:focus {
370
  outline: 0 !important;
371
  /* @TODO might not need this any more */
372
  }
373
- #query-monitor .qm-non-tabular {
374
  padding: 10px 20px !important;
375
  }
376
- #query-monitor .qm-boxed {
377
  display: flex !important;
378
  flex-wrap: wrap !important;
379
  }
380
- #query-monitor .qm-boxed:not(#qm-broken) + .qm-boxed {
381
  border-top: 1px solid #ddd !important;
382
  padding-top: 10px !important;
383
  }
384
- #query-monitor .qm-boxed-wrap {
385
  flex-wrap: wrap !important;
386
  }
387
- #query-monitor .qm .qm-none {
388
  margin: 2em !important;
389
  }
390
- #query-monitor .qm .qm-none p {
391
- text-align: center !important;
392
  font-style: italic !important;
 
393
  }
394
- #query-monitor .qm table {
395
- color: #222 !important;
 
396
  border-collapse: collapse !important;
397
  box-shadow: none !important;
398
- width: 100% !important;
399
- table-layout: auto !important;
400
  margin: 0 !important;
401
- border: none !important;
402
- border-bottom: 1px solid #e0e0e0 !important;
403
  }
404
- #query-monitor .qm table + table {
405
- margin-top: 5px !important;
406
  border-top: 1px solid #e0e0e0 !important;
 
407
  }
408
- #query-monitor #qm-conditionals table,
409
- #query-monitor #qm-overview table {
410
- table-layout: fixed !important;
411
- }
412
- #query-monitor .qm tr {
413
  border: none !important;
414
  }
415
- #query-monitor .qm tbody th,
416
- #query-monitor .qm tbody td,
417
- #query-monitor .qm tfoot th,
418
- #query-monitor .qm tfoot td {
419
  border: 1px solid #e0e0e0 !important;
420
  padding: 5px 5px 4px 5px !important;
421
  }
422
- #query-monitor .qm tbody th,
423
- #query-monitor .qm tbody td {
424
- border-top: none !important;
425
  border-bottom: none !important;
 
426
  }
427
- #query-monitor .qm thead th {
428
- box-shadow: 0px 1px 0px #e0e0e0 !important;
429
  border: 1px solid #e0e0e0 !important;
430
  border-top: none !important;
 
431
  padding: 5px !important;
432
  position: -webkit-sticky !important;
433
  position: sticky !important;
434
  top: 0 !important;
435
- background: #fff !important;
436
  z-index: 1 !important;
437
  }
438
- #query-monitor .qm thead .qm-th {
439
  display: flex !important;
440
  }
441
- #query-monitor .qm tfoot tr td,
442
- #query-monitor .qm tfoot tr th {
443
- box-shadow: inset 0px 1px 0px #e0e0e0 !important;
444
  border: 1px solid #e0e0e0 !important;
445
  border-bottom: none !important;
446
- background: #f3f3f3 !important;
 
447
  position: -webkit-sticky !important;
448
  position: sticky !important;
449
- bottom: 0 !important;
450
  }
451
- #query-monitor .qm th:first-child,
452
- #query-monitor .qm td:first-child {
453
  border-left: none !important;
454
  }
455
- #query-monitor .qm th:last-child,
456
- #query-monitor .qm td:last-child {
457
  border-right: none !important;
458
  }
459
- #query-monitor .qm tfoot td.qm-num,
460
- #query-monitor .qm tfoot th.qm-num,
461
- #query-monitor .qm thead td.qm-num,
462
- #query-monitor .qm thead th.qm-num {
463
  width: 5.5em !important;
464
  }
465
- #query-monitor .qm th.qm-num,
466
- #query-monitor .qm td.qm-num {
467
  text-align: right !important;
468
  }
469
- #query-monitor .qm td.qm-row-sql {
470
  min-width: 25em !important;
471
  }
472
- #query-monitor .qm td.qm-row-block-html {
473
  max-width: 40em !important;
474
  }
475
- #query-monitor .qm tr.qm-warn td.qm-col-status,
476
- #query-monitor .qm td.qm-url,
477
- #query-monitor .qm th.qm-col-message,
478
- #query-monitor .qm td.qm-row-component {
479
  min-width: 15em !important;
480
  }
481
- #query-monitor .qm td.qm-has-toggle p,
482
- #query-monitor .qm td .qm-toggler {
483
  padding: 0 22px 0 0 !important;
484
  position: relative !important;
485
  }
486
- #query-monitor .qm td.qm-has-toggle:not(.qm-toggled-on) .qm-supplemental {
487
  display: none;
488
  }
489
- #query-monitor .qm .qm-inner-toggle {
490
  padding: 4px 6px !important;
491
  }
492
-
493
- .qm-has-inner .qm-toggled > table {
494
  border-top: 1px solid #e0e0e0 !important;
495
  }
496
-
497
- .qm-inner {
498
- border-collapse: collapse !important;
499
- margin: 0 !important;
500
- border-style: hidden !important;
501
- width: 100% !important;
502
- }
503
-
504
- #query-monitor .qm td.qm-has-inner .qm-toggler,
505
- #query-monitor .qm td.qm-has-inner {
506
  padding: 0 !important;
507
  }
508
- #query-monitor .qm-non-tabular h3 {
509
- margin: 0 0 15px 0 !important;
510
  font-size: 14px !important;
 
511
  }
512
- #query-monitor .qm-non-tabular h4 {
513
- margin: 20px 0 10px !important;
 
 
 
 
 
 
 
514
  font-size: 12px !important;
 
515
  }
516
- #query-monitor .qm-non-tabular p {
517
  margin-bottom: 10px !important;
518
  }
519
- #query-monitor .qm-non-tabular dd {
520
  margin: 0 0 10px 10px !important;
521
  }
522
- #query-monitor .qm-non-tabular h3 a {
523
  float: right !important;
524
  }
525
- #query-monitor .qm-non-tabular .qm-item {
526
  display: inline-block !important;
527
  margin: 0 20px 5px 0 !important;
528
  }
529
- #query-monitor .qm-non-tabular section,
530
- #query-monitor .qm-non-tabular .qm-section {
531
  margin: 0 0 30px 0 !important;
532
  }
533
- #query-monitor .qm-non-tabular .qm-boxed section,
534
- #query-monitor .qm-non-tabular .qm-boxed .qm-section {
535
- margin: 0 20px 10px 0 !important;
536
  border-right: 1px solid #ddd !important;
 
537
  padding: 10px 20px 10px 0 !important;
538
  }
539
- #query-monitor .qm-non-tabular .qm-boxed section:last-child,
540
- #query-monitor .qm-non-tabular .qm-boxed .qm-section:last-child {
541
- margin-right: 0 !important;
542
  border-right: none !important;
 
543
  padding-right: 20px !important;
544
  }
545
- #query-monitor .qm-non-tabular table {
546
  border-bottom-color: #e0e0e0 !important;
547
  }
548
- #query-monitor .qm ol,
549
- #query-monitor .qm ul {
550
  list-style: none !important;
551
  }
552
- #query-monitor .qm li {
553
  display: list-item !important;
554
  list-style: none !important;
555
  }
556
- #query-monitor .qm li::before {
557
  content: '' !important;
558
  }
559
- #query-monitor .qm .qm-has-toggle ol.qm-numbered li {
560
  list-style: none !important;
561
  }
562
- #query-monitor .qm .qm-toggled-on ol.qm-numbered li,
563
- #query-monitor .qm ol.qm-numbered li {
564
  list-style: decimal inside !important;
565
  }
566
- #query-monitor .qm code,
567
- #query-monitor .qm pre {
 
568
  font-size: 11px !important;
569
  line-height: 18px !important;
570
- font-family: Menlo, Monaco, Consolas, monospace !important;
571
  }
572
- #query-monitor .qm pre {
573
  background: transparent !important;
574
- margin: 0 !important;
575
- width: auto !important;
576
  height: auto !important;
 
577
  padding: 0 !important;
 
578
  }
579
- #query-monitor .qm .qm-true code,
580
- #query-monitor .qm p.qm-true,
581
- #query-monitor .qm span.qm-true,
582
- #query-monitor .qm td.qm-true {
583
  color: #4a4 !important;
584
  }
585
- #query-monitor .qm .qm-false code,
586
- #query-monitor .qm span.qm-false,
587
- #query-monitor .qm td.qm-false {
588
  color: #999 !important;
589
  }
590
- #query-monitor .qm .qm-num,
591
- #query-monitor .qm code,
592
- #query-monitor .qm .qm-nowrap {
593
  white-space: nowrap !important;
594
  }
595
- #query-monitor .qm .qm-wrap code,
596
- #query-monitor .qm .qm-wrap {
597
- word-wrap: break-word !important;
598
- word-break: break-all !important;
599
  white-space: normal !important;
600
- }
601
- #query-monitor .qm .qm-pre-wrap code {
602
- word-wrap: break-word !important;
603
  word-break: break-all !important;
 
 
 
604
  white-space: pre-wrap !important;
 
 
605
  }
606
- #query-monitor .qm .qm-sticky {
607
  position: sticky !important;
608
  top: 36px !important;
609
  }
610
- #query-monitor .qm .qm-current,
611
- #query-monitor .qm td.qm-has-toggle p,
612
- #query-monitor .qm .qm-nonselectsql code,
613
- #query-monitor .qm .qm-nonselectsql {
614
  color: #a0a !important;
615
  }
616
- #query-monitor .qm .qm-info {
617
  color: #777 !important;
618
  }
619
- #query-monitor .qm .qm-supplemental {
620
- margin-right: 0.75em !important;
621
  margin-left: 0.75em !important;
 
622
  }
623
- #query-monitor .qm td.qm-toggled-on .qm-inverse-toggled,
624
- #query-monitor .qm td .qm-toggled {
625
  display: none;
626
  }
627
- #query-monitor .qm button.qm-button,
628
- #query-monitor .qm .qm-toggle {
629
- color: #fff !important;
630
- font-weight: normal !important;
631
  background: #0085ba !important;
632
- cursor: pointer !important;
633
  border: 1px solid #0073a1 !important;
634
  border-radius: 2px !important;
 
 
 
635
  text-shadow: 0 -1px 1px #0073a1, 1px 0 1px #0073a1, 0 1px 1px #0073a1, -1px 0 1px #0073a1 !important;
636
  }
637
- #query-monitor .qm .qm-toggle {
638
- padding: 0 !important;
639
  font-family: Menlo, Monaco, Consolas, monospace !important;
 
 
 
 
640
  position: absolute !important;
641
- top: 0 !important;
642
  right: 0 !important;
643
- left: auto !important;
644
- bottom: auto !important;
645
  text-align: center !important;
646
- line-height: 16px !important;
647
- height: 18px !important;
648
  width: 18px !important;
649
  }
650
- #query-monitor .qm button {
651
  cursor: pointer !important;
652
  }
653
- #query-monitor .qm button.qm-button {
654
  padding: 4px 10px !important;
655
  }
656
- #query-monitor .qm .qm-has-inner .qm-toggle {
657
- top: 5px !important;
658
  right: 5px !important;
 
659
  }
660
- #query-monitor .qm button.qm-button:hover,
661
- #query-monitor .qm button.qm-button:focus,
662
- #query-monitor .qm .qm-toggle:focus,
663
- #query-monitor .qm .qm-toggle:hover {
664
- text-decoration: none !important;
665
- color: #fff !important;
666
  background: #0094ce !important;
 
 
667
  }
668
- #query-monitor .qm tbody tr.qm-odd td,
669
- #query-monitor .qm tbody tr.qm-odd th {
670
  background: #f7f7f7 !important;
671
  }
672
-
673
- .qm-debug-bar tbody tr:hover th,
674
- .qm-debug-bar tbody tr:hover td {
675
- background: #fff !important;
676
- /* transparent? */
677
- }
678
-
679
- #query-monitor .qm-non-tabular .qm-warn,
680
- #query-monitor .qm thead tr .qm-warn,
681
- #query-monitor .qm tbody tr .qm-warn {
682
  background-color: #fff0f0 !important;
683
  color: #a00 !important;
684
  }
685
- #query-monitor .qm tbody tr th.qm-warn,
686
- #query-monitor .qm tbody tr td.qm-warn,
687
- #query-monitor .qm tbody tr.qm-warn td,
688
- #query-monitor .qm tbody tr.qm-warn th {
689
  background-color: #fff0f0 !important;
690
- box-shadow: inset 0 -1px #ffd6d6 !important;
691
  border-color: #ffd6d6 !important;
 
692
  color: #a00 !important;
693
  }
694
- #query-monitor .qm-non-tabular .qm-warn code,
695
- #query-monitor .qm tbody .qm-warn li,
696
- #query-monitor .qm tbody .qm-warn .qm-info,
697
- #query-monitor .qm tbody .qm-warn code {
698
- color: #a00 !important;
699
  background-color: transparent !important;
 
700
  }
701
- #query-monitor .qm .qm-notice {
702
  background: #def !important;
703
  border: 1px solid #aad5ff !important;
704
- padding: 10px 20px 0 !important;
705
  margin: 0 0 10px 0 !important;
 
706
  }
707
- #query-monitor .qm .dashicons {
708
  font-size: 16px !important;
709
- width: 16px !important;
710
  height: 16px !important;
711
  margin-right: 0.3em !important;
712
  transition: none !important;
 
713
  }
714
- #query-monitor .qm .qm-dashicons-yes {
715
- color: #fff !important;
716
  background-color: #0a0 !important;
717
  border-radius: 50% !important;
 
718
  }
719
- #query-monitor .qm tbody tr.qm-hovered th,
720
- #query-monitor .qm tbody tr.qm-hovered td,
721
- #query-monitor .qm tbody tr:hover th,
722
- #query-monitor .qm tbody tr:hover td {
723
  background: #eef3fa !important;
724
  }
725
- #query-monitor .qm thead th.qm-filtered select.qm-filter {
726
  background-color: #ffd !important;
727
  color: #222 !important;
728
  }
729
- #query-monitor .qm tbody tr td.qm-highlight,
730
- #query-monitor .qm tbody tr.qm-highlight td {
731
  background-color: #ffd !important;
732
- box-shadow: inset 0 -1px #eec !important;
733
  border-color: #eec !important;
 
734
  color: #222 !important;
735
  }
736
-
737
- #query-monitor .qm tbody .qm-warn a code,
738
- #qm-title a,
739
- #query-monitor .qm a code,
740
- #query-monitor .qm a {
741
  color: #0073aa !important;
742
- text-decoration: none !important;
743
  cursor: pointer !important;
 
744
  }
745
- #query-monitor .qm tbody .qm-warn a code:after, #query-monitor .qm tbody .qm-warn a code:focus, #query-monitor .qm tbody .qm-warn a code:hover,
746
- #qm-title a:after,
747
- #qm-title a:focus,
748
- #qm-title a:hover,
749
- #query-monitor .qm a code:after,
750
- #query-monitor .qm a code:focus,
751
- #query-monitor .qm a code:hover,
752
- #query-monitor .qm a:after,
753
- #query-monitor .qm a:focus,
754
- #query-monitor .qm a:hover {
755
- text-decoration: underline !important;
 
 
756
  color: #0096dd !important;
 
757
  }
758
-
759
- #query-monitor .qm a.qm-external-link:after,
760
- #query-monitor .qm a.qm-link:after,
761
- #query-monitor .qm a.qm-edit-link:after,
762
- #query-monitor .qm a.qm-filter-trigger:after {
763
- font-family: dashicons !important;
764
- text-decoration: none !important;
765
- visibility: hidden !important;
766
  display: inline-block !important;
 
767
  font-size: 13px !important;
 
768
  line-height: 15px !important;
769
  position: relative !important;
 
770
  top: 2px !important;
771
- left: 2px !important;
772
  }
773
-
774
- #query-monitor .qm a.qm-external-link:after,
775
- #query-monitor.qm-touch .qm a.qm-link:after,
776
- #query-monitor .qm a.qm-link:hover:after,
777
- #query-monitor .qm a.qm-link:focus:after,
778
- #query-monitor.qm-touch .qm a.qm-edit-link:after,
779
- #query-monitor .qm a.qm-edit-link:hover:after,
780
- #query-monitor .qm a.qm-edit-link:focus:after,
781
- #query-monitor.qm-touch .qm a.qm-filter-trigger:after,
782
- #query-monitor .qm a.qm-filter-trigger:hover:after,
783
- #query-monitor .qm a.qm-filter-trigger:focus:after {
784
  visibility: visible !important;
785
  }
786
-
787
- #query-monitor .qm a.qm-filter-trigger:after {
788
  content: '\f536' !important;
789
  }
790
-
791
- #query-monitor .qm a.qm-edit-link:after {
792
  content: '\f464' !important;
793
  }
794
-
795
- #query-monitor .qm a.qm-external-link:after,
796
- #query-monitor .qm a.qm-link:after {
797
  content: '\f504' !important;
798
  }
799
-
800
- #query-monitor #qm-ajax-errors {
801
  display: none;
802
  }
803
-
804
- /* Filters */
805
- #query-monitor button,
806
- #query-monitor select {
807
- margin: 0 !important;
808
  height: auto !important;
 
809
  width: auto !important;
810
- background: none !important;
811
  }
812
-
813
- #query-monitor .qm label {
814
- cursor: pointer !important;
815
  color: #222 !important;
816
- font-weight: normal !important;
817
  font-size: 12px !important;
818
  font-style: normal !important;
 
819
  margin: 0 !important;
820
  }
821
-
822
- #query-monitor .qm thead label {
823
  flex-grow: 1 !important;
824
  }
825
-
826
- #query-monitor .qm .qm-filter-container {
827
  display: flex !important;
828
  }
829
-
830
- #query-monitor .qm .qm-filter-container label {
831
  cursor: default !important;
 
832
  }
833
-
834
- #query-monitor .qm .qm-filter-container div {
835
  /* Some themes use Select2 etc on all selects. This hides that. */
836
  display: none !important;
837
  }
838
-
839
- #query-monitor .qm select.qm-filter {
840
- display: block !important;
841
- margin: 0 0 0 5px !important;
842
- outline: 1px solid #aaa !important;
843
- border: none !important;
844
- padding: 0 !important;
845
- background: #fff !important;
846
- color: #222 !important;
847
- height: auto !important;
848
- width: auto !important;
849
- float: none !important;
850
- cursor: pointer !important;
851
  -webkit-appearance: menulist !important;
852
  -moz-appearance: menulist !important;
853
  appearance: menulist !important;
 
 
 
 
 
 
 
854
  letter-spacing: normal !important;
 
855
  max-width: 10em !important;
 
 
 
856
  }
857
-
858
- #query-monitor .qm select.qm-filter:hover {
859
  background: #f3f3f3 !important;
860
  }
861
-
862
- .qm-hide,
863
- .qm-hide-scripts-dependencies,
864
- .qm-hide-styles-dependencies,
865
- .qm-hide-scripts-dependents,
866
- .qm-hide-styles-dependents,
867
- .qm-hide-scripts-host,
868
- .qm-hide-styles-host,
869
- .qm-hide-user,
870
- .qm-hide-result,
871
- .qm-hide-name,
872
- .qm-hide-type,
873
- .qm-hide-caller,
874
- .qm-hide-component {
875
  display: none !important;
876
  }
877
-
878
- /* Sorters */
879
- #query-monitor .qm thead th.qm-sortable-column {
880
  cursor: pointer !important;
881
  }
882
-
883
- #query-monitor .qm thead th.qm-sortable-column:hover {
884
  background: #f3f3f3 !important;
885
  }
886
-
887
- #query-monitor .qm .qm-sort-heading {
888
  flex-grow: 1 !important;
889
  }
890
-
891
- #query-monitor .qm .qm-sort-controls {
892
- text-align: right !important;
893
  flex-shrink: 0 !important;
 
894
  }
895
-
896
- #query-monitor .qm .qm-sortable-column .qm-sort-arrow {
 
897
  font-family: dashicons !important;
898
  font-size: 23px !important;
899
- color: #ccc !important;
900
  margin: 0 !important;
901
  width: 16px !important;
902
- height: 10px !important;
903
- display: block !important;
904
  }
905
-
906
- #query-monitor .qm .qm-sorted-desc .qm-sort-arrow,
907
- #query-monitor .qm .qm-sorted-asc .qm-sort-arrow {
908
  color: #222 !important;
909
  }
910
-
911
- #query-monitor .qm thead th.qm-sortable-column:hover .qm-sort-arrow {
912
  color: #0073aa !important;
913
  }
914
-
915
- #query-monitor .qm .qm-sortable-column .qm-sort-arrow::before {
916
  content: "\f140" !important;
917
- top: 4px !important;
918
- right: 0 !important;
919
  position: absolute !important;
 
 
920
  }
921
-
922
- #query-monitor .qm .qm-sortable-column.qm-sorted-asc .qm-sort-arrow::before {
923
  content: "\f142" !important;
924
  }
925
-
926
- #query-monitor .qm button:focus,
927
- #query-monitor .qm a:focus,
928
- #query-monitor .qm select:focus {
929
  box-shadow: 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, 0.8) !important;
930
  }
931
-
932
- #query-monitor .qm-screen-reader-text,
933
- #query-monitor .screen-reader-text {
934
- position: absolute !important;
 
935
  margin: -1px !important;
 
936
  padding: 0 !important;
937
- height: 1px !important;
938
  width: 1px !important;
939
- overflow: hidden !important;
940
- clip: rect(0 0 0 0) !important;
941
- border: 0 !important;
942
  }
943
-
944
  @media screen and (max-width: 782px) {
945
- #query-monitor #qm-panel-menu,
946
- #query-monitor #qm-title h1.qm-title-heading {
947
  display: none;
948
  }
949
-
950
- #query-monitor #qm-title div.qm-title-heading {
951
  display: block;
952
  }
953
  }
954
- /* State Toggle */
955
- #query-monitor [data-qm-state="off"] [data-qm-state-visibility="on"],
956
- #query-monitor [data-qm-state="on"] [data-qm-state-visibility="off"] {
957
  display: none;
958
  }
959
-
960
- /* No-JS tweaks */
961
- .qm-no-js .qm-sort-controls,
962
- .qm-no-js .qm-toggle,
963
- .qm-no-js select.qm-filter {
964
  display: none !important;
965
  }
966
-
967
- /* Debug bar add-ons */
968
- #query-monitor .qm.qm-debug-bar textarea,
969
- #query-monitor .qm.qm-debug-bar pre {
970
- padding: 10px !important;
971
  border: 1px solid #ddd !important;
972
  margin: 4px 0 !important;
 
973
  }
974
-
975
- #query-monitor .qm.qm-debug-bar textarea {
976
  resize: vertical !important;
977
  }
978
-
979
- #query-monitor .qm.qm-debug-bar .left {
980
  float: left !important;
981
  }
982
-
983
- #query-monitor .qm.qm-debug-bar .right {
984
  float: right !important;
985
  }
986
-
987
- #query-monitor .qm.qm-debug-bar h2 {
988
  font-size: 14px !important;
989
  margin: 4px 6px 15px !important;
990
  }
991
-
992
- #query-monitor .qm.qm-debug-bar h3 {
993
  float: left !important;
994
  /* why */
 
 
995
  min-width: 150px !important;
996
  padding: 5px 10px 15px !important;
997
- clear: none !important;
998
  text-align: center !important;
999
- font-size: 14px !important;
1000
- margin: 3px 8px 15px 0 !important;
1001
  }
1002
-
1003
- #query-monitor .qm.qm-debug-bar h3 small {
1004
  font-size: 14px !important;
1005
  }
1006
-
1007
- #query-monitor .qm.qm-debug-bar h3 span {
1008
- white-space: nowrap !important;
1009
  display: block !important;
1010
  margin-bottom: 8px !important;
 
1011
  }
1012
-
1013
- #query-monitor .qm.qm-debug-bar h4 {
1014
- margin: 15px 6px 5px !important;
1015
  font-size: 13px !important;
 
1016
  }
1017
-
1018
- #query-monitor .qm.qm-debug-bar .qm-debug-bar-output {
1019
  position: relative !important;
1020
  }
1021
-
1022
- #query-monitor .qm.qm-debug-bar .qm-debug-bar-output table {
1023
- margin-top: 4px !important;
1024
  margin-bottom: 4px !important;
 
1025
  }
1026
-
1027
- #query-monitor #debug-menu-target-Debug_Bar_Console {
1028
  min-height: 400px !important;
1029
  }
1030
-
1031
- #query-monitor #debug-menu-target-Debug_Bar_Cache_Lookup,
1032
- #query-monitor #debug-menu-target-Debug_Bar_Rewrite_Rules,
1033
- #query-monitor #debug-menu-target-Debug_Bar_Widgets {
1034
  margin: 4px 6px !important;
1035
  }
1036
-
1037
- #query-monitor #debug-menu-target-Debug_Bar_Rewrite_Rules_Panel .filterui,
1038
- #query-monitor #debug-menu-target-Debug_Bar_Rewrite_Rules_Panel .dbrr {
1039
  margin: 0 !important;
1040
  }
1041
-
1042
- /* Broken output handling */
1043
- #query-monitor.qm-broken #qm-title {
1044
  cursor: default !important;
1045
  }
1046
-
1047
- #query-monitor #qm-broken,
1048
- #query-monitor.qm-broken .qm-title-button {
1049
  display: none !important;
1050
  }
1051
-
1052
- #query-monitor.qm-broken #qm-broken,
1053
- #query-monitor.qm-broken .qm {
1054
  display: block !important;
1055
  }
1056
-
1057
- #query-monitor.qm-broken .qm {
1058
  margin-bottom: 50px !important;
1059
  }
1060
-
1061
- #query-monitor.qm-broken #qm-broken h2 {
1062
  padding: 20px !important;
1063
  }
3
  *
4
  * @package query-monitor
5
  */
 
6
  #wpadminbar .quicklinks .menupop ul li.qm-true > a {
7
  color: #8c8 !important;
8
  }
76
  }
77
 
78
  #wpadminbar #wp-admin-bar-query-monitor .ab-icon {
 
 
 
 
79
  color: #aaa !important;
80
  display: none !important;
81
+ font: 18px/44px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
82
+ padding: 0 10px !important;
83
+ width: auto !important;
84
  }
85
 
86
  @media screen and (max-width: 782px) {
 
87
  #wpadminbar #wp-admin-bar-query-monitor .ab-icon {
88
  display: block !important;
89
  }
90
 
 
91
  #wpadminbar #wp-admin-bar-query-monitor .ab-label {
92
  display: none !important;
93
  }
94
  }
95
+ #query-monitor-main,
96
+ #query-monitor-main dl,
97
+ #query-monitor-main dt,
98
+ #query-monitor-main dd,
99
+ #query-monitor-main button,
100
+ #query-monitor-main label,
101
+ #query-monitor-main select,
102
+ #query-monitor-main table,
103
+ #query-monitor-main td,
104
+ #query-monitor-main th,
105
+ #query-monitor-main ul,
106
+ #query-monitor-main ol,
107
+ #query-monitor-main li,
108
+ #query-monitor-main code,
109
+ #query-monitor-main a,
110
+ #query-monitor-main h1,
111
+ #query-monitor-main h2,
112
+ #query-monitor-main h3,
113
+ #query-monitor-main h4,
114
+ #query-monitor-main h5,
115
+ #query-monitor-main h6,
116
+ #query-monitor-main section,
117
+ #query-monitor-main nav,
118
+ #query-monitor-main p {
 
 
119
  background: transparent !important;
120
+ border: none !important;
121
+ border-radius: 0 !important;
122
+ box-shadow: none !important;
123
  box-sizing: border-box !important;
124
+ clear: both !important;
125
+ color: #222 !important;
126
+ float: none !important;
127
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
128
+ font-size: 12px !important;
129
+ -webkit-font-smoothing: auto !important;
130
  font-style: normal !important;
131
  font-weight: normal !important;
132
+ letter-spacing: normal !important;
133
  line-height: 18px !important;
 
 
 
134
  margin: 0 !important;
135
+ outline: none !important;
136
+ padding: 0 !important;
137
+ text-align: left !important;
138
+ text-decoration: none !important;
139
+ text-indent: 0 !important;
140
  text-shadow: none !important;
141
  text-transform: none !important;
 
 
 
 
142
  transition: none !important;
143
+ vertical-align: baseline !important;
144
  word-break: normal !important;
145
+ word-wrap: normal !important;
 
 
 
 
146
  }
147
+ #query-monitor-main::before, #query-monitor-main::after,
148
+ #query-monitor-main dl::before,
149
+ #query-monitor-main dl::after,
150
+ #query-monitor-main dt::before,
151
+ #query-monitor-main dt::after,
152
+ #query-monitor-main dd::before,
153
+ #query-monitor-main dd::after,
154
+ #query-monitor-main button::before,
155
+ #query-monitor-main button::after,
156
+ #query-monitor-main label::before,
157
+ #query-monitor-main label::after,
158
+ #query-monitor-main select::before,
159
+ #query-monitor-main select::after,
160
+ #query-monitor-main table::before,
161
+ #query-monitor-main table::after,
162
+ #query-monitor-main td::before,
163
+ #query-monitor-main td::after,
164
+ #query-monitor-main th::before,
165
+ #query-monitor-main th::after,
166
+ #query-monitor-main ul::before,
167
+ #query-monitor-main ul::after,
168
+ #query-monitor-main ol::before,
169
+ #query-monitor-main ol::after,
170
+ #query-monitor-main li::before,
171
+ #query-monitor-main li::after,
172
+ #query-monitor-main code::before,
173
+ #query-monitor-main code::after,
174
+ #query-monitor-main a::before,
175
+ #query-monitor-main a::after,
176
+ #query-monitor-main h1::before,
177
+ #query-monitor-main h1::after,
178
+ #query-monitor-main h2::before,
179
+ #query-monitor-main h2::after,
180
+ #query-monitor-main h3::before,
181
+ #query-monitor-main h3::after,
182
+ #query-monitor-main h4::before,
183
+ #query-monitor-main h4::after,
184
+ #query-monitor-main h5::before,
185
+ #query-monitor-main h5::after,
186
+ #query-monitor-main h6::before,
187
+ #query-monitor-main h6::after,
188
+ #query-monitor-main section::before,
189
+ #query-monitor-main section::after,
190
+ #query-monitor-main nav::before,
191
+ #query-monitor-main nav::after,
192
+ #query-monitor-main p::before,
193
+ #query-monitor-main p::after {
194
  display: none !important;
195
  }
196
+ #query-monitor-main {
 
197
  background: #fff !important;
 
198
  border-top: 1px solid #aaa !important;
 
 
 
 
199
  bottom: 0 !important;
200
+ direction: ltr !important;
201
+ display: none;
202
  left: 0 !important;
203
+ margin: 0 !important;
204
+ position: fixed;
205
  right: 0 !important;
206
+ text-align: left !important;
207
+ z-index: 99998 !important;
208
  }
209
+ #query-monitor-main ::selection {
210
  background-color: #B9D6FB !important;
211
  color: #222 !important;
212
  }
213
+ #query-monitor-main strong,
214
+ #query-monitor-main b {
215
  font-weight: bold !important;
216
  }
217
+ #query-monitor-main em,
218
+ #query-monitor-main i {
219
  font-style: italic !important;
220
  }
221
+ #query-monitor-main.qm-show, #query-monitor-main.qm-peek {
 
 
 
222
  display: flex;
223
  flex-direction: column !important;
224
+ height: 27px;
225
  }
226
+ #query-monitor-main.qm-show {
 
227
  height: 40%;
228
+ width: 40%;
229
  }
230
+ #query-monitor-main:not(.qm-show-right) {
231
+ width: 100% !important;
232
+ }
233
+ #query-monitor-main.qm-show-right {
234
+ height: calc( 100vh - 32px ) !important;
235
+ top: 32px !important;
236
+ left: unset !important;
237
+ border-top: 0 !important;
238
+ border-left: 1px solid #aaa !important;
239
+ }
240
+ #query-monitor-main.qm-show-right #qm-panel-menu,
241
+ #query-monitor-main.qm-show-right #qm-title h1.qm-title-heading {
242
+ display: none;
243
+ }
244
+ #query-monitor-main.qm-show-right #qm-title div.qm-title-heading {
245
+ display: block;
246
+ }
247
+ #query-monitor-main.qm-show-right #qm-title {
248
+ cursor: default !important;
249
+ }
250
+ #query-monitor-main.qm-show-right #qm-side-resizer {
251
+ background: transparent !important;
252
+ cursor: ew-resize !important;
253
+ display: block !important;
254
+ height: 100% !important;
255
+ position: absolute !important;
256
+ left: -2px !important;
257
+ top: 0 !important;
258
+ width: 4px !important;
259
+ z-index: 2 !important;
260
+ }
261
+ #query-monitor-main #qm-wrapper {
262
  display: flex;
263
  flex-grow: 1 !important;
264
  /* Fix nested scrolling in Firefox. See https://bugzilla.mozilla.org/show_bug.cgi?id=1043520: */
265
  min-height: 0;
266
  }
267
+ #query-monitor-main #qm-title {
268
+ align-items: center !important;
269
  background: #f3f3f3 !important;
270
  border-bottom: 1px solid #aaa !important;
271
  cursor: ns-resize !important;
 
272
  display: flex !important;
 
 
273
  flex-shrink: 0 !important;
274
+ height: 27px !important;
275
+ padding: 0 0 0 5px !important;
276
  -moz-user-select: none !important;
277
  -ms-user-select: none !important;
278
  -webkit-user-select: none !important;
279
  user-select: none !important;
280
  }
281
+ #query-monitor-main #qm-title .qm-title-heading {
 
282
  border-right: 1px solid #bbb !important;
283
+ flex-grow: 1 !important;
284
  margin-right: 6px !important;
285
  }
286
+ #query-monitor-main #qm-title div.qm-title-heading {
287
  display: none;
288
  }
289
+ #query-monitor-main #qm-title .qm-title-button {
290
  flex-shrink: 0 !important;
291
  }
292
+ #query-monitor-main #qm-title .dashicons {
293
  transition: none !important;
294
  }
295
+ #query-monitor-main #qm-title .qm-button-container-settings .dashicons {
296
  font-size: 17px !important;
297
  margin: 3px 0 2px !important;
298
  }
299
+ #query-monitor-main #qm-title .qm-button-container-position .dashicons {
300
+ font-size: 15px !important;
301
+ margin: 4px 0 1px !important;
302
+ }
303
+ #query-monitor-main #qm-title .qm-button-container-close {
304
+ margin-right: 5px !important;
305
+ }
306
+ #query-monitor-main #qm-title .qm-button-container-close .dashicons {
307
  margin: 2px 0 3px !important;
308
  }
309
+ @media screen and (max-width: 960px) {
310
+ #query-monitor-main #qm-title .qm-button-container-position {
311
+ display: none !important;
312
+ }
313
+ }
314
+ #query-monitor-main #qm-title button {
315
  background: transparent !important;
316
+ color: #666 !important;
317
  cursor: pointer !important;
 
318
  display: inline-block !important;
319
+ margin: 0 0 0 0px !important;
320
  min-width: auto !important;
321
+ padding: 0px 4px !important;
322
  }
323
+ #query-monitor-main #qm-title button:focus,
324
+ #query-monitor-main #qm-title button:hover {
 
325
  background: #e6e6e6 !important;
326
+ color: #000 !important;
327
  }
328
+ #query-monitor-main #qm-title button:active {
329
  background: #ccc !important;
330
  }
331
+ #query-monitor-main #qm-title button.qm-button-active {
332
  color: #3879d9 !important;
333
  }
334
+ #query-monitor-main .qm {
335
  display: none !important;
336
  }
337
+ #query-monitor-main #qm-panel-menu {
 
 
338
  background: #ececec !important;
339
+ flex-shrink: 0 !important;
340
+ overflow-y: scroll !important;
341
  overscroll-behavior: contain !important;
342
  }
343
+ #query-monitor-main #qm-panel-menu ul {
344
+ display: block !important;
 
345
  list-style: none !important;
346
+ margin: 0 !important;
 
347
  padding: 0 !important;
348
+ }
349
+ #query-monitor-main #qm-panel-menu li {
350
+ display: list-item !important;
351
  margin: 0 !important;
352
+ padding: 0 !important;
353
  }
354
+ #query-monitor-main #qm-panel-menu li button {
355
+ background: #f3f3f3 !important;
356
+ border-bottom: 1px solid #ddd !important;
357
+ border-right: 1px solid #aaa !important;
358
+ color: #333 !important;
359
+ cursor: pointer !important;
360
  display: block !important;
361
  padding: 8px 28px 8px 6px !important;
 
 
 
362
  position: relative !important;
363
+ text-decoration: none !important;
 
364
  width: 100% !important;
 
365
  }
366
+ #query-monitor-main #qm-panel-menu li button:focus,
367
+ #query-monitor-main #qm-panel-menu li button:hover {
368
  background: #def !important;
369
  color: #222 !important;
370
  }
371
+ #query-monitor-main #qm-panel-menu li button:focus {
372
  text-decoration: underline !important;
373
  }
374
+ #query-monitor-main #qm-panel-menu li.qm-current-menu button {
375
+ background: #def !important;
376
+ color: #222 !important;
377
+ }
378
+ #query-monitor-main #qm-panel-menu li button.qm-selected-menu {
379
  background: #0073aa !important;
380
  color: #fff !important;
381
  text-shadow: 0 -1px 1px #006291, 1px 0 1px #006291, 0 1px 1px #006291, -1px 0 1px #006291 !important;
382
  }
383
+ #query-monitor-main #qm-panel-menu li button.qm-selected-menu:focus {
384
  background: #0084c4 !important;
385
  color: #fff !important;
386
  }
387
+ #query-monitor-main #qm-panel-menu li button.qm-selected-menu:after {
 
388
  border: solid 8px transparent;
389
+ border-right-color: #fff;
390
  content: " ";
391
+ display: inline-block !important;
392
  height: 0;
393
+ margin-top: -8px;
 
394
  pointer-events: none;
395
+ position: absolute;
396
+ right: -1px;
397
  top: 50%;
398
+ width: 0;
399
  }
400
+ #query-monitor-main #qm-panels {
401
  flex-grow: 1 !important;
402
  overflow-y: scroll !important;
403
  overscroll-behavior: contain !important;
404
  }
405
+ #query-monitor-main .qm.qm-panel-show {
406
  display: block !important;
407
  }
408
+ #query-monitor-main .qm:focus {
409
  outline: 0 !important;
410
  /* @TODO might not need this any more */
411
  }
412
+ #query-monitor-main .qm-non-tabular {
413
  padding: 10px 20px !important;
414
  }
415
+ #query-monitor-main .qm-boxed {
416
  display: flex !important;
417
  flex-wrap: wrap !important;
418
  }
419
+ #query-monitor-main .qm-boxed:not(#qm-broken) + .qm-boxed {
420
  border-top: 1px solid #ddd !important;
421
  padding-top: 10px !important;
422
  }
423
+ #query-monitor-main .qm-boxed-wrap {
424
  flex-wrap: wrap !important;
425
  }
426
+ #query-monitor-main .qm .qm-none {
427
  margin: 2em !important;
428
  }
429
+ #query-monitor-main .qm .qm-none p {
 
430
  font-style: italic !important;
431
+ text-align: center !important;
432
  }
433
+ #query-monitor-main .qm table {
434
+ border: none !important;
435
+ border-bottom: 1px solid #e0e0e0 !important;
436
  border-collapse: collapse !important;
437
  box-shadow: none !important;
438
+ color: #222 !important;
 
439
  margin: 0 !important;
440
+ table-layout: auto !important;
441
+ width: 100% !important;
442
  }
443
+ #query-monitor-main .qm table + table {
 
444
  border-top: 1px solid #e0e0e0 !important;
445
+ margin-top: 5px !important;
446
  }
447
+ #query-monitor-main .qm tr {
 
 
 
 
448
  border: none !important;
449
  }
450
+ #query-monitor-main .qm tbody th,
451
+ #query-monitor-main .qm tbody td,
452
+ #query-monitor-main .qm tfoot th,
453
+ #query-monitor-main .qm tfoot td {
454
  border: 1px solid #e0e0e0 !important;
455
  padding: 5px 5px 4px 5px !important;
456
  }
457
+ #query-monitor-main .qm tbody th,
458
+ #query-monitor-main .qm tbody td {
 
459
  border-bottom: none !important;
460
+ border-top: none !important;
461
  }
462
+ #query-monitor-main .qm thead th {
463
+ background: #fff !important;
464
  border: 1px solid #e0e0e0 !important;
465
  border-top: none !important;
466
+ box-shadow: 0px 1px 0px #e0e0e0 !important;
467
  padding: 5px !important;
468
  position: -webkit-sticky !important;
469
  position: sticky !important;
470
  top: 0 !important;
 
471
  z-index: 1 !important;
472
  }
473
+ #query-monitor-main .qm thead .qm-th {
474
  display: flex !important;
475
  }
476
+ #query-monitor-main .qm tfoot tr td,
477
+ #query-monitor-main .qm tfoot tr th {
478
+ background: #f3f3f3 !important;
479
  border: 1px solid #e0e0e0 !important;
480
  border-bottom: none !important;
481
+ bottom: 0 !important;
482
+ box-shadow: inset 0px 1px 0px #e0e0e0 !important;
483
  position: -webkit-sticky !important;
484
  position: sticky !important;
 
485
  }
486
+ #query-monitor-main .qm th:first-child,
487
+ #query-monitor-main .qm td:first-child {
488
  border-left: none !important;
489
  }
490
+ #query-monitor-main .qm th:last-child,
491
+ #query-monitor-main .qm td:last-child {
492
  border-right: none !important;
493
  }
494
+ #query-monitor-main .qm tfoot td.qm-num,
495
+ #query-monitor-main .qm tfoot th.qm-num,
496
+ #query-monitor-main .qm thead td.qm-num,
497
+ #query-monitor-main .qm thead th.qm-num {
498
  width: 5.5em !important;
499
  }
500
+ #query-monitor-main .qm th.qm-num,
501
+ #query-monitor-main .qm td.qm-num {
502
  text-align: right !important;
503
  }
504
+ #query-monitor-main .qm td.qm-row-sql {
505
  min-width: 25em !important;
506
  }
507
+ #query-monitor-main .qm td.qm-row-block-html {
508
  max-width: 40em !important;
509
  }
510
+ #query-monitor-main .qm tr.qm-warn td.qm-col-status,
511
+ #query-monitor-main .qm td.qm-url,
512
+ #query-monitor-main .qm th.qm-col-message,
513
+ #query-monitor-main .qm td.qm-row-component {
514
  min-width: 15em !important;
515
  }
516
+ #query-monitor-main .qm td .qm-toggler {
 
517
  padding: 0 22px 0 0 !important;
518
  position: relative !important;
519
  }
520
+ #query-monitor-main .qm td.qm-has-toggle:not(.qm-toggled-on) .qm-supplemental {
521
  display: none;
522
  }
523
+ #query-monitor-main .qm .qm-inner-toggle {
524
  padding: 4px 6px !important;
525
  }
526
+ #query-monitor-main .qm-has-inner .qm-toggled > table {
527
+ border-bottom: none !important;
528
  border-top: 1px solid #e0e0e0 !important;
529
  }
530
+ #query-monitor-main .qm td.qm-has-inner .qm-toggler,
531
+ #query-monitor-main .qm td.qm-has-inner {
 
 
 
 
 
 
 
 
532
  padding: 0 !important;
533
  }
534
+ #query-monitor-main .qm caption h2 {
 
535
  font-size: 14px !important;
536
+ margin: 20px !important;
537
  }
538
+ #query-monitor-main .qm-concerns table {
539
+ border-top: 1px solid #e0e0e0 !important;
540
+ margin-bottom: 20px !important;
541
+ }
542
+ #query-monitor-main .qm-non-tabular h3 {
543
+ font-size: 14px !important;
544
+ margin: 0 0 15px 0 !important;
545
+ }
546
+ #query-monitor-main .qm-non-tabular h4 {
547
  font-size: 12px !important;
548
+ margin: 20px 0 10px !important;
549
  }
550
+ #query-monitor-main .qm-non-tabular p {
551
  margin-bottom: 10px !important;
552
  }
553
+ #query-monitor-main .qm-non-tabular dd {
554
  margin: 0 0 10px 10px !important;
555
  }
556
+ #query-monitor-main .qm-non-tabular h3 a {
557
  float: right !important;
558
  }
559
+ #query-monitor-main #qm-conditionals li {
560
  display: inline-block !important;
561
  margin: 0 20px 5px 0 !important;
562
  }
563
+ #query-monitor-main .qm-non-tabular section,
564
+ #query-monitor-main .qm-non-tabular .qm-section {
565
  margin: 0 0 30px 0 !important;
566
  }
567
+ #query-monitor-main .qm-non-tabular .qm-boxed section,
568
+ #query-monitor-main .qm-non-tabular .qm-boxed .qm-section {
 
569
  border-right: 1px solid #ddd !important;
570
+ margin: 0 20px 10px 0 !important;
571
  padding: 10px 20px 10px 0 !important;
572
  }
573
+ #query-monitor-main .qm-non-tabular .qm-boxed section:last-child,
574
+ #query-monitor-main .qm-non-tabular .qm-boxed .qm-section:last-child {
 
575
  border-right: none !important;
576
+ margin-right: 0 !important;
577
  padding-right: 20px !important;
578
  }
579
+ #query-monitor-main .qm-non-tabular table {
580
  border-bottom-color: #e0e0e0 !important;
581
  }
582
+ #query-monitor-main .qm ol,
583
+ #query-monitor-main .qm ul {
584
  list-style: none !important;
585
  }
586
+ #query-monitor-main .qm li {
587
  display: list-item !important;
588
  list-style: none !important;
589
  }
590
+ #query-monitor-main .qm li::before {
591
  content: '' !important;
592
  }
593
+ #query-monitor-main .qm .qm-has-toggle ol.qm-numbered li {
594
  list-style: none !important;
595
  }
596
+ #query-monitor-main .qm .qm-toggled-on ol.qm-numbered li,
597
+ #query-monitor-main .qm ol.qm-numbered li {
598
  list-style: decimal inside !important;
599
  }
600
+ #query-monitor-main .qm code,
601
+ #query-monitor-main .qm pre {
602
+ font-family: Menlo, Monaco, Consolas, monospace !important;
603
  font-size: 11px !important;
604
  line-height: 18px !important;
 
605
  }
606
+ #query-monitor-main .qm pre {
607
  background: transparent !important;
 
 
608
  height: auto !important;
609
+ margin: 0 !important;
610
  padding: 0 !important;
611
+ width: auto !important;
612
  }
613
+ #query-monitor-main .qm .qm-true code,
614
+ #query-monitor-main .qm p.qm-true,
615
+ #query-monitor-main .qm span.qm-true,
616
+ #query-monitor-main .qm td.qm-true {
617
  color: #4a4 !important;
618
  }
619
+ #query-monitor-main .qm .qm-false code,
620
+ #query-monitor-main .qm span.qm-false,
621
+ #query-monitor-main .qm td.qm-false {
622
  color: #999 !important;
623
  }
624
+ #query-monitor-main .qm .qm-num,
625
+ #query-monitor-main .qm code,
626
+ #query-monitor-main .qm .qm-nowrap {
627
  white-space: nowrap !important;
628
  }
629
+ #query-monitor-main .qm .qm-wrap code,
630
+ #query-monitor-main .qm .qm-wrap {
 
 
631
  white-space: normal !important;
 
 
 
632
  word-break: break-all !important;
633
+ word-wrap: break-word !important;
634
+ }
635
+ #query-monitor-main .qm .qm-pre-wrap code {
636
  white-space: pre-wrap !important;
637
+ word-break: break-all !important;
638
+ word-wrap: break-word !important;
639
  }
640
+ #query-monitor-main .qm .qm-sticky {
641
  position: sticky !important;
642
  top: 36px !important;
643
  }
644
+ #query-monitor-main .qm .qm-current,
645
+ #query-monitor-main .qm td.qm-has-toggle p,
646
+ #query-monitor-main .qm .qm-nonselectsql code,
647
+ #query-monitor-main .qm .qm-nonselectsql {
648
  color: #a0a !important;
649
  }
650
+ #query-monitor-main .qm .qm-info {
651
  color: #777 !important;
652
  }
653
+ #query-monitor-main .qm .qm-supplemental {
 
654
  margin-left: 0.75em !important;
655
+ margin-right: 0.75em !important;
656
  }
657
+ #query-monitor-main .qm td.qm-toggled-on .qm-inverse-toggled,
658
+ #query-monitor-main .qm td .qm-toggled {
659
  display: none;
660
  }
661
+ #query-monitor-main .qm button.qm-button,
662
+ #query-monitor-main .qm .qm-toggle {
 
 
663
  background: #0085ba !important;
 
664
  border: 1px solid #0073a1 !important;
665
  border-radius: 2px !important;
666
+ color: #fff !important;
667
+ cursor: pointer !important;
668
+ font-weight: normal !important;
669
  text-shadow: 0 -1px 1px #0073a1, 1px 0 1px #0073a1, 0 1px 1px #0073a1, -1px 0 1px #0073a1 !important;
670
  }
671
+ #query-monitor-main .qm .qm-toggle {
672
+ bottom: auto !important;
673
  font-family: Menlo, Monaco, Consolas, monospace !important;
674
+ height: 18px !important;
675
+ left: auto !important;
676
+ line-height: 16px !important;
677
+ padding: 0 !important;
678
  position: absolute !important;
 
679
  right: 0 !important;
 
 
680
  text-align: center !important;
681
+ top: 0 !important;
 
682
  width: 18px !important;
683
  }
684
+ #query-monitor-main .qm button {
685
  cursor: pointer !important;
686
  }
687
+ #query-monitor-main .qm button.qm-button {
688
  padding: 4px 10px !important;
689
  }
690
+ #query-monitor-main .qm .qm-has-inner .qm-toggle {
 
691
  right: 5px !important;
692
+ top: 5px !important;
693
  }
694
+ #query-monitor-main .qm button.qm-button:hover,
695
+ #query-monitor-main .qm button.qm-button:focus,
696
+ #query-monitor-main .qm .qm-toggle:focus,
697
+ #query-monitor-main .qm .qm-toggle:hover {
 
 
698
  background: #0094ce !important;
699
+ color: #fff !important;
700
+ text-decoration: none !important;
701
  }
702
+ #query-monitor-main .qm tbody tr.qm-odd td,
703
+ #query-monitor-main .qm tbody tr.qm-odd th {
704
  background: #f7f7f7 !important;
705
  }
706
+ #query-monitor-main .qm-non-tabular .qm-warn,
707
+ #query-monitor-main .qm thead tr .qm-warn,
708
+ #query-monitor-main .qm tbody tr .qm-warn {
 
 
 
 
 
 
 
709
  background-color: #fff0f0 !important;
710
  color: #a00 !important;
711
  }
712
+ #query-monitor-main .qm tbody tr th.qm-warn,
713
+ #query-monitor-main .qm tbody tr td.qm-warn,
714
+ #query-monitor-main .qm tbody tr.qm-warn td,
715
+ #query-monitor-main .qm tbody tr.qm-warn th {
716
  background-color: #fff0f0 !important;
 
717
  border-color: #ffd6d6 !important;
718
+ box-shadow: inset 0 -1px #ffd6d6 !important;
719
  color: #a00 !important;
720
  }
721
+ #query-monitor-main .qm-non-tabular .qm-warn code,
722
+ #query-monitor-main .qm tbody .qm-warn li,
723
+ #query-monitor-main .qm tbody .qm-warn .qm-info,
724
+ #query-monitor-main .qm tbody .qm-warn code {
 
725
  background-color: transparent !important;
726
+ color: #a00 !important;
727
  }
728
+ #query-monitor-main .qm .qm-notice {
729
  background: #def !important;
730
  border: 1px solid #aad5ff !important;
 
731
  margin: 0 0 10px 0 !important;
732
+ padding: 10px 20px 0 !important;
733
  }
734
+ #query-monitor-main .qm .dashicons {
735
  font-size: 16px !important;
 
736
  height: 16px !important;
737
  margin-right: 0.3em !important;
738
  transition: none !important;
739
+ width: 16px !important;
740
  }
741
+ #query-monitor-main .qm .qm-dashicons-yes {
 
742
  background-color: #0a0 !important;
743
  border-radius: 50% !important;
744
+ color: #fff !important;
745
  }
746
+ #query-monitor-main .qm tbody tr.qm-hovered th,
747
+ #query-monitor-main .qm tbody tr.qm-hovered td,
748
+ #query-monitor-main .qm tbody tr:hover th,
749
+ #query-monitor-main .qm tbody tr:hover td {
750
  background: #eef3fa !important;
751
  }
752
+ #query-monitor-main .qm thead th.qm-filtered select.qm-filter {
753
  background-color: #ffd !important;
754
  color: #222 !important;
755
  }
756
+ #query-monitor-main .qm tbody tr td.qm-highlight,
757
+ #query-monitor-main .qm tbody tr.qm-highlight td {
758
  background-color: #ffd !important;
 
759
  border-color: #eec !important;
760
+ box-shadow: inset 0 -1px #eec !important;
761
  color: #222 !important;
762
  }
763
+ #query-monitor-main .qm button.qm-filter-trigger,
764
+ #query-monitor-main .qm button.qm-filter-trigger code,
765
+ #query-monitor-main .qm tbody .qm-warn a code,
766
+ #query-monitor-main .qm a code,
767
+ #query-monitor-main .qm a {
768
  color: #0073aa !important;
 
769
  cursor: pointer !important;
770
+ text-decoration: none !important;
771
  }
772
+ #query-monitor-main .qm button.qm-filter-trigger:after, #query-monitor-main .qm button.qm-filter-trigger:focus, #query-monitor-main .qm button.qm-filter-trigger:hover,
773
+ #query-monitor-main .qm button.qm-filter-trigger code:after,
774
+ #query-monitor-main .qm button.qm-filter-trigger code:focus,
775
+ #query-monitor-main .qm button.qm-filter-trigger code:hover,
776
+ #query-monitor-main .qm tbody .qm-warn a code:after,
777
+ #query-monitor-main .qm tbody .qm-warn a code:focus,
778
+ #query-monitor-main .qm tbody .qm-warn a code:hover,
779
+ #query-monitor-main .qm a code:after,
780
+ #query-monitor-main .qm a code:focus,
781
+ #query-monitor-main .qm a code:hover,
782
+ #query-monitor-main .qm a:after,
783
+ #query-monitor-main .qm a:focus,
784
+ #query-monitor-main .qm a:hover {
785
  color: #0096dd !important;
786
+ text-decoration: underline !important;
787
  }
788
+ #query-monitor-main .qm a.qm-external-link:after,
789
+ #query-monitor-main .qm a.qm-link:after,
790
+ #query-monitor-main .qm a.qm-edit-link:after,
791
+ #query-monitor-main .qm button.qm-filter-trigger:after {
 
 
 
 
792
  display: inline-block !important;
793
+ font-family: dashicons !important;
794
  font-size: 13px !important;
795
+ left: 2px !important;
796
  line-height: 15px !important;
797
  position: relative !important;
798
+ text-decoration: none !important;
799
  top: 2px !important;
800
+ visibility: hidden !important;
801
  }
802
+ #query-monitor-main .qm a.qm-external-link:after,
803
+ #query-monitor-main .qm a.qm-link:hover:after,
804
+ #query-monitor-main .qm a.qm-link:focus:after,
805
+ #query-monitor-main .qm a.qm-edit-link:hover:after,
806
+ #query-monitor-main .qm a.qm-edit-link:focus:after,
807
+ #query-monitor-main .qm button.qm-filter-trigger:hover:after,
808
+ #query-monitor-main .qm button.qm-filter-trigger:focus:after {
 
 
 
 
809
  visibility: visible !important;
810
  }
811
+ #query-monitor-main .qm button.qm-filter-trigger:after {
 
812
  content: '\f536' !important;
813
  }
814
+ #query-monitor-main .qm a.qm-edit-link:after {
 
815
  content: '\f464' !important;
816
  }
817
+ #query-monitor-main .qm a.qm-external-link:after,
818
+ #query-monitor-main .qm a.qm-link:after {
 
819
  content: '\f504' !important;
820
  }
821
+ #query-monitor-main #qm-ajax-errors {
 
822
  display: none;
823
  }
824
+ #query-monitor-main button,
825
+ #query-monitor-main select {
826
+ background: none !important;
827
+ cursor: pointer !important;
 
828
  height: auto !important;
829
+ margin: 0 !important;
830
  width: auto !important;
 
831
  }
832
+ #query-monitor-main .qm label {
 
 
833
  color: #222 !important;
834
+ cursor: pointer !important;
835
  font-size: 12px !important;
836
  font-style: normal !important;
837
+ font-weight: normal !important;
838
  margin: 0 !important;
839
  }
840
+ #query-monitor-main .qm thead label {
 
841
  flex-grow: 1 !important;
842
  }
843
+ #query-monitor-main .qm .qm-filter-container {
 
844
  display: flex !important;
845
  }
846
+ #query-monitor-main .qm .qm-filter-container label {
 
847
  cursor: default !important;
848
+ white-space: nowrap !important;
849
  }
850
+ #query-monitor-main .qm .qm-filter-container div {
 
851
  /* Some themes use Select2 etc on all selects. This hides that. */
852
  display: none !important;
853
  }
854
+ #query-monitor-main .qm select.qm-filter {
 
 
 
 
 
 
 
 
 
 
 
 
855
  -webkit-appearance: menulist !important;
856
  -moz-appearance: menulist !important;
857
  appearance: menulist !important;
858
+ background: #fff !important;
859
+ border: none !important;
860
+ color: #222 !important;
861
+ cursor: pointer !important;
862
+ display: block !important;
863
+ float: none !important;
864
+ height: auto !important;
865
  letter-spacing: normal !important;
866
+ margin: 0 0 0 5px !important;
867
  max-width: 10em !important;
868
+ outline: 1px solid #aaa !important;
869
+ padding: 0 !important;
870
+ width: auto !important;
871
  }
872
+ #query-monitor-main .qm select.qm-filter:hover {
 
873
  background: #f3f3f3 !important;
874
  }
875
+ #query-monitor-main .qm-hide,
876
+ #query-monitor-main .qm-hide-scripts-dependencies,
877
+ #query-monitor-main .qm-hide-styles-dependencies,
878
+ #query-monitor-main .qm-hide-scripts-dependents,
879
+ #query-monitor-main .qm-hide-styles-dependents,
880
+ #query-monitor-main .qm-hide-scripts-host,
881
+ #query-monitor-main .qm-hide-styles-host,
882
+ #query-monitor-main .qm-hide-user,
883
+ #query-monitor-main .qm-hide-result,
884
+ #query-monitor-main .qm-hide-name,
885
+ #query-monitor-main .qm-hide-type,
886
+ #query-monitor-main .qm-hide-caller,
887
+ #query-monitor-main .qm-hide-component {
 
888
  display: none !important;
889
  }
890
+ #query-monitor-main .qm thead th.qm-sortable-column {
 
 
891
  cursor: pointer !important;
892
  }
893
+ #query-monitor-main .qm thead th.qm-sortable-column:hover {
 
894
  background: #f3f3f3 !important;
895
  }
896
+ #query-monitor-main .qm .qm-sort-heading {
 
897
  flex-grow: 1 !important;
898
  }
899
+ #query-monitor-main .qm .qm-sort-controls {
 
 
900
  flex-shrink: 0 !important;
901
+ text-align: right !important;
902
  }
903
+ #query-monitor-main .qm .qm-sortable-column .qm-sort-arrow {
904
+ color: #ccc !important;
905
+ display: block !important;
906
  font-family: dashicons !important;
907
  font-size: 23px !important;
908
+ height: 10px !important;
909
  margin: 0 !important;
910
  width: 16px !important;
 
 
911
  }
912
+ #query-monitor-main .qm .qm-sorted-desc .qm-sort-arrow,
913
+ #query-monitor-main .qm .qm-sorted-asc .qm-sort-arrow {
 
914
  color: #222 !important;
915
  }
916
+ #query-monitor-main .qm thead th.qm-sortable-column:hover .qm-sort-arrow {
 
917
  color: #0073aa !important;
918
  }
919
+ #query-monitor-main .qm .qm-sortable-column .qm-sort-arrow::before {
 
920
  content: "\f140" !important;
 
 
921
  position: absolute !important;
922
+ right: 0 !important;
923
+ top: 4px !important;
924
  }
925
+ #query-monitor-main .qm .qm-sortable-column.qm-sorted-asc .qm-sort-arrow::before {
 
926
  content: "\f142" !important;
927
  }
928
+ #query-monitor-main .qm button:focus,
929
+ #query-monitor-main .qm a:focus,
930
+ #query-monitor-main .qm select:focus {
 
931
  box-shadow: 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, 0.8) !important;
932
  }
933
+ #query-monitor-main .qm-screen-reader-text,
934
+ #query-monitor-main .screen-reader-text {
935
+ border: 0 !important;
936
+ clip: rect(0 0 0 0) !important;
937
+ height: 1px !important;
938
  margin: -1px !important;
939
+ overflow: hidden !important;
940
  padding: 0 !important;
941
+ position: absolute !important;
942
  width: 1px !important;
 
 
 
943
  }
 
944
  @media screen and (max-width: 782px) {
945
+ #query-monitor-main #qm-panel-menu,
946
+ #query-monitor-main #qm-title h1.qm-title-heading {
947
  display: none;
948
  }
949
+ #query-monitor-main #qm-title div.qm-title-heading {
 
950
  display: block;
951
  }
952
  }
953
+ #query-monitor-main [data-qm-state="off"] [data-qm-state-visibility="on"],
954
+ #query-monitor-main [data-qm-state="on"] [data-qm-state-visibility="off"] {
 
955
  display: none;
956
  }
957
+ #query-monitor-main.qm-no-js .qm-sort-controls, #query-monitor-main.qm-no-js .qm-toggle, #query-monitor-main.qm-no-js select.qm-filter {
 
 
 
 
958
  display: none !important;
959
  }
960
+ #query-monitor-main .qm.qm-debug-bar textarea,
961
+ #query-monitor-main .qm.qm-debug-bar pre {
 
 
 
962
  border: 1px solid #ddd !important;
963
  margin: 4px 0 !important;
964
+ padding: 10px !important;
965
  }
966
+ #query-monitor-main .qm.qm-debug-bar textarea {
 
967
  resize: vertical !important;
968
  }
969
+ #query-monitor-main .qm.qm-debug-bar .left {
 
970
  float: left !important;
971
  }
972
+ #query-monitor-main .qm.qm-debug-bar .right {
 
973
  float: right !important;
974
  }
975
+ #query-monitor-main .qm.qm-debug-bar h2 {
 
976
  font-size: 14px !important;
977
  margin: 4px 6px 15px !important;
978
  }
979
+ #query-monitor-main .qm.qm-debug-bar h3 {
980
+ clear: none !important;
981
  float: left !important;
982
  /* why */
983
+ font-size: 14px !important;
984
+ margin: 3px 8px 15px 0 !important;
985
  min-width: 150px !important;
986
  padding: 5px 10px 15px !important;
 
987
  text-align: center !important;
 
 
988
  }
989
+ #query-monitor-main .qm.qm-debug-bar h3 small {
 
990
  font-size: 14px !important;
991
  }
992
+ #query-monitor-main .qm.qm-debug-bar h3 span {
 
 
993
  display: block !important;
994
  margin-bottom: 8px !important;
995
+ white-space: nowrap !important;
996
  }
997
+ #query-monitor-main .qm.qm-debug-bar h4 {
 
 
998
  font-size: 13px !important;
999
+ margin: 15px 6px 5px !important;
1000
  }
1001
+ #query-monitor-main .qm.qm-debug-bar .qm-debug-bar-output {
 
1002
  position: relative !important;
1003
  }
1004
+ #query-monitor-main .qm.qm-debug-bar .qm-debug-bar-output table {
 
 
1005
  margin-bottom: 4px !important;
1006
+ margin-top: 4px !important;
1007
  }
1008
+ #query-monitor-main #debug-menu-target-Debug_Bar_Console {
 
1009
  min-height: 400px !important;
1010
  }
1011
+ #query-monitor-main #debug-menu-target-Debug_Bar_Cache_Lookup,
1012
+ #query-monitor-main #debug-menu-target-Debug_Bar_Rewrite_Rules,
1013
+ #query-monitor-main #debug-menu-target-Debug_Bar_Widgets {
 
1014
  margin: 4px 6px !important;
1015
  }
1016
+ #query-monitor-main #debug-menu-target-Debug_Bar_Rewrite_Rules_Panel .filterui,
1017
+ #query-monitor-main #debug-menu-target-Debug_Bar_Rewrite_Rules_Panel .dbrr {
 
1018
  margin: 0 !important;
1019
  }
1020
+ #query-monitor-main.qm-broken #qm-title {
 
 
1021
  cursor: default !important;
1022
  }
1023
+ #query-monitor-main #qm-broken, #query-monitor-main.qm-broken .qm-title-button {
 
 
1024
  display: none !important;
1025
  }
1026
+ #query-monitor-main.qm-broken #qm-broken, #query-monitor-main.qm-broken .qm {
 
 
1027
  display: block !important;
1028
  }
1029
+ #query-monitor-main.qm-broken .qm {
 
1030
  margin-bottom: 50px !important;
1031
  }
1032
+ #query-monitor-main.qm-broken #qm-broken h2 {
 
1033
  padding: 20px !important;
1034
  }
assets/query-monitor.js CHANGED
@@ -48,17 +48,22 @@ var QM_i18n = {
48
  if ( window.jQuery ) {
49
 
50
  jQuery( function($) {
51
- var minheight = 100;
52
- var maxheight = ( $(window).height() - 50 );
53
- var container = $('#query-monitor');
54
- var container_storage_key = 'qm-container-height';
55
- var container_pinned_key = 'qm-container-pinned';
56
-
57
- if ( $('#query-monitor').hasClass('qm-peek') ) {
 
 
 
 
 
58
  minheight = 27;
59
  }
60
 
61
- $('#query-monitor').removeClass('qm-no-js').addClass('qm-js');
62
 
63
  var link_click = function(e){
64
  var href = $( this ).attr('href') || $( this ).data('qm-href');
@@ -75,7 +80,7 @@ if ( window.jQuery ) {
75
  };
76
 
77
  var show_panel = function( panel ) {
78
- $('#query-monitor').addClass('qm-show').removeClass('qm-hide');
79
  $( '.qm' ).removeClass('qm-panel-show');
80
  $('#qm-panels').scrollTop(0);
81
  $( panel ).addClass('qm-panel-show');
@@ -85,15 +90,20 @@ if ( window.jQuery ) {
85
  }
86
 
87
  $('#qm-panel-menu').find('button').removeClass('qm-selected-menu');
 
88
  var selected_menu = $('#qm-panel-menu').find('[data-qm-href="' + panel + '"]').addClass('qm-selected-menu');
89
 
90
  if ( selected_menu.length ) {
91
- var selected_menu_pos = selected_menu.position();
92
  var menu_height = $('#qm-panel-menu').height();
93
  var menu_scroll = $('#qm-panel-menu').scrollTop();
 
 
 
 
94
 
95
- if ( ( selected_menu_pos.top > ( menu_height + menu_scroll ) ) || ( selected_menu_pos.top < menu_scroll ) ) {
96
- $('#qm-panel-menu').scrollTop( selected_menu_pos.top - ( menu_height / 2 ) );
97
  }
98
  }
99
 
@@ -148,13 +158,13 @@ if ( window.jQuery ) {
148
  $('#wp-admin-bar-query-monitor,#wp-admin-bar-query-monitor-default').show();
149
 
150
  } else {
151
- $('#query-monitor').addClass('qm-peek').removeClass('qm-hide');
152
  $('#qm-overview').addClass('qm-panel-show');
153
  }
154
 
155
  $('#qm-panel-menu').find('button').on('click',link_click);
156
 
157
- $('#query-monitor').find('.qm-filter').on('change',function(e){
158
 
159
  var filter = $(this).attr('data-filter'),
160
  table = $(this).closest('table'),
@@ -209,7 +219,7 @@ if ( window.jQuery ) {
209
  stripes(table);
210
  });
211
 
212
- $('#query-monitor').find('.qm-filter').each(function () {
213
  var key = $(this).attr('id');
214
  var value = localStorage.getItem( key );
215
  if ( value !== null ) {
@@ -222,7 +232,7 @@ if ( window.jQuery ) {
222
  }
223
  });
224
 
225
- $('#query-monitor').find('.qm-filter-trigger').on('click',function(e){
226
  var filter = $(this).data('qm-filter'),
227
  value = $(this).data('qm-value'),
228
  target = $(this).data('qm-target');
@@ -233,7 +243,7 @@ if ( window.jQuery ) {
233
  e.preventDefault();
234
  });
235
 
236
- $('#query-monitor').find('.qm-toggle').on('click',function(e){
237
  var el = $(this);
238
  var currentState = el.attr('aria-expanded');
239
  var newState = 'true';
@@ -260,7 +270,7 @@ if ( window.jQuery ) {
260
  e.preventDefault();
261
  });
262
 
263
- $('#query-monitor').find('.qm-highlighter').on('mouseenter',function(e){
264
 
265
  var subject = $(this).data('qm-highlight');
266
  var table = $(this).closest('table');
@@ -288,7 +298,7 @@ if ( window.jQuery ) {
288
  $(this).closest('tr').removeClass('qm-hovered');
289
  });
290
 
291
- $('#query-monitor').find('.qm table').on('sorted.qm',function(){
292
  stripes( $(this) );
293
  });
294
 
@@ -362,22 +372,28 @@ if ( window.jQuery ) {
362
 
363
  $.qm.tableSort({target: $('.qm-sortable')});
364
 
365
- var startY, resizerHeight, toolbarHeight;
366
 
367
- toolbarHeight = $('#wpadminbar').outerHeight();
368
-
369
- $(document).on('mousedown', '#qm-title', function(event) {
370
  resizerHeight = $(this).outerHeight() - 1;
371
  startY = container.outerHeight() + event.clientY;
 
372
 
373
  $(document).on('mousemove', qm_do_resizer_drag);
374
  $(document).on('mouseup', qm_stop_resizer_drag);
375
  });
376
 
377
  function qm_do_resizer_drag(event) {
378
- var h = ( startY - event.clientY );
379
- if ( h >= resizerHeight && h < ( $(window).height() - toolbarHeight ) ) {
380
- container.height( h );
 
 
 
 
 
 
 
381
  }
382
  }
383
 
@@ -385,23 +401,45 @@ if ( window.jQuery ) {
385
  $(document).off('mousemove', qm_do_resizer_drag);
386
  $(document).off('mouseup', qm_stop_resizer_drag);
387
 
388
- localStorage.setItem( container_storage_key, container.height() );
 
 
 
 
 
 
389
  }
390
 
391
- var h = localStorage.getItem( container_storage_key );
392
- if ( h !== null && ! $('#query-monitor').hasClass('qm-peek') ) {
393
- if ( h < minheight ) {
394
- h = minheight;
395
- }
396
- if ( h > maxheight ) {
397
- h = maxheight;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  }
399
- container.height( h );
400
  }
401
 
402
  $(window).on('resize', function(){
403
- var maxheight = ( $(window).height() - toolbarHeight );
404
  var h = container.height();
 
 
 
 
405
 
406
  if ( h < minheight ) {
407
  container.height( minheight );
@@ -409,11 +447,20 @@ if ( window.jQuery ) {
409
  if ( h > maxheight ) {
410
  container.height( maxheight );
411
  }
412
- localStorage.setItem( container_storage_key, container.height() );
 
 
 
 
 
 
 
 
 
413
  });
414
 
415
  $('.qm-button-container-close').click(function(){
416
- $('#query-monitor').removeClass('qm-show').height('');
417
  localStorage.removeItem( container_pinned_key );
418
  });
419
 
@@ -422,6 +469,22 @@ if ( window.jQuery ) {
422
  $('#qm-settings').focus();
423
  });
424
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
  var pinned = localStorage.getItem( container_pinned_key );
426
  if ( pinned && $( pinned ).length ) {
427
  show_panel( pinned );
48
  if ( window.jQuery ) {
49
 
50
  jQuery( function($) {
51
+ var toolbarHeight = $('#wpadminbar').outerHeight();
52
+ var minheight = 100;
53
+ var maxheight = ( $(window).height() - toolbarHeight );
54
+ var minwidth = 300;
55
+ var maxwidth = $(window).width();
56
+ var container = $('#query-monitor-main');
57
+ var container_height_key = 'qm-container-height';
58
+ var container_pinned_key = 'qm-container-pinned';
59
+ var container_position_key = 'qm-container-position';
60
+ var container_width_key = 'qm-container-width';
61
+
62
+ if ( container.hasClass('qm-peek') ) {
63
  minheight = 27;
64
  }
65
 
66
+ container.removeClass('qm-no-js').addClass('qm-js');
67
 
68
  var link_click = function(e){
69
  var href = $( this ).attr('href') || $( this ).data('qm-href');
80
  };
81
 
82
  var show_panel = function( panel ) {
83
+ container.addClass('qm-show').removeClass('qm-hide');
84
  $( '.qm' ).removeClass('qm-panel-show');
85
  $('#qm-panels').scrollTop(0);
86
  $( panel ).addClass('qm-panel-show');
90
  }
91
 
92
  $('#qm-panel-menu').find('button').removeClass('qm-selected-menu');
93
+ $('#qm-panel-menu').find('li').removeClass('qm-current-menu');
94
  var selected_menu = $('#qm-panel-menu').find('[data-qm-href="' + panel + '"]').addClass('qm-selected-menu');
95
 
96
  if ( selected_menu.length ) {
97
+ var selected_menu_top = selected_menu.position().top - 27;
98
  var menu_height = $('#qm-panel-menu').height();
99
  var menu_scroll = $('#qm-panel-menu').scrollTop();
100
+ selected_menu.closest('#qm-panel-menu > ul > li').addClass('qm-current-menu');
101
+
102
+ var selected_menu_off_bottom = ( selected_menu_top > ( menu_height ) );
103
+ var selected_menu_off_top = ( selected_menu_top < 0 );
104
 
105
+ if ( selected_menu_off_bottom || selected_menu_off_top ) {
106
+ $('#qm-panel-menu').scrollTop( selected_menu_top + menu_scroll - ( menu_height / 2 ) + ( selected_menu.outerHeight() / 2 ) );
107
  }
108
  }
109
 
158
  $('#wp-admin-bar-query-monitor,#wp-admin-bar-query-monitor-default').show();
159
 
160
  } else {
161
+ container.addClass('qm-peek').removeClass('qm-hide');
162
  $('#qm-overview').addClass('qm-panel-show');
163
  }
164
 
165
  $('#qm-panel-menu').find('button').on('click',link_click);
166
 
167
+ container.find('.qm-filter').on('change',function(e){
168
 
169
  var filter = $(this).attr('data-filter'),
170
  table = $(this).closest('table'),
219
  stripes(table);
220
  });
221
 
222
+ container.find('.qm-filter').each(function () {
223
  var key = $(this).attr('id');
224
  var value = localStorage.getItem( key );
225
  if ( value !== null ) {
232
  }
233
  });
234
 
235
+ container.find('.qm-filter-trigger').on('click',function(e){
236
  var filter = $(this).data('qm-filter'),
237
  value = $(this).data('qm-value'),
238
  target = $(this).data('qm-target');
243
  e.preventDefault();
244
  });
245
 
246
+ container.find('.qm-toggle').on('click',function(e){
247
  var el = $(this);
248
  var currentState = el.attr('aria-expanded');
249
  var newState = 'true';
270
  e.preventDefault();
271
  });
272
 
273
+ container.find('.qm-highlighter').on('mouseenter',function(e){
274
 
275
  var subject = $(this).data('qm-highlight');
276
  var table = $(this).closest('table');
298
  $(this).closest('tr').removeClass('qm-hovered');
299
  });
300
 
301
+ container.find('.qm table').on('sorted.qm',function(){
302
  stripes( $(this) );
303
  });
304
 
372
 
373
  $.qm.tableSort({target: $('.qm-sortable')});
374
 
375
+ var startY, startX, resizerHeight;
376
 
377
+ $(document).on('mousedown', '.qm-resizer', function(event) {
 
 
378
  resizerHeight = $(this).outerHeight() - 1;
379
  startY = container.outerHeight() + event.clientY;
380
+ startX = container.outerWidth() + event.clientX;
381
 
382
  $(document).on('mousemove', qm_do_resizer_drag);
383
  $(document).on('mouseup', qm_stop_resizer_drag);
384
  });
385
 
386
  function qm_do_resizer_drag(event) {
387
+ if ( ! container.hasClass('qm-show-right') ) {
388
+ var h = ( startY - event.clientY );
389
+ if ( h >= resizerHeight && h <= maxheight ) {
390
+ container.height( h );
391
+ }
392
+ } else {
393
+ var w = ( startX - event.clientX );
394
+ if ( w >= minwidth && w <= maxwidth ) {
395
+ container.width( w );
396
+ }
397
  }
398
  }
399
 
401
  $(document).off('mousemove', qm_do_resizer_drag);
402
  $(document).off('mouseup', qm_stop_resizer_drag);
403
 
404
+ if ( ! container.hasClass('qm-show-right') ) {
405
+ localStorage.removeItem( container_position_key );
406
+ localStorage.setItem( container_height_key, container.height() );
407
+ } else {
408
+ localStorage.setItem( container_position_key, 'right' );
409
+ localStorage.setItem( container_width_key, container.width() );
410
+ }
411
  }
412
 
413
+ var p = localStorage.getItem( container_position_key );
414
+ var h = localStorage.getItem( container_height_key );
415
+ var w = localStorage.getItem( container_width_key );
416
+ if ( ! container.hasClass('qm-peek') ) {
417
+ if ( p === 'right' && w !== null ) {
418
+ if ( w < minwidth ) {
419
+ w = minwidth;
420
+ }
421
+ if ( w > maxwidth ) {
422
+ w = maxwidth;
423
+ }
424
+ container.width( w );
425
+ container.addClass('qm-show-right');
426
+ } else if ( p !== 'right' && h !== null ) {
427
+ if ( h < minheight ) {
428
+ h = minheight;
429
+ }
430
+ if ( h > maxheight ) {
431
+ h = maxheight;
432
+ }
433
+ container.height( h );
434
  }
 
435
  }
436
 
437
  $(window).on('resize', function(){
 
438
  var h = container.height();
439
+ var w = container.width();
440
+
441
+ maxheight = ( $(window).height() - toolbarHeight );
442
+ maxwidth = $(window).width();
443
 
444
  if ( h < minheight ) {
445
  container.height( minheight );
447
  if ( h > maxheight ) {
448
  container.height( maxheight );
449
  }
450
+ localStorage.setItem( container_height_key, container.height() );
451
+
452
+ if ( w > $(window).width() ) {
453
+ container.width( minwidth );
454
+ localStorage.setItem( container_width_key, container.width() );
455
+ }
456
+ if ( $(window).width() < 960 ) {
457
+ container.removeClass('qm-show-right');
458
+ localStorage.removeItem( container_position_key );
459
+ }
460
  });
461
 
462
  $('.qm-button-container-close').click(function(){
463
+ container.removeClass('qm-show').height('').width('');
464
  localStorage.removeItem( container_pinned_key );
465
  });
466
 
469
  $('#qm-settings').focus();
470
  });
471
 
472
+ $('.qm-button-container-position').click(function(){
473
+ container.toggleClass('qm-show-right');
474
+
475
+ if ( container.hasClass('qm-show-right') ) {
476
+ var w = localStorage.getItem( container_width_key );
477
+
478
+ if ( w !== null && w < $(window).width() ) {
479
+ container.width( w );
480
+ }
481
+
482
+ localStorage.setItem( container_position_key, 'right' );
483
+ } else {
484
+ localStorage.removeItem( container_position_key );
485
+ }
486
+ });
487
+
488
  var pinned = localStorage.getItem( container_pinned_key );
489
  if ( pinned && $( pinned ).length ) {
490
  show_panel( pinned );
classes/Backtrace.php CHANGED
@@ -55,11 +55,13 @@ class QM_Backtrace {
55
  protected $calling_file = '';
56
 
57
  public function __construct( array $args = array() ) {
 
 
58
  $args = array_merge( array(
59
  'ignore_current_filter' => true,
60
  'ignore_frames' => 0,
61
  ), $args );
62
- $this->trace = debug_backtrace( false );
63
  $this->ignore( 1 ); # Self-awareness
64
 
65
  /**
@@ -121,14 +123,38 @@ class QM_Backtrace {
121
  $components = array();
122
 
123
  foreach ( $this->trace as $frame ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  try {
125
 
126
  if ( isset( $frame['class'] ) ) {
127
  if ( ! class_exists( $frame['class'], false ) ) {
128
- continue;
129
  }
130
  if ( ! method_exists( $frame['class'], $frame['function'] ) ) {
131
- continue;
132
  }
133
  $ref = new ReflectionMethod( $frame['class'], $frame['function'] );
134
  $file = $ref->getFileName();
@@ -138,31 +164,14 @@ class QM_Backtrace {
138
  } elseif ( isset( $frame['file'] ) ) {
139
  $file = $frame['file'];
140
  } else {
141
- continue;
142
  }
143
 
144
- $comp = QM_Util::get_file_component( $file );
145
- $components[ $comp->type ] = $comp;
146
 
147
- if ( 'plugin' === $comp->type ) {
148
- // If the component is a plugin then it can't be anything else,
149
- // so short-circuit and return early.
150
- return $comp;
151
- }
152
- // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
153
  } catch ( ReflectionException $e ) {
154
- # nothing
155
  }
156
- }
157
-
158
- foreach ( QM_Util::get_file_dirs() as $type => $dir ) {
159
- if ( isset( $components[ $type ] ) ) {
160
- return $components[ $type ];
161
- }
162
- }
163
-
164
- # This should not happen
165
-
166
  }
167
 
168
  public function get_trace() {
@@ -201,7 +210,7 @@ class QM_Backtrace {
201
  }
202
 
203
  public function ignore( $num ) {
204
- for ( $i = 0; $i < absint( $num ); $i++ ) {
205
  unset( $this->trace[ $i ] );
206
  }
207
  $this->trace = array_values( $this->trace );
55
  protected $calling_file = '';
56
 
57
  public function __construct( array $args = array() ) {
58
+ $this->trace = debug_backtrace( false );
59
+
60
  $args = array_merge( array(
61
  'ignore_current_filter' => true,
62
  'ignore_frames' => 0,
63
  ), $args );
64
+
65
  $this->ignore( 1 ); # Self-awareness
66
 
67
  /**
123
  $components = array();
124
 
125
  foreach ( $this->trace as $frame ) {
126
+ $component = self::get_frame_component( $frame );
127
+
128
+ if ( $component ) {
129
+ if ( 'plugin' === $component->type ) {
130
+ // If the component is a plugin then it can't be anything else,
131
+ // so short-circuit and return early.
132
+ return $component;
133
+ }
134
+
135
+ $components[ $component->type ] = $component;
136
+ }
137
+ }
138
+
139
+ foreach ( QM_Util::get_file_dirs() as $type => $dir ) {
140
+ if ( isset( $components[ $type ] ) ) {
141
+ return $components[ $type ];
142
+ }
143
+ }
144
+
145
+ # This should not happen
146
+
147
+ }
148
+
149
+ public static function get_frame_component( array $frame ) {
150
  try {
151
 
152
  if ( isset( $frame['class'] ) ) {
153
  if ( ! class_exists( $frame['class'], false ) ) {
154
+ return null;
155
  }
156
  if ( ! method_exists( $frame['class'], $frame['function'] ) ) {
157
+ return null;
158
  }
159
  $ref = new ReflectionMethod( $frame['class'], $frame['function'] );
160
  $file = $ref->getFileName();
164
  } elseif ( isset( $frame['file'] ) ) {
165
  $file = $frame['file'];
166
  } else {
167
+ return null;
168
  }
169
 
170
+ return QM_Util::get_file_component( $file );
 
171
 
 
 
 
 
 
 
172
  } catch ( ReflectionException $e ) {
173
+ return null;
174
  }
 
 
 
 
 
 
 
 
 
 
175
  }
176
 
177
  public function get_trace() {
210
  }
211
 
212
  public function ignore( $num ) {
213
+ for ( $i = 0; $i < $num; $i++ ) {
214
  unset( $this->trace[ $i ] );
215
  }
216
  $this->trace = array_values( $this->trace );
classes/Collector.php CHANGED
@@ -15,6 +15,11 @@ abstract class QM_Collector {
15
  );
16
  protected static $hide_qm = null;
17
 
 
 
 
 
 
18
  public function __construct() {}
19
 
20
  final public function id() {
@@ -90,6 +95,115 @@ abstract class QM_Collector {
90
  $this->id = $id;
91
  }
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  public static function format_user( WP_User $user_object ) {
94
  $user = get_object_vars( $user_object->data );
95
  unset(
@@ -128,5 +242,20 @@ abstract class QM_Collector {
128
  $this->timer = $timer;
129
  }
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  }
132
  }
15
  );
16
  protected static $hide_qm = null;
17
 
18
+ public $concerned_actions = array();
19
+ public $concerned_filters = array();
20
+ public $concerned_constants = array();
21
+ public $tracked_hooks = array();
22
+
23
  public function __construct() {}
24
 
25
  final public function id() {
95
  $this->id = $id;
96
  }
97
 
98
+ final public function process_concerns() {
99
+ global $wp_filter;
100
+
101
+ $tracked = array();
102
+ $id = $this->id;
103
+
104
+ /**
105
+ * Filters the concerned actions for the given panel.
106
+ *
107
+ * The dynamic portion of the hook name, `$id`, refers to the collector ID, which is typically the `$id`
108
+ * property of the collector class.
109
+ *
110
+ * @since 3.3.0
111
+ *
112
+ * @param string[] $actions Array of action names that this panel concerns itself with.
113
+ */
114
+ $concerned_actions = apply_filters( "qm/collect/concerned_actions/{$id}", $this->get_concerned_actions() );
115
+
116
+ /**
117
+ * Filters the concerned filters for the given panel.
118
+ *
119
+ * The dynamic portion of the hook name, `$id`, refers to the collector ID, which is typically the `$id`
120
+ * property of the collector class.
121
+ *
122
+ * @since 3.3.0
123
+ *
124
+ * @param string[] $filters Array of filter names that this panel concerns itself with.
125
+ */
126
+ $concerned_filters = apply_filters( "qm/collect/concerned_filters/{$id}", $this->get_concerned_filters() );
127
+
128
+ /**
129
+ * Filters the concerned options for the given panel.
130
+ *
131
+ * The dynamic portion of the hook name, `$id`, refers to the collector ID, which is typically the `$id`
132
+ * property of the collector class.
133
+ *
134
+ * @since 3.3.0
135
+ *
136
+ * @param string[] $options Array of option names that this panel concerns itself with.
137
+ */
138
+ $concerned_options = apply_filters( "qm/collect/concerned_options/{$id}", $this->get_concerned_options() );
139
+
140
+ /**
141
+ * Filters the concerned constants for the given panel.
142
+ *
143
+ * The dynamic portion of the hook name, `$id`, refers to the collector ID, which is typically the `$id`
144
+ * property of the collector class.
145
+ *
146
+ * @since 3.3.0
147
+ *
148
+ * @param string[] $constants Array of constant names that this panel concerns itself with.
149
+ */
150
+ $concerned_constants = apply_filters( "qm/collect/concerned_constants/{$id}", $this->get_concerned_constants() );
151
+
152
+ foreach ( $concerned_actions as $action ) {
153
+ if ( has_action( $action ) ) {
154
+ $this->concerned_actions[ $action ] = QM_Collector_Hooks::process_action( $action, $wp_filter, true, true );
155
+ }
156
+ $tracked[] = $action;
157
+ }
158
+
159
+ foreach ( $concerned_filters as $filter ) {
160
+ if ( has_filter( $filter ) ) {
161
+ $this->concerned_filters[ $filter ] = QM_Collector_Hooks::process_action( $filter, $wp_filter, true, true );
162
+ }
163
+ $tracked[] = $filter;
164
+ }
165
+
166
+ $option_filters = array(
167
+ // Should this include the pre_delete_ and pre_update_ filters too?
168
+ 'pre_option_%s',
169
+ 'default_option_%s',
170
+ 'option_%s',
171
+ 'pre_site_option_%s',
172
+ 'default_site_option_%s',
173
+ 'site_option_%s',
174
+ );
175
+
176
+ foreach ( $concerned_options as $option ) {
177
+ foreach ( $option_filters as $option_filter ) {
178
+ $filter = sprintf(
179
+ $option_filter,
180
+ $option
181
+ );
182
+ if ( has_filter( $filter ) ) {
183
+ $this->concerned_filters[ $filter ] = QM_Collector_Hooks::process_action( $filter, $wp_filter, true, true );
184
+ }
185
+ $tracked[] = $filter;
186
+ }
187
+ }
188
+
189
+ $this->concerned_actions = array_filter( $this->concerned_actions, array( $this, 'filter_concerns' ) );
190
+ $this->concerned_filters = array_filter( $this->concerned_filters, array( $this, 'filter_concerns' ) );
191
+
192
+ foreach ( $concerned_constants as $constant ) {
193
+ if ( defined( $constant ) ) {
194
+ $this->concerned_constants[ $constant ] = constant( $constant );
195
+ }
196
+ }
197
+
198
+ sort( $tracked );
199
+
200
+ $this->tracked_hooks = $tracked;
201
+ }
202
+
203
+ public function filter_concerns( $concerns ) {
204
+ return ! empty( $concerns['actions'] );
205
+ }
206
+
207
  public static function format_user( WP_User $user_object ) {
208
  $user = get_object_vars( $user_object->data );
209
  unset(
242
  $this->timer = $timer;
243
  }
244
 
245
+ public function get_concerned_actions() {
246
+ return array();
247
+ }
248
+
249
+ public function get_concerned_filters() {
250
+ return array();
251
+ }
252
+
253
+ public function get_concerned_options() {
254
+ return array();
255
+ }
256
+
257
+ public function get_concerned_constants() {
258
+ return array();
259
+ }
260
  }
261
  }
classes/Collectors.php CHANGED
@@ -52,6 +52,7 @@ class QM_Collectors implements IteratorAggregate {
52
  $timer->start();
53
 
54
  $collector->process();
 
55
 
56
  $collector->set_timer( $timer->stop() );
57
  }
52
  $timer->start();
53
 
54
  $collector->process();
55
+ $collector->process_concerns();
56
 
57
  $collector->set_timer( $timer->stop() );
58
  }
classes/Dispatcher.php CHANGED
@@ -12,7 +12,7 @@ abstract class QM_Dispatcher {
12
  $this->qm = $qm;
13
 
14
  if ( ! defined( 'QM_COOKIE' ) ) {
15
- define( 'QM_COOKIE', 'query_monitor_' . COOKIEHASH );
16
  }
17
 
18
  add_action( 'init', array( $this, 'init' ) );
12
  $this->qm = $qm;
13
 
14
  if ( ! defined( 'QM_COOKIE' ) ) {
15
+ define( 'QM_COOKIE', 'wp-query_monitor_' . COOKIEHASH );
16
  }
17
 
18
  add_action( 'init', array( $this, 'init' ) );
classes/Util.php CHANGED
@@ -416,6 +416,33 @@ class QM_Util {
416
  }, $fqn );
417
  }
418
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
419
  public static function sort( array &$array, $field ) {
420
  self::$sort_field = $field;
421
  usort( $array, array( __CLASS__, '_sort' ) );
416
  }, $fqn );
417
  }
418
 
419
+ /**
420
+ * Helper function for JSON encoding data and formatting it in a consistent and compatible manner.
421
+ *
422
+ * @param mixed $data The data to be JSON encoded.
423
+ * @return string The JSON encoded data.
424
+ */
425
+ public static function json_format( $data ) {
426
+ $json_options = JSON_PRETTY_PRINT;
427
+
428
+ if ( defined( 'JSON_UNESCAPED_SLASHES' ) ) {
429
+ // phpcs:ignore PHPCompatibility.Constants.NewConstants.json_unescaped_slashesFound
430
+ $json_options |= JSON_UNESCAPED_SLASHES;
431
+ }
432
+
433
+ $json = json_encode( $data, $json_options );
434
+
435
+ if ( ! defined( 'JSON_UNESCAPED_SLASHES' ) ) {
436
+ $json = wp_unslash( $json );
437
+ }
438
+
439
+ return $json;
440
+ }
441
+
442
+ public static function is_stringy( $data ) {
443
+ return ( is_string( $data ) || ( is_object( $data ) && method_exists( $data, '__toString' ) ) );
444
+ }
445
+
446
  public static function sort( array &$array, $field ) {
447
  self::$sort_field = $field;
448
  usort( $array, array( __CLASS__, '_sort' ) );
collectors/admin.php CHANGED
@@ -13,6 +13,29 @@ class QM_Collector_Admin extends QM_Collector {
13
  return __( 'Admin Screen', 'query-monitor' );
14
  }
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  public function process() {
17
 
18
  global $pagenow, $wp_list_table;
13
  return __( 'Admin Screen', 'query-monitor' );
14
  }
15
 
16
+ public function get_concerned_actions() {
17
+ $actions = array(
18
+ 'current_screen',
19
+ );
20
+
21
+ if ( ! empty( $this->data['list_table'] ) ) {
22
+ $actions[] = $this->data['list_table']['column_action'];
23
+ }
24
+
25
+ return $actions;
26
+ }
27
+
28
+ public function get_concerned_filters() {
29
+ $filters = array();
30
+
31
+ if ( ! empty( $this->data['list_table'] ) ) {
32
+ $filters[] = $this->data['list_table']['columns_filter'];
33
+ $filters[] = $this->data['list_table']['sortables_filter'];
34
+ }
35
+
36
+ return $filters;
37
+ }
38
+
39
  public function process() {
40
 
41
  global $pagenow, $wp_list_table;
collectors/assets.php CHANGED
@@ -5,88 +5,159 @@
5
  * @package query-monitor
6
  */
7
 
8
- class QM_Collector_Assets extends QM_Collector {
9
-
10
- public $id = 'assets';
11
 
12
  public function __construct() {
13
  parent::__construct();
14
  add_action( 'admin_print_footer_scripts', array( $this, 'action_print_footer_scripts' ) );
15
  add_action( 'wp_print_footer_scripts', array( $this, 'action_print_footer_scripts' ) );
16
- add_action( 'admin_head', array( $this, 'action_head' ), 999 );
17
- add_action( 'wp_head', array( $this, 'action_head' ), 999 );
18
- add_action( 'login_head', array( $this, 'action_head' ), 999 );
19
- add_action( 'embed_head', array( $this, 'action_head' ), 999 );
20
  }
21
 
22
- public function action_head() {
23
- global $wp_scripts, $wp_styles;
24
 
25
- $this->data['header']['styles'] = $wp_styles->done;
26
- $this->data['header']['scripts'] = $wp_scripts->done;
27
 
 
28
  }
29
 
30
  public function action_print_footer_scripts() {
31
- global $wp_scripts, $wp_styles;
32
-
33
  if ( empty( $this->data['header'] ) ) {
34
  return;
35
  }
36
 
37
- // @TODO remove the need for these raw scripts & styles to be collected
38
- $this->data['raw']['scripts'] = $wp_scripts;
39
- $this->data['raw']['styles'] = $wp_styles;
40
 
41
- $this->data['footer']['scripts'] = array_diff( $wp_scripts->done, $this->data['header']['scripts'] );
42
- $this->data['footer']['styles'] = array_diff( $wp_styles->done, $this->data['header']['styles'] );
43
 
44
  }
45
 
46
  public function process() {
47
- if ( ! isset( $this->data['raw'] ) ) {
48
  return;
49
  }
50
 
51
  $this->data['is_ssl'] = is_ssl();
 
 
 
 
 
 
 
 
 
 
 
52
 
53
- foreach ( array( 'scripts', 'styles' ) as $type ) {
54
- foreach ( array( 'header', 'footer' ) as $position ) {
55
- if ( empty( $this->data[ $position ][ $type ] ) ) {
56
- $this->data[ $position ][ $type ] = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
58
  }
59
- $raw = $this->data['raw'][ $type ];
60
- $broken = array_values( array_diff( $raw->queue, $raw->done ) );
61
- $missing = array_values( array_diff( $raw->queue, array_keys( $raw->registered ) ) );
62
 
63
  if ( ! empty( $broken ) ) {
64
- foreach ( $broken as $key => $handle ) {
65
- $item = $raw->query( $handle );
66
- if ( $item ) {
67
- $broken = array_merge( $broken, self::get_broken_dependencies( $item, $raw ) );
68
- } else {
69
- unset( $broken[ $key ] );
70
- $missing[] = $handle;
71
- }
72
- }
73
 
74
- if ( ! empty( $broken ) ) {
75
- $this->data['broken'][ $type ] = array_unique( $broken );
 
 
 
 
 
 
76
  }
77
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
- if ( ! empty( $missing ) ) {
80
- $this->data['missing'][ $type ] = array_unique( $missing );
81
- foreach ( $this->data['missing'][ $type ] as $handle ) {
82
- $raw->add( $handle, false );
83
- $key = array_search( $handle, $raw->done, true );
84
- if ( false !== $key ) {
85
- unset( $raw->done[ $key ] );
 
 
 
 
 
86
  }
87
  }
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
  }
 
 
 
 
 
 
 
 
 
 
90
  }
91
 
92
  protected static function get_broken_dependencies( _WP_Dependency $item, WP_Dependencies $dependencies ) {
@@ -122,15 +193,45 @@ class QM_Collector_Assets extends QM_Collector {
122
  return $dependents;
123
  }
124
 
125
- public function name() {
126
- return __( 'Scripts & Styles', 'query-monitor' );
127
- }
 
128
 
129
- }
 
 
130
 
131
- function register_qm_collector_assets( array $collectors, QueryMonitor $qm ) {
132
- $collectors['assets'] = new QM_Collector_Assets();
133
- return $collectors;
134
- }
 
 
135
 
136
- add_filter( 'qm/collectors', 'register_qm_collector_assets', 10, 2 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  * @package query-monitor
6
  */
7
 
8
+ abstract class QM_Collector_Assets extends QM_Collector {
 
 
9
 
10
  public function __construct() {
11
  parent::__construct();
12
  add_action( 'admin_print_footer_scripts', array( $this, 'action_print_footer_scripts' ) );
13
  add_action( 'wp_print_footer_scripts', array( $this, 'action_print_footer_scripts' ) );
14
+ add_action( 'admin_head', array( $this, 'action_head' ), 9999 );
15
+ add_action( 'wp_head', array( $this, 'action_head' ), 9999 );
16
+ add_action( 'login_head', array( $this, 'action_head' ), 9999 );
17
+ add_action( 'embed_head', array( $this, 'action_head' ), 9999 );
18
  }
19
 
20
+ abstract public function get_dependency_type();
 
21
 
22
+ public function action_head() {
23
+ $type = $this->get_dependency_type();
24
 
25
+ $this->data['header'] = $GLOBALS[ "wp_{$type}" ]->done;
26
  }
27
 
28
  public function action_print_footer_scripts() {
 
 
29
  if ( empty( $this->data['header'] ) ) {
30
  return;
31
  }
32
 
33
+ $type = $this->get_dependency_type();
 
 
34
 
35
+ $this->data['footer'] = array_diff( $GLOBALS[ "wp_{$type}" ]->done, $this->data['header'] );
 
36
 
37
  }
38
 
39
  public function process() {
40
+ if ( empty( $this->data['header'] ) && empty( $this->data['footer'] ) ) {
41
  return;
42
  }
43
 
44
  $this->data['is_ssl'] = is_ssl();
45
+ $this->data['host'] = wp_unslash( $_SERVER['HTTP_HOST'] );
46
+
47
+ $home_url = home_url();
48
+ $positions = array(
49
+ 'missing',
50
+ 'broken',
51
+ 'header',
52
+ 'footer',
53
+ );
54
+
55
+ $type = $this->get_dependency_type();
56
 
57
+ foreach ( array( 'header', 'footer' ) as $position ) {
58
+ if ( empty( $this->data[ $position ] ) ) {
59
+ $this->data[ $position ] = array();
60
+ }
61
+ }
62
+ $raw = $GLOBALS[ "wp_{$type}" ];
63
+ $broken = array_values( array_diff( $raw->queue, $raw->done ) );
64
+ $missing = array_values( array_diff( $raw->queue, array_keys( $raw->registered ) ) );
65
+
66
+ // A broken asset is one which has been deregistered without also being dequeued
67
+ if ( ! empty( $broken ) ) {
68
+ foreach ( $broken as $key => $handle ) {
69
+ $item = $raw->query( $handle );
70
+ if ( $item ) {
71
+ $broken = array_merge( $broken, self::get_broken_dependencies( $item, $raw ) );
72
+ } else {
73
+ unset( $broken[ $key ] );
74
+ $missing[] = $handle;
75
  }
76
  }
 
 
 
77
 
78
  if ( ! empty( $broken ) ) {
79
+ $this->data['broken'] = array_unique( $broken );
80
+ }
81
+ }
 
 
 
 
 
 
82
 
83
+ // A missing asset is one which has been enqueued with dependencies that don't exist
84
+ if ( ! empty( $missing ) ) {
85
+ $this->data['missing'] = array_unique( $missing );
86
+ foreach ( $this->data['missing'] as $handle ) {
87
+ $raw->add( $handle, false );
88
+ $key = array_search( $handle, $raw->done, true );
89
+ if ( false !== $key ) {
90
+ unset( $raw->done[ $key ] );
91
  }
92
  }
93
+ }
94
+
95
+ $all_dependencies = array();
96
+ $all_dependents = array();
97
+
98
+ foreach ( $positions as $position ) {
99
+ if ( empty( $this->data[ $position ] ) ) {
100
+ continue;
101
+ }
102
+
103
+ foreach ( $this->data[ $position ] as $handle ) {
104
+ $dependency = $raw->query( $handle );
105
+
106
+ if ( ! $dependency ) {
107
+ continue;
108
+ }
109
+
110
+ $all_dependencies = array_merge( $all_dependencies, $dependency->deps );
111
+ $dependents = $this->get_dependents( $dependency, $raw );
112
+ $all_dependents = array_merge( $all_dependents, $dependents );
113
+
114
+ list( $host, $source, $local ) = $this->get_dependency_data( $dependency, $raw );
115
+
116
+ if ( empty( $dependency->ver ) ) {
117
+ $ver = '';
118
+ } else {
119
+ $ver = $dependency->ver;
120
+ }
121
+
122
+ $warning = ! in_array( $handle, $raw->done, true );
123
 
124
+ if ( is_wp_error( $source ) ) {
125
+ $display = $source->get_error_message();
126
+ } else {
127
+ $display = ltrim( str_replace( $home_url, '', remove_query_arg( 'ver', $source ) ), '/' );
128
+ }
129
+
130
+ $dependencies = $dependency->deps;
131
+
132
+ foreach ( $dependencies as & $dep ) {
133
+ if ( ! $raw->query( $dep ) ) {
134
+ /* translators: %s: Script or style dependency name */
135
+ $dep = sprintf( __( '%s (missing)', 'query-monitor' ), $dep );
136
  }
137
  }
138
+
139
+ $this->data['assets'][ $position ][ $handle ] = array(
140
+ 'host' => $host,
141
+ 'source' => $source,
142
+ 'local' => $local,
143
+ 'ver' => $ver,
144
+ 'warning' => $warning,
145
+ 'display' => $display,
146
+ 'dependents' => $dependents,
147
+ 'dependencies' => $dependencies,
148
+ );
149
  }
150
  }
151
+
152
+ unset( $this->data[ $position ] );
153
+
154
+ $all_dependencies = array_unique( $all_dependencies );
155
+ sort( $all_dependencies );
156
+ $this->data['dependencies'] = $all_dependencies;
157
+
158
+ $all_dependents = array_unique( $all_dependents );
159
+ sort( $all_dependents );
160
+ $this->data['dependents'] = $all_dependents;
161
  }
162
 
163
  protected static function get_broken_dependencies( _WP_Dependency $item, WP_Dependencies $dependencies ) {
193
  return $dependents;
194
  }
195
 
196
+ public function get_dependency_data( _WP_Dependency $dependency, WP_Dependencies $dependencies ) {
197
+ $data = $this->get_data();
198
+ $loader = rtrim( $this->get_dependency_type(), 's' );
199
+ $src = $dependency->src;
200
 
201
+ if ( ! empty( $src ) && ! empty( $dependency->ver ) ) {
202
+ $src = add_query_arg( 'ver', $dependency->ver, $src );
203
+ }
204
 
205
+ /** This filter is documented in wp-includes/class.wp-scripts.php */
206
+ $source = apply_filters( "{$loader}_loader_src", $src, $dependency->handle );
207
+
208
+ $host = (string) parse_url( $source, PHP_URL_HOST );
209
+ $scheme = (string) parse_url( $source, PHP_URL_SCHEME );
210
+ $http_host = $data['host'];
211
 
212
+ if ( empty( $host ) && ! empty( $http_host ) ) {
213
+ $host = $http_host;
214
+ }
215
+
216
+ if ( $scheme && $data['is_ssl'] && ( 'https' !== $scheme ) ) {
217
+ $source = new WP_Error( 'qm_insecure_content', __( 'Insecure content', 'query-monitor' ), array(
218
+ 'src' => $source,
219
+ ) );
220
+ }
221
+
222
+ if ( is_wp_error( $source ) ) {
223
+ $error_data = $source->get_error_data();
224
+ if ( $error_data && isset( $error_data['src'] ) ) {
225
+ $host = (string) parse_url( $error_data['src'], PHP_URL_HOST );
226
+ }
227
+ } elseif ( empty( $source ) ) {
228
+ $source = '';
229
+ $host = '';
230
+ }
231
+
232
+ $local = ( $http_host === $host );
233
+
234
+ return array( $host, $source, $local );
235
+ }
236
+
237
+ }
collectors/assets_scripts.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Enqueued scripts collector.
4
+ *
5
+ * @package query-monitor
6
+ */
7
+
8
+ class QM_Collector_Assets_Scripts extends QM_Collector_Assets {
9
+
10
+ public $id = 'assets_scripts';
11
+
12
+ public function get_dependency_type() {
13
+ return 'scripts';
14
+ }
15
+
16
+ public function get_concerned_actions() {
17
+ return array(
18
+ 'admin_print_footer_scripts',
19
+ 'wp_print_footer_scripts',
20
+ );
21
+ }
22
+
23
+ public function get_concerned_filters() {
24
+ return array(
25
+ 'print_scripts_array',
26
+ 'script_loader_src',
27
+ 'script_loader_tag',
28
+ );
29
+ }
30
+
31
+ public function name() {
32
+ return __( 'Scripts', 'query-monitor' );
33
+ }
34
+
35
+ }
36
+
37
+ function register_qm_collector_assets_scripts( array $collectors, QueryMonitor $qm ) {
38
+ $collectors['assets_scripts'] = new QM_Collector_Assets_Scripts();
39
+ return $collectors;
40
+ }
41
+
42
+ add_filter( 'qm/collectors', 'register_qm_collector_assets_scripts', 10, 2 );
collectors/assets_styles.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Enqueued styles collector.
4
+ *
5
+ * @package query-monitor
6
+ */
7
+
8
+ class QM_Collector_Assets_Styles extends QM_Collector_Assets {
9
+
10
+ public $id = 'assets_styles';
11
+
12
+ public function get_dependency_type() {
13
+ return 'styles';
14
+ }
15
+
16
+ public function get_concerned_filters() {
17
+ return array(
18
+ 'print_styles_array',
19
+ 'style_loader_src',
20
+ 'style_loader_tag',
21
+ );
22
+ }
23
+
24
+ public function name() {
25
+ return __( 'Styles', 'query-monitor' );
26
+ }
27
+
28
+ }
29
+
30
+ function register_qm_collector_assets_styles( array $collectors, QueryMonitor $qm ) {
31
+ $collectors['assets_styles'] = new QM_Collector_Assets_Styles();
32
+ return $collectors;
33
+ }
34
+
35
+ add_filter( 'qm/collectors', 'register_qm_collector_assets_styles', 10, 2 );
collectors/block_editor.php CHANGED
@@ -8,12 +8,54 @@
8
  class QM_Collector_Block_Editor extends QM_Collector {
9
 
10
  public $id = 'block_editor';
11
- protected static $block_type_registry = null;
 
 
12
 
13
  public function name() {
14
  return __( 'Blocks', 'query-monitor' );
15
  }
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  public function process() {
18
  $this->data['block_editor_enabled'] = self::wp_block_editor_enabled();
19
 
@@ -21,14 +63,15 @@ class QM_Collector_Block_Editor extends QM_Collector {
21
  return;
22
  }
23
 
24
- $this->data['post_has_blocks'] = self::wp_has_blocks( get_post()->post_content );
25
- $this->data['post_blocks'] = self::wp_parse_blocks( get_post()->post_content );
 
 
26
  $this->data['all_dynamic_blocks'] = self::wp_get_dynamic_block_names();
27
  $this->data['total_blocks'] = 0;
 
28
 
29
  if ( $this->data['post_has_blocks'] ) {
30
- self::$block_type_registry = WP_Block_Type_Registry::get_instance();
31
-
32
  $this->data['post_blocks'] = array_values( array_filter( array_map( array( $this, 'process_block' ), $this->data['post_blocks'] ) ) );
33
  }
34
  }
@@ -36,12 +79,13 @@ class QM_Collector_Block_Editor extends QM_Collector {
36
  protected function process_block( array $block ) {
37
  // Remove empty blocks caused by two consecutive line breaks in content
38
  if ( ! $block['blockName'] && ! trim( $block['innerHTML'] ) ) {
 
39
  return null;
40
  }
41
 
42
  $this->data['total_blocks']++;
43
 
44
- $block_type = self::$block_type_registry->get_registered( $block['blockName'] );
45
  $dynamic = false;
46
  $callback = null;
47
 
@@ -52,10 +96,17 @@ class QM_Collector_Block_Editor extends QM_Collector {
52
  ) );
53
  }
54
 
 
 
55
  $block['dynamic'] = $dynamic;
56
  $block['callback'] = $callback;
57
  $block['size'] = strlen( $block['innerHTML'] );
58
 
 
 
 
 
 
59
  if ( ! empty( $block['innerBlocks'] ) ) {
60
  $block['innerBlocks'] = array_values( array_filter( array_map( array( $this, 'process_block' ), $block['innerBlocks'] ) ) );
61
  }
8
  class QM_Collector_Block_Editor extends QM_Collector {
9
 
10
  public $id = 'block_editor';
11
+
12
+ protected $block_timing = array();
13
+ protected $block_timer = null;
14
 
15
  public function name() {
16
  return __( 'Blocks', 'query-monitor' );
17
  }
18
 
19
+ public function __construct() {
20
+ parent::__construct();
21
+
22
+ add_filter( 'pre_render_block', array( $this, 'filter_pre_render_block' ), 9999, 2 );
23
+ add_filter( 'render_block_data', array( $this, 'filter_render_block_data' ), -9999 );
24
+ add_filter( 'render_block', array( $this, 'filter_render_block' ), 9999, 2 );
25
+ }
26
+
27
+ public function get_concerned_filters() {
28
+ return array(
29
+ 'allowed_block_types',
30
+ 'pre_render_block',
31
+ 'render_block_data',
32
+ 'render_block',
33
+ );
34
+ }
35
+
36
+ public function filter_pre_render_block( $pre_render, array $block ) {
37
+ if ( null !== $pre_render ) {
38
+ $this->block_timing[] = false;
39
+ }
40
+
41
+ return $pre_render;
42
+ }
43
+
44
+ public function filter_render_block_data( array $block ) {
45
+ $this->block_timer = new QM_Timer();
46
+ $this->block_timer->start();
47
+
48
+ return $block;
49
+ }
50
+
51
+ public function filter_render_block( $block_content, array $block ) {
52
+ if ( isset( $this->block_timer ) ) {
53
+ $this->block_timing[] = $this->block_timer->stop();
54
+ }
55
+
56
+ return $block_content;
57
+ }
58
+
59
  public function process() {
60
  $this->data['block_editor_enabled'] = self::wp_block_editor_enabled();
61
 
63
  return;
64
  }
65
 
66
+ $post = get_post( get_queried_object_id() );
67
+
68
+ $this->data['post_has_blocks'] = self::wp_has_blocks( $post->post_content );
69
+ $this->data['post_blocks'] = self::wp_parse_blocks( $post->post_content );
70
  $this->data['all_dynamic_blocks'] = self::wp_get_dynamic_block_names();
71
  $this->data['total_blocks'] = 0;
72
+ $this->data['has_block_timing'] = false;
73
 
74
  if ( $this->data['post_has_blocks'] ) {
 
 
75
  $this->data['post_blocks'] = array_values( array_filter( array_map( array( $this, 'process_block' ), $this->data['post_blocks'] ) ) );
76
  }
77
  }
79
  protected function process_block( array $block ) {
80
  // Remove empty blocks caused by two consecutive line breaks in content
81
  if ( ! $block['blockName'] && ! trim( $block['innerHTML'] ) ) {
82
+ array_shift( $this->block_timing );
83
  return null;
84
  }
85
 
86
  $this->data['total_blocks']++;
87
 
88
+ $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
89
  $dynamic = false;
90
  $callback = null;
91
 
96
  ) );
97
  }
98
 
99
+ $timing = array_shift( $this->block_timing );
100
+
101
  $block['dynamic'] = $dynamic;
102
  $block['callback'] = $callback;
103
  $block['size'] = strlen( $block['innerHTML'] );
104
 
105
+ if ( $timing ) {
106
+ $block['timing'] = $timing->get_time();
107
+ $this->data['has_block_timing'] = true;
108
+ }
109
+
110
  if ( ! empty( $block['innerBlocks'] ) ) {
111
  $block['innerBlocks'] = array_values( array_filter( array_map( array( $this, 'process_block' ), $block['innerBlocks'] ) ) );
112
  }
collectors/cache.php CHANGED
@@ -16,7 +16,7 @@ class QM_Collector_Cache extends QM_Collector {
16
  public function process() {
17
  global $wp_object_cache;
18
 
19
- $this->data['ext_object_cache'] = (bool) wp_using_ext_object_cache();
20
  $this->data['cache_hit_percentage'] = 0;
21
 
22
  if ( is_object( $wp_object_cache ) ) {
@@ -73,16 +73,26 @@ class QM_Collector_Cache extends QM_Collector {
73
  $this->data['display_hit_rate_warning'] = ( 100 === $this->data['cache_hit_percentage'] );
74
 
75
  if ( function_exists( 'extension_loaded' ) ) {
76
- $this->data['extensions'] = array_map( 'extension_loaded', array(
77
- 'APC' => 'APC',
78
  'APCu' => 'APCu',
79
  'Memcache' => 'Memcache',
80
  'Memcached' => 'Memcached',
81
  'Redis' => 'Redis',
 
 
 
82
  'Zend OPcache' => 'Zend OPcache',
83
  ) );
84
  } else {
85
- $this->data['extensions'] = array();
 
 
 
 
 
 
 
 
86
  }
87
  }
88
 
16
  public function process() {
17
  global $wp_object_cache;
18
 
19
+ $this->data['has_object_cache'] = (bool) wp_using_ext_object_cache();
20
  $this->data['cache_hit_percentage'] = 0;
21
 
22
  if ( is_object( $wp_object_cache ) ) {
73
  $this->data['display_hit_rate_warning'] = ( 100 === $this->data['cache_hit_percentage'] );
74
 
75
  if ( function_exists( 'extension_loaded' ) ) {
76
+ $this->data['object_cache_extensions'] = array_map( 'extension_loaded', array(
 
77
  'APCu' => 'APCu',
78
  'Memcache' => 'Memcache',
79
  'Memcached' => 'Memcached',
80
  'Redis' => 'Redis',
81
+ ) );
82
+ $this->data['opcode_cache_extensions'] = array_map( 'extension_loaded', array(
83
+ 'APC' => 'APC',
84
  'Zend OPcache' => 'Zend OPcache',
85
  ) );
86
  } else {
87
+ $this->data['object_cache_extensions'] = array();
88
+ $this->data['opcode_cache_extensions'] = array();
89
+ }
90
+
91
+ $this->data['has_opcode_cache'] = false;
92
+
93
+ if ( array_filter( $this->data['opcode_cache_extensions'] ) && function_exists( 'opcache_get_status' ) ) {
94
+ $status = opcache_get_status();
95
+ $this->data['has_opcode_cache'] = $status && ! empty( $status['opcache_enabled'] );
96
  }
97
  }
98
 
collectors/caps.php CHANGED
@@ -22,6 +22,36 @@ class QM_Collector_Caps extends QM_Collector {
22
  add_filter( 'map_meta_cap', array( $this, 'filter_map_meta_cap' ), 9999, 4 );
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  public function tear_down() {
26
  remove_filter( 'user_has_cap', array( $this, 'filter_user_has_cap' ), 9999 );
27
  remove_filter( 'map_meta_cap', array( $this, 'filter_map_meta_cap' ), 9999 );
22
  add_filter( 'map_meta_cap', array( $this, 'filter_map_meta_cap' ), 9999, 4 );
23
  }
24
 
25
+ public function get_concerned_actions() {
26
+ return array(
27
+ 'wp_roles_init',
28
+ );
29
+ }
30
+
31
+ public function get_concerned_filters() {
32
+ return array(
33
+ 'map_meta_cap',
34
+ 'role_has_cap',
35
+ 'user_has_cap',
36
+ );
37
+ }
38
+
39
+ public function get_concerned_options() {
40
+ $blog_prefix = $GLOBALS['wpdb']->get_blog_prefix();
41
+
42
+ return array(
43
+ "{$blog_prefix}user_roles",
44
+ );
45
+ }
46
+
47
+ public function get_concerned_constants() {
48
+ return array(
49
+ 'ALLOW_UNFILTERED_UPLOADS',
50
+ 'DISALLOW_FILE_EDIT',
51
+ 'DISALLOW_UNFILTERED_HTML',
52
+ );
53
+ }
54
+
55
  public function tear_down() {
56
  remove_filter( 'user_has_cap', array( $this, 'filter_user_has_cap' ), 9999 );
57
  remove_filter( 'map_meta_cap', array( $this, 'filter_map_meta_cap' ), 9999 );
collectors/hooks.php CHANGED
@@ -26,7 +26,7 @@ class QM_Collector_Hooks extends QM_Collector {
26
  $components = array();
27
 
28
  if ( has_filter( 'all' ) ) {
29
- $hooks['all'] = self::process_action( 'all', $wp_filter, self::$hide_qm, self::$hide_core );
30
  }
31
 
32
  if ( defined( 'QM_SHOW_ALL_HOOKS' ) && QM_SHOW_ALL_HOOKS ) {
@@ -39,10 +39,11 @@ class QM_Collector_Hooks extends QM_Collector {
39
 
40
  foreach ( $hook_names as $name ) {
41
 
42
- $hooks[ $name ] = self::process_action( $name, $wp_filter, self::$hide_qm, self::$hide_core );
 
43
 
44
- $all_parts = array_merge( $all_parts, $hooks[ $name ]['parts'] );
45
- $components = array_merge( $components, $hooks[ $name ]['components'] );
46
 
47
  }
48
 
@@ -50,16 +51,8 @@ class QM_Collector_Hooks extends QM_Collector {
50
  $this->data['parts'] = array_unique( array_filter( $all_parts ) );
51
  $this->data['components'] = array_unique( array_filter( $components ) );
52
 
53
- }
54
-
55
- public function post_process() {
56
- $admin = QM_Collectors::get( 'response' );
57
-
58
- if ( is_admin() && $admin ) {
59
- $this->data['screen'] = $admin->data['base'];
60
- } else {
61
- $this->data['screen'] = '';
62
- }
63
  }
64
 
65
  public static function process_action( $name, array $wp_filter, $hide_qm = false, $hide_core = false ) {
26
  $components = array();
27
 
28
  if ( has_filter( 'all' ) ) {
29
+ $hooks[] = self::process_action( 'all', $wp_filter, self::$hide_qm, self::$hide_core );
30
  }
31
 
32
  if ( defined( 'QM_SHOW_ALL_HOOKS' ) && QM_SHOW_ALL_HOOKS ) {
39
 
40
  foreach ( $hook_names as $name ) {
41
 
42
+ $hook = self::process_action( $name, $wp_filter, self::$hide_qm, self::$hide_core );
43
+ $hooks[] = $hook;
44
 
45
+ $all_parts = array_merge( $all_parts, $hook['parts'] );
46
+ $components = array_merge( $components, $hook['components'] );
47
 
48
  }
49
 
51
  $this->data['parts'] = array_unique( array_filter( $all_parts ) );
52
  $this->data['components'] = array_unique( array_filter( $components ) );
53
 
54
+ usort( $this->data['parts'], 'strcasecmp' );
55
+ usort( $this->data['components'], 'strcasecmp' );
 
 
 
 
 
 
 
 
56
  }
57
 
58
  public static function process_action( $name, array $wp_filter, $hide_qm = false, $hide_core = false ) {
collectors/http.php CHANGED
@@ -12,24 +12,82 @@ class QM_Collector_HTTP extends QM_Collector {
12
  private $info = null;
13
 
14
  public function name() {
15
- return __( 'HTTP API Requests', 'query-monitor' );
16
  }
17
 
18
  public function __construct() {
19
 
20
  parent::__construct();
21
 
22
- add_filter( 'http_request_args', array( $this, 'filter_http_request_args' ), 99, 2 );
23
- add_filter( 'pre_http_request', array( $this, 'filter_pre_http_request' ), 99, 3 );
24
- add_action( 'http_api_debug', array( $this, 'action_http_api_debug' ), 99, 5 );
25
 
26
- add_action( 'requests-curl.before_request', array( $this, 'action_curl_before_request' ), 99 );
27
- add_action( 'requests-curl.after_request', array( $this, 'action_curl_after_request' ), 99, 2 );
28
- add_action( 'requests-fsockopen.before_request', array( $this, 'action_fsockopen_before_request' ), 99 );
29
- add_action( 'requests-fsockopen.after_request', array( $this, 'action_fsockopen_after_request' ), 99, 2 );
30
 
31
  }
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  /**
34
  * Filter the arguments used in an HTTP request.
35
  *
@@ -160,26 +218,6 @@ class QM_Collector_HTTP extends QM_Collector {
160
  }
161
 
162
  public function process() {
163
-
164
- foreach ( array(
165
- 'WP_PROXY_HOST',
166
- 'WP_PROXY_PORT',
167
- 'WP_PROXY_USERNAME',
168
- 'WP_PROXY_PASSWORD',
169
- 'WP_PROXY_BYPASS_HOSTS',
170
- 'WP_HTTP_BLOCK_EXTERNAL',
171
- 'WP_ACCESSIBLE_HOSTS',
172
- ) as $var ) {
173
- if ( defined( $var ) && constant( $var ) ) {
174
- $val = constant( $var );
175
- if ( true === $val ) {
176
- # @TODO this transformation should happen in the output, not the collector
177
- $val = 'true';
178
- }
179
- $this->data['vars'][ $var ] = $val;
180
- }
181
- }
182
-
183
  $this->data['ltime'] = 0;
184
 
185
  if ( ! isset( $this->data['http'] ) ) {
12
  private $info = null;
13
 
14
  public function name() {
15
+ return __( 'HTTP API Calls', 'query-monitor' );
16
  }
17
 
18
  public function __construct() {
19
 
20
  parent::__construct();
21
 
22
+ add_filter( 'http_request_args', array( $this, 'filter_http_request_args' ), 9999, 2 );
23
+ add_filter( 'pre_http_request', array( $this, 'filter_pre_http_request' ), 9999, 3 );
24
+ add_action( 'http_api_debug', array( $this, 'action_http_api_debug' ), 9999, 5 );
25
 
26
+ add_action( 'requests-curl.before_request', array( $this, 'action_curl_before_request' ), 9999 );
27
+ add_action( 'requests-curl.after_request', array( $this, 'action_curl_after_request' ), 9999, 2 );
28
+ add_action( 'requests-fsockopen.before_request', array( $this, 'action_fsockopen_before_request' ), 9999 );
29
+ add_action( 'requests-fsockopen.after_request', array( $this, 'action_fsockopen_after_request' ), 9999, 2 );
30
 
31
  }
32
 
33
+ public function get_concerned_actions() {
34
+ $actions = array(
35
+ 'http_api_curl',
36
+ 'requests-multiple.request.complete',
37
+ 'requests-request.progress',
38
+ 'requests-transport.internal.parse_error',
39
+ 'requests-transport.internal.parse_response',
40
+ );
41
+ $transports = array(
42
+ 'requests',
43
+ 'curl',
44
+ 'fsockopen',
45
+ );
46
+
47
+ foreach ( $transports as $transport ) {
48
+ $actions[] = "requests-{$transport}.after_headers";
49
+ $actions[] = "requests-{$transport}.after_multi_exec";
50
+ $actions[] = "requests-{$transport}.after_request";
51
+ $actions[] = "requests-{$transport}.after_send";
52
+ $actions[] = "requests-{$transport}.before_multi_add";
53
+ $actions[] = "requests-{$transport}.before_multi_exec";
54
+ $actions[] = "requests-{$transport}.before_parse";
55
+ $actions[] = "requests-{$transport}.before_redirect";
56
+ $actions[] = "requests-{$transport}.before_redirect_check";
57
+ $actions[] = "requests-{$transport}.before_request";
58
+ $actions[] = "requests-{$transport}.before_send";
59
+ $actions[] = "requests-{$transport}.remote_host_path";
60
+ $actions[] = "requests-{$transport}.remote_socket";
61
+ }
62
+
63
+ return $actions;
64
+ }
65
+
66
+ public function get_concerned_filters() {
67
+ return array(
68
+ 'block_local_requests',
69
+ 'http_request_args',
70
+ 'http_response',
71
+ 'https_local_ssl_verify',
72
+ 'https_ssl_verify',
73
+ 'pre_http_request',
74
+ 'use_curl_transport',
75
+ 'use_streams_transport',
76
+ );
77
+ }
78
+
79
+ public function get_concerned_constants() {
80
+ return array(
81
+ 'WP_PROXY_HOST',
82
+ 'WP_PROXY_PORT',
83
+ 'WP_PROXY_USERNAME',
84
+ 'WP_PROXY_PASSWORD',
85
+ 'WP_PROXY_BYPASS_HOSTS',
86
+ 'WP_HTTP_BLOCK_EXTERNAL',
87
+ 'WP_ACCESSIBLE_HOSTS',
88
+ );
89
+ }
90
+
91
  /**
92
  * Filter the arguments used in an HTTP request.
93
  *
218
  }
219
 
220
  public function process() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  $this->data['ltime'] = 0;
222
 
223
  if ( ! isset( $this->data['http'] ) ) {
collectors/languages.php CHANGED
@@ -17,12 +17,54 @@ class QM_Collector_Languages extends QM_Collector {
17
 
18
  parent::__construct();
19
 
20
- add_filter( 'override_load_textdomain', array( $this, 'log_file_load' ), 99, 3 );
 
21
 
22
  }
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  public function process() {
25
- $this->data['locale'] = get_locale();
 
26
  ksort( $this->data['languages'] );
27
  }
28
 
@@ -78,14 +120,42 @@ class QM_Collector_Languages extends QM_Collector {
78
  $this->data['languages'][ $domain ][] = array(
79
  'caller' => $caller,
80
  'domain' => $domain,
81
- 'mofile' => $mofile,
82
  'found' => file_exists( $mofile ) ? filesize( $mofile ) : false,
 
 
83
  );
84
 
85
  return $override;
86
 
87
  }
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  }
90
 
91
  # Load early to catch early errors
17
 
18
  parent::__construct();
19
 
20
+ add_filter( 'override_load_textdomain', array( $this, 'log_file_load' ), 9999, 3 );
21
+ add_filter( 'load_script_translation_file', array( $this, 'log_script_file_load' ), 9999, 3 );
22
 
23
  }
24
 
25
+ public function get_concerned_actions() {
26
+ return array(
27
+ 'load_textdomain',
28
+ 'unload_textdomain',
29
+ );
30
+ }
31
+
32
+ public function get_concerned_filters() {
33
+ return array(
34
+ 'determine_locale',
35
+ 'gettext',
36
+ 'gettext_with_context',
37
+ 'load_script_textdomain_relative_path',
38
+ 'load_script_translation_file',
39
+ 'load_script_translations',
40
+ 'load_textdomain_mofile',
41
+ 'locale',
42
+ 'ngettext',
43
+ 'ngettext_with_context',
44
+ 'override_load_textdomain',
45
+ 'override_unload_textdomain',
46
+ 'plugin_locale',
47
+ 'pre_determine_locale',
48
+ 'pre_load_script_translations',
49
+ 'theme_locale',
50
+ );
51
+ }
52
+
53
+ public function get_concerned_options() {
54
+ return array(
55
+ 'WPLANG',
56
+ );
57
+ }
58
+
59
+ public function get_concerned_constants() {
60
+ return array(
61
+ 'WPLANG',
62
+ );
63
+ }
64
+
65
  public function process() {
66
+ $this->data['locale'] = get_locale();
67
+ $this->data['user_locale'] = function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
68
  ksort( $this->data['languages'] );
69
  }
70
 
120
  $this->data['languages'][ $domain ][] = array(
121
  'caller' => $caller,
122
  'domain' => $domain,
123
+ 'file' => $mofile,
124
  'found' => file_exists( $mofile ) ? filesize( $mofile ) : false,
125
+ 'handle' => null,
126
+ 'type' => 'gettext',
127
  );
128
 
129
  return $override;
130
 
131
  }
132
 
133
+ /**
134
+ * Filters the file path for loading script translations for the given script handle and textdomain.
135
+ *
136
+ * @param string|false $file Path to the translation file to load. False if there isn't one.
137
+ * @param string $handle Name of the script to register a translation domain to.
138
+ * @param string $domain The textdomain.
139
+ *
140
+ * @return string|false Path to the translation file to load. False if there isn't one.
141
+ */
142
+ public function log_script_file_load( $file, $handle, $domain ) {
143
+ $trace = new QM_Backtrace();
144
+ $filtered = $trace->get_filtered_trace();
145
+ $caller = $filtered[0];
146
+
147
+ $this->data['languages'][ $domain ][] = array(
148
+ 'caller' => $caller,
149
+ 'domain' => $domain,
150
+ 'file' => $file,
151
+ 'found' => ( $file && file_exists( $file ) ) ? filesize( $file ) : false,
152
+ 'handle' => $handle,
153
+ 'type' => 'jed',
154
+ );
155
+
156
+ return $file;
157
+ }
158
+
159
  }
160
 
161
  # Load early to catch early errors
collectors/logger.php CHANGED
@@ -78,31 +78,37 @@ class QM_Collector_Logger extends QM_Collector {
78
 
79
  if ( is_wp_error( $message ) ) {
80
  $message = sprintf(
81
- '%s (%s)',
82
  $message->get_error_message(),
83
  $message->get_error_code()
84
  );
85
  }
86
 
87
  if ( $message instanceof Exception ) {
88
- $message = $message->getMessage();
 
 
 
 
89
  }
90
 
91
  $this->data['logs'][] = array(
92
- 'message' => $this->interpolate( $message, $context ),
93
  'context' => $context,
94
  'trace' => $trace,
95
  'level' => $level,
96
  );
97
  }
98
 
99
- protected function interpolate( $message, array $context = array() ) {
100
  // build a replacement array with braces around the context keys
101
  $replace = array();
102
 
103
  foreach ( $context as $key => $val ) {
104
  // check that the value can be casted to string
105
- if ( is_scalar( $val ) || ( is_object( $val ) && method_exists( $val, '__toString' ) ) ) {
 
 
106
  $replace[ "{{$key}}" ] = $val;
107
  }
108
  }
78
 
79
  if ( is_wp_error( $message ) ) {
80
  $message = sprintf(
81
+ 'WP_Error: %s (%s)',
82
  $message->get_error_message(),
83
  $message->get_error_code()
84
  );
85
  }
86
 
87
  if ( $message instanceof Exception ) {
88
+ $message = get_class( $message ) . ': ' . $message->getMessage();
89
+ }
90
+
91
+ if ( ! QM_Util::is_stringy( $message ) ) {
92
+ $message = QM_Util::json_format( $message );
93
  }
94
 
95
  $this->data['logs'][] = array(
96
+ 'message' => self::interpolate( $message, $context ),
97
  'context' => $context,
98
  'trace' => $trace,
99
  'level' => $level,
100
  );
101
  }
102
 
103
+ protected static function interpolate( $message, array $context = array() ) {
104
  // build a replacement array with braces around the context keys
105
  $replace = array();
106
 
107
  foreach ( $context as $key => $val ) {
108
  // check that the value can be casted to string
109
+ if ( is_bool( $val ) ) {
110
+ $replace[ "{{$key}}" ] = ( $val ? 'true' : 'false' );
111
+ } elseif ( is_scalar( $val ) || QM_Util::is_stringy( $val ) ) {
112
  $replace[ "{{$key}}" ] = $val;
113
  }
114
  }
collectors/php_errors.php CHANGED
@@ -180,8 +180,7 @@ class QM_Collector_PHP_Errors extends QM_Collector {
180
 
181
  }
182
 
183
- public function tear_down() {
184
- parent::tear_down();
185
  ini_set( 'display_errors', $this->display_errors );
186
  restore_error_handler();
187
  }
180
 
181
  }
182
 
183
+ public function post_process() {
 
184
  ini_set( 'display_errors', $this->display_errors );
185
  restore_error_handler();
186
  }
collectors/redirects.php CHANGED
@@ -15,7 +15,7 @@ class QM_Collector_Redirects extends QM_Collector {
15
 
16
  public function __construct() {
17
  parent::__construct();
18
- add_filter( 'wp_redirect', array( $this, 'filter_wp_redirect' ), 999, 2 );
19
  }
20
 
21
  public function filter_wp_redirect( $location, $status ) {
15
 
16
  public function __construct() {
17
  parent::__construct();
18
+ add_filter( 'wp_redirect', array( $this, 'filter_wp_redirect' ), 9999, 2 );
19
  }
20
 
21
  public function filter_wp_redirect( $location, $status ) {
collectors/request.php CHANGED
@@ -13,6 +13,78 @@ class QM_Collector_Request extends QM_Collector {
13
  return __( 'Request', 'query-monitor' );
14
  }
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  public function process() {
17
 
18
  global $wp, $wp_query, $current_blog, $current_site, $wp_rewrite;
13
  return __( 'Request', 'query-monitor' );
14
  }
15
 
16
+ public function get_concerned_actions() {
17
+ return array(
18
+ # Rewrites
19
+ 'generate_rewrite_rules',
20
+
21
+ # Everything else
22
+ 'parse_query',
23
+ 'parse_request',
24
+ 'parse_tax_query',
25
+ 'pre_get_posts',
26
+ 'the_post',
27
+ 'wp',
28
+ );
29
+ }
30
+
31
+ public function get_concerned_filters() {
32
+ global $wp_rewrite;
33
+
34
+ $filters = array(
35
+ # Rewrite rules
36
+ 'author_rewrite_rules',
37
+ 'category_rewrite_rules',
38
+ 'comments_rewrite_rules',
39
+ 'date_rewrite_rules',
40
+ 'page_rewrite_rules',
41
+ 'post_format_rewrite_rules',
42
+ 'post_rewrite_rules',
43
+ 'root_rewrite_rules',
44
+ 'search_rewrite_rules',
45
+ 'tag_rewrite_rules',
46
+
47
+ # More rewrite stuff
48
+ 'iis7_url_rewrite_rules',
49
+ 'mod_rewrite_rules',
50
+ 'rewrite_rules',
51
+ 'rewrite_rules_array',
52
+
53
+ # Everything else
54
+ 'do_parse_request',
55
+ 'pre_handle_404',
56
+ 'query_string',
57
+ 'query_vars',
58
+ 'redirect_canonical',
59
+ 'request',
60
+ );
61
+
62
+ foreach ( $wp_rewrite->extra_permastructs as $permastructname => $struct ) {
63
+ $filters[] = sprintf(
64
+ '%s_rewrite_rules',
65
+ $permastructname
66
+ );
67
+ }
68
+
69
+ return $filters;
70
+ }
71
+
72
+ public function get_concerned_options() {
73
+ return array(
74
+ 'home',
75
+ 'permalink_structure',
76
+ 'rewrite_rules',
77
+ 'siteurl',
78
+ );
79
+ }
80
+
81
+ public function get_concerned_constants() {
82
+ return array(
83
+ 'WP_HOME',
84
+ 'WP_SITEURL',
85
+ );
86
+ }
87
+
88
  public function process() {
89
 
90
  global $wp, $wp_query, $current_blog, $current_site, $wp_rewrite;
collectors/theme.php CHANGED
@@ -16,12 +16,43 @@ class QM_Collector_Theme extends QM_Collector {
16
 
17
  public function __construct() {
18
  parent::__construct();
19
- add_filter( 'body_class', array( $this, 'filter_body_class' ), 999 );
20
- add_filter( 'template_include', array( $this, 'filter_template_include' ), 999 );
21
- add_filter( 'timber/output', array( $this, 'filter_timber_output' ), 999, 3 );
22
  add_action( 'template_redirect', array( $this, 'action_template_redirect' ) );
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  public static function get_query_template_names() {
26
  return array(
27
  'embed' => 'is_embed',
@@ -46,6 +77,7 @@ class QM_Collector_Theme extends QM_Collector {
46
 
47
  // https://core.trac.wordpress.org/ticket/14310
48
  public function action_template_redirect() {
 
49
 
50
  foreach ( self::get_query_template_names() as $template => $conditional ) {
51
 
@@ -58,9 +90,9 @@ class QM_Collector_Theme extends QM_Collector {
58
 
59
  if ( function_exists( $conditional ) && function_exists( $get_template ) && call_user_func( $conditional ) ) {
60
  $filter = str_replace( '_', '', $template );
61
- add_filter( "{$filter}_template_hierarchy", array( $this, 'filter_template_hierarchy' ), 999 );
62
  call_user_func( $get_template );
63
- remove_filter( "{$filter}_template_hierarchy", array( $this, 'filter_template_hierarchy' ), 999 );
64
  }
65
  }
66
 
16
 
17
  public function __construct() {
18
  parent::__construct();
19
+ add_filter( 'body_class', array( $this, 'filter_body_class' ), 9999 );
20
+ add_filter( 'timber/output', array( $this, 'filter_timber_output' ), 9999, 3 );
 
21
  add_action( 'template_redirect', array( $this, 'action_template_redirect' ) );
22
  }
23
 
24
+ public function get_concerned_actions() {
25
+ return array(
26
+ 'template_redirect',
27
+ );
28
+ }
29
+
30
+ public function get_concerned_filters() {
31
+ $filters = array(
32
+ 'stylesheet',
33
+ 'stylesheet_directory',
34
+ 'template',
35
+ 'template_directory',
36
+ 'template_include',
37
+ );
38
+
39
+ foreach ( self::get_query_template_names() as $template => $conditional ) {
40
+ // @TODO this isn't correct for post type archives
41
+ $filter = str_replace( '_', '', $template );
42
+ $filters[] = "{$filter}_template_hierarchy";
43
+ $filters[] = "{$filter}_template";
44
+ }
45
+
46
+ return $filters;
47
+ }
48
+
49
+ public function get_concerned_options() {
50
+ return array(
51
+ 'stylesheet',
52
+ 'template',
53
+ );
54
+ }
55
+
56
  public static function get_query_template_names() {
57
  return array(
58
  'embed' => 'is_embed',
77
 
78
  // https://core.trac.wordpress.org/ticket/14310
79
  public function action_template_redirect() {
80
+ add_filter( 'template_include', array( $this, 'filter_template_include' ), PHP_INT_MAX );
81
 
82
  foreach ( self::get_query_template_names() as $template => $conditional ) {
83
 
90
 
91
  if ( function_exists( $conditional ) && function_exists( $get_template ) && call_user_func( $conditional ) ) {
92
  $filter = str_replace( '_', '', $template );
93
+ add_filter( "{$filter}_template_hierarchy", array( $this, 'filter_template_hierarchy' ), PHP_INT_MAX );
94
  call_user_func( $get_template );
95
+ remove_filter( "{$filter}_template_hierarchy", array( $this, 'filter_template_hierarchy' ), PHP_INT_MAX );
96
  }
97
  }
98
 
composer.json CHANGED
@@ -22,16 +22,16 @@
22
  "name": "danieltj27/dark-mode",
23
  "version": "3.2",
24
  "source": {
25
- "type" : "git",
26
- "url" : "git://github.com/danieltj27/Dark-Mode.git",
27
- "reference" : "3.2"
28
- },
29
- "dist": {
30
- "url": "https://github.com/danieltj27/Dark-Mode/archive/31e1407ef72af69bcd5d94cc3c502163547d4898.zip",
31
- "type": "zip"
32
- }
33
  }
34
- }
35
  ],
36
  "require": {
37
  "php": ">=5.3",
@@ -42,7 +42,12 @@
42
  "squizlabs/php_codesniffer": "^3.2",
43
  "phpcompatibility/phpcompatibility-wp": "^2.0",
44
  "danieltj27/dark-mode": "3.2",
45
- "wp-coding-standards/wpcs": "^1.2",
46
  "phpunit/phpunit": "^5"
 
 
 
 
 
47
  }
48
  }
22
  "name": "danieltj27/dark-mode",
23
  "version": "3.2",
24
  "source": {
25
+ "type" : "git",
26
+ "url" : "git://github.com/danieltj27/Dark-Mode.git",
27
+ "reference" : "3.2"
28
+ },
29
+ "dist": {
30
+ "url": "https://github.com/danieltj27/Dark-Mode/archive/31e1407ef72af69bcd5d94cc3c502163547d4898.zip",
31
+ "type": "zip"
32
+ }
33
  }
34
+ }
35
  ],
36
  "require": {
37
  "php": ">=5.3",
42
  "squizlabs/php_codesniffer": "^3.2",
43
  "phpcompatibility/phpcompatibility-wp": "^2.0",
44
  "danieltj27/dark-mode": "3.2",
45
+ "wp-coding-standards/wpcs": "^2",
46
  "phpunit/phpunit": "^5"
47
+ },
48
+ "scripts": {
49
+ "test": [
50
+ "bin/test.sh"
51
+ ]
52
  }
53
  }
dispatchers/Html.php CHANGED
@@ -105,10 +105,10 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
105
  return;
106
  }
107
 
108
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ), -999 );
109
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ), -999 );
110
- add_action( 'login_enqueue_scripts', array( $this, 'enqueue_assets' ), -999 );
111
- add_action( 'enqueue_embed_scripts', array( $this, 'enqueue_assets' ), -999 );
112
 
113
  add_action( 'gp_head', array( $this, 'manually_print_assets' ), 11 );
114
 
@@ -239,6 +239,17 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
239
  */
240
  $this->panel_menu = apply_filters( 'qm/output/panel_menus', $this->admin_bar_menu );
241
 
 
 
 
 
 
 
 
 
 
 
 
242
  $class = array(
243
  'qm-no-js',
244
  );
@@ -252,10 +263,6 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
252
  $class[] = 'qm-peek';
253
  }
254
 
255
- if ( wp_is_mobile() ) {
256
- $class[] = 'qm-touch';
257
- }
258
-
259
  $json = array(
260
  'menu' => $this->js_admin_bar_menu(),
261
  'ajax_errors' => array(), # @TODO move this into the php_errors collector
@@ -265,8 +272,9 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
265
  echo 'var qm = ' . json_encode( $json ) . ';' . "\n\n";
266
  echo '</script>' . "\n\n";
267
 
268
- echo '<div id="query-monitor" class="' . implode( ' ', array_map( 'esc_attr', $class ) ) . '" dir="ltr">';
269
- echo '<div id="qm-title">';
 
270
  echo '<h1 class="qm-title-heading">' . esc_html__( 'Query Monitor', 'query-monitor' ) . '</h1>';
271
  echo '<div class="qm-title-heading">';
272
  echo '<select>';
@@ -283,12 +291,22 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
283
  esc_attr( $menu['href'] ),
284
  esc_html( $menu['title'] )
285
  );
 
 
 
 
 
 
 
 
 
286
  }
287
  echo '</select>';
288
 
289
  echo '</div>';
290
- echo '<div class="qm-title-button"><button class="qm-button-container-settings"><span class="screen-reader-text">' . esc_html__( 'Settings', 'query-monitor' ) . '</span><span class="dashicons dashicons-admin-generic" aria-hidden="true"></span></button></div>';
291
- echo '<div class="qm-title-button"><button class="qm-button-container-close"><span class="screen-reader-text">' . esc_html__( 'Close Panel', 'query-monitor' ) . '</span><span class="dashicons dashicons-no-alt" aria-hidden="true"></span></button></div>';
 
292
  echo '</div>'; // #qm-title
293
 
294
  echo '<div id="qm-wrapper">';
@@ -302,12 +320,8 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
302
  esc_html__( 'Overview', 'query-monitor' )
303
  );
304
 
305
- foreach ( $this->panel_menu as $menu ) {
306
- printf(
307
- '<li><button data-qm-href="%1$s">%2$s</button></li>',
308
- esc_attr( $menu['href'] ),
309
- esc_html( $menu['title'] )
310
- );
311
  }
312
 
313
  echo '</ul>';
@@ -317,6 +331,24 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
317
 
318
  }
319
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  protected function after_output() {
321
 
322
  $state = self::user_verified() ? 'on' : 'off';
@@ -433,7 +465,7 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
433
 
434
  echo '</div>'; // #qm-panels
435
  echo '</div>'; // #qm-wrapper
436
- echo '</div>'; // #qm
437
 
438
  echo '<script type="text/javascript">' . "\n\n";
439
  ?>
105
  return;
106
  }
107
 
108
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ), -9999 );
109
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ), -9999 );
110
+ add_action( 'login_enqueue_scripts', array( $this, 'enqueue_assets' ), -9999 );
111
+ add_action( 'enqueue_embed_scripts', array( $this, 'enqueue_assets' ), -9999 );
112
 
113
  add_action( 'gp_head', array( $this, 'manually_print_assets' ), 11 );
114
 
239
  */
240
  $this->panel_menu = apply_filters( 'qm/output/panel_menus', $this->admin_bar_menu );
241
 
242
+ foreach ( $this->outputters as $output_id => $output ) {
243
+ $collector = $output->get_collector();
244
+
245
+ if ( ( ! empty( $collector->concerned_filters ) || ! empty( $collector->concerned_actions ) ) && isset( $this->panel_menu[ 'qm-' . $output_id ] ) ) {
246
+ $this->panel_menu[ 'qm-' . $output_id ]['children'][ 'qm-' . $output_id . '-concerned_hooks' ] = array(
247
+ 'href' => esc_attr( '#' . $collector->id() . '-concerned_hooks' ),
248
+ 'title' => '└ ' . __( 'Hooks in Use', 'query-monitor' ),
249
+ );
250
+ }
251
+ }
252
+
253
  $class = array(
254
  'qm-no-js',
255
  );
263
  $class[] = 'qm-peek';
264
  }
265
 
 
 
 
 
266
  $json = array(
267
  'menu' => $this->js_admin_bar_menu(),
268
  'ajax_errors' => array(), # @TODO move this into the php_errors collector
272
  echo 'var qm = ' . json_encode( $json ) . ';' . "\n\n";
273
  echo '</script>' . "\n\n";
274
 
275
+ echo '<div id="query-monitor-main" class="' . implode( ' ', array_map( 'esc_attr', $class ) ) . '" dir="ltr">';
276
+ echo '<div id="qm-side-resizer" class="qm-resizer"></div>';
277
+ echo '<div id="qm-title" class="qm-resizer">';
278
  echo '<h1 class="qm-title-heading">' . esc_html__( 'Query Monitor', 'query-monitor' ) . '</h1>';
279
  echo '<div class="qm-title-heading">';
280
  echo '<select>';
291
  esc_attr( $menu['href'] ),
292
  esc_html( $menu['title'] )
293
  );
294
+ if ( ! empty( $menu['children'] ) ) {
295
+ foreach ( $menu['children'] as $child ) {
296
+ printf(
297
+ '<option value="%1$s">%2$s</option>',
298
+ esc_attr( $child['href'] ),
299
+ esc_html( $child['title'] )
300
+ );
301
+ }
302
+ }
303
  }
304
  echo '</select>';
305
 
306
  echo '</div>';
307
+ echo '<div class="qm-title-button"><button class="qm-button-container-settings" aria-label="' . esc_attr__( 'Settings', 'query-monitor' ) . '"><span class="dashicons dashicons-admin-generic" aria-hidden="true"></span></button></div>';
308
+ echo '<div class="qm-title-button"><button class="qm-button-container-position" aria-label="' . esc_html__( 'Toggle panel position', 'query-monitor' ) . '"><span class="dashicons dashicons-image-rotate-left" aria-hidden="true"></span></button></div>';
309
+ echo '<div class="qm-title-button"><button class="qm-button-container-close" aria-label="' . esc_attr__( 'Close Panel', 'query-monitor' ) . '"><span class="dashicons dashicons-no-alt" aria-hidden="true"></span></button></div>';
310
  echo '</div>'; // #qm-title
311
 
312
  echo '<div id="qm-wrapper">';
320
  esc_html__( 'Overview', 'query-monitor' )
321
  );
322
 
323
+ foreach ( $this->panel_menu as $id => $menu ) {
324
+ $this->do_panel_menu_item( $id, $menu );
 
 
 
 
325
  }
326
 
327
  echo '</ul>';
331
 
332
  }
333
 
334
+ protected function do_panel_menu_item( $id, array $menu ) {
335
+ printf(
336
+ '<li><button data-qm-href="%1$s">%2$s</button>',
337
+ esc_attr( $menu['href'] ),
338
+ esc_html( $menu['title'] )
339
+ );
340
+
341
+ if ( ! empty( $menu['children'] ) ) {
342
+ echo '<ul>';
343
+ foreach ( $menu['children'] as $child_id => $child ) {
344
+ $this->do_panel_menu_item( $child_id, $child );
345
+ }
346
+ echo '</ul>';
347
+ }
348
+
349
+ echo '</li>';
350
+ }
351
+
352
  protected function after_output() {
353
 
354
  $state = self::user_verified() ? 'on' : 'off';
465
 
466
  echo '</div>'; // #qm-panels
467
  echo '</div>'; // #qm-wrapper
468
+ echo '</div>'; // #query-monitor-main
469
 
470
  echo '<script type="text/javascript">' . "\n\n";
471
  ?>
dispatchers/Redirect.php CHANGED
@@ -12,7 +12,7 @@ class QM_Dispatcher_Redirect extends QM_Dispatcher {
12
  public function __construct( QM_Plugin $qm ) {
13
  parent::__construct( $qm );
14
 
15
- add_filter( 'wp_redirect', array( $this, 'filter_wp_redirect' ), 999, 2 );
16
 
17
  }
18
 
12
  public function __construct( QM_Plugin $qm ) {
13
  parent::__construct( $qm );
14
 
15
+ add_filter( 'wp_redirect', array( $this, 'filter_wp_redirect' ), 9999, 2 );
16
 
17
  }
18
 
dispatchers/WP_Die.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Dispatcher for output that gets added to `wp_die()` calls.
4
+ *
5
+ * @package query-monitor
6
+ */
7
+
8
+ class QM_Dispatcher_WP_Die extends QM_Dispatcher {
9
+
10
+ public $id = 'wp_die';
11
+ public $trace = null;
12
+
13
+ protected $outputters = array();
14
+
15
+ public function __construct( QM_Plugin $qm ) {
16
+ add_action( 'shutdown', array( $this, 'dispatch' ), 0 );
17
+
18
+ add_filter( 'wp_die_handler', array( $this, 'filter_wp_die_handler' ) );
19
+
20
+ parent::__construct( $qm );
21
+ }
22
+
23
+ public function filter_wp_die_handler( $handler ) {
24
+ $this->trace = new QM_Backtrace( array(
25
+ 'ignore_frames' => 1,
26
+ ) );
27
+
28
+ return $handler;
29
+ }
30
+
31
+ public function dispatch() {
32
+ if ( ! $this->should_dispatch() ) {
33
+ return;
34
+ }
35
+
36
+ require_once $this->qm->plugin_path( 'output/Html.php' );
37
+
38
+ $switched_locale = function_exists( 'switch_to_locale' ) && switch_to_locale( get_user_locale() );
39
+ $stack = array();
40
+ $filtered_trace = $this->trace->get_display_trace();
41
+
42
+ // Ignore the `apply_filters('wp_die_handler')` stack frame:
43
+ array_pop( $filtered_trace );
44
+
45
+ foreach ( $filtered_trace as $i => $item ) {
46
+ $stack[] = QM_Output_Html::output_filename( $item['display'], $item['file'], $item['line'] );
47
+ }
48
+
49
+ if ( isset( $filtered_trace[ $i - 1 ] ) ) {
50
+ $culprit = $filtered_trace[ $i - 1 ];
51
+ } else {
52
+ $culprit = $filtered_trace[ $i ];
53
+ }
54
+
55
+ $component = QM_Backtrace::get_frame_component( $culprit );
56
+
57
+ ?>
58
+ <style>
59
+ #query-monitor {
60
+ position: absolute;
61
+ margin: 4em 0 1em;
62
+ border: 1px solid #aaa;
63
+ background: #fff;
64
+ width: 700px;
65
+ }
66
+
67
+ #query-monitor h2 {
68
+ font-size: 12px;
69
+ font-weight: normal;
70
+ padding: 5px;
71
+ background: #f3f3f3;
72
+ margin: 0;
73
+ border-bottom: 1px solid #aaa;
74
+ }
75
+
76
+ #query-monitor ol,
77
+ #query-monitor p {
78
+ font-size: 12px;
79
+ padding: 0;
80
+ margin: 1em;
81
+ }
82
+
83
+ #query-monitor ol {
84
+ padding: 0 0 1em 2em;
85
+ }
86
+
87
+ #query-monitor li {
88
+ margin: 0 0 0.5em;
89
+ }
90
+
91
+ #query-monitor .qm-info {
92
+ color: #777;
93
+ }
94
+ </style>
95
+ <?php
96
+
97
+ echo '<div id="query-monitor">';
98
+
99
+ echo '<h2>' . esc_html__( 'Query Monitor', 'query-monitor' ) . '</h2>';
100
+
101
+ if ( $component ) {
102
+ echo '<p>';
103
+ $name = ( 'plugin' === $component->type ) ? $component->context : $component->name;
104
+ printf(
105
+ /* translators: %s: Plugin or theme name */
106
+ esc_html__( 'The message above was triggered by %s.', 'query-monitor' ),
107
+ '<b>' . esc_html( $name ) . '</b>'
108
+ );
109
+ echo '</p>';
110
+ }
111
+
112
+ echo '<p>' . esc_html__( 'Call stack:', 'query-monitor' ) . '</p>';
113
+ echo '<ol>';
114
+ echo '<li>' . implode( '</li><li>', $stack ) . '</li>'; // WPCS: XSS ok.
115
+ echo '</ol>';
116
+
117
+ echo '</div>';
118
+
119
+ if ( $switched_locale ) {
120
+ restore_previous_locale();
121
+ }
122
+ }
123
+
124
+ public function is_active() {
125
+ if ( ! $this->trace ) {
126
+ return false;
127
+ }
128
+
129
+ if ( ! $this->user_can_view() ) {
130
+ return false;
131
+ }
132
+
133
+ return true;
134
+ }
135
+
136
+ }
137
+
138
+ function register_qm_dispatcher_wp_die( array $dispatchers, QM_Plugin $qm ) {
139
+ $dispatchers['wp_die'] = new QM_Dispatcher_WP_Die( $qm );
140
+ return $dispatchers;
141
+ }
142
+
143
+ add_filter( 'qm/dispatchers', 'register_qm_dispatcher_wp_die', 10, 2 );
output/Html.php CHANGED
@@ -9,9 +9,12 @@ abstract class QM_Output_Html extends QM_Output {
9
 
10
  protected static $file_link_format = null;
11
 
 
 
 
12
  public function admin_menu( array $menu ) {
13
 
14
- $menu[] = $this->menu( array(
15
  'title' => esc_html( $this->collector->name() ),
16
  ) );
17
  return $menu;
@@ -34,6 +37,9 @@ abstract class QM_Output_Html extends QM_Output {
34
  $name = $this->collector->name();
35
  }
36
 
 
 
 
37
  printf(
38
  '<div class="qm" id="%1$s" role="group" aria-labelledby="%1$s-caption" tabindex="-1">',
39
  esc_attr( $id )
@@ -51,6 +57,8 @@ abstract class QM_Output_Html extends QM_Output {
51
  protected function after_tabular_output() {
52
  echo '</table>';
53
  echo '</div>';
 
 
54
  }
55
 
56
  protected function before_non_tabular_output( $id = null, $name = null ) {
@@ -61,6 +69,9 @@ abstract class QM_Output_Html extends QM_Output {
61
  $name = $this->collector->name();
62
  }
63
 
 
 
 
64
  printf(
65
  '<div class="qm qm-non-tabular" id="%1$s" role="group" aria-labelledby="%1$s-caption" tabindex="-1">',
66
  esc_attr( $id )
@@ -78,6 +89,62 @@ abstract class QM_Output_Html extends QM_Output {
78
  protected function after_non_tabular_output() {
79
  echo '</div>';
80
  echo '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
 
83
  protected function before_debug_bar_output( $id = null, $name = null ) {
@@ -118,17 +185,17 @@ abstract class QM_Output_Html extends QM_Output {
118
 
119
  public static function output_inner( $vars ) {
120
 
121
- echo '<table class="qm-inner">';
122
 
123
  foreach ( $vars as $key => $value ) {
124
  echo '<tr>';
125
  echo '<td>' . esc_html( $key ) . '</td>';
126
  if ( is_array( $value ) ) {
127
- echo '<td class="qm-has-inner">';
128
  self::output_inner( $value );
129
  echo '</td>';
130
  } elseif ( is_object( $value ) ) {
131
- echo '<td class="qm-has-inner">';
132
  self::output_inner( get_object_vars( $value ) );
133
  echo '</td>';
134
  } elseif ( is_bool( $value ) ) {
@@ -226,7 +293,7 @@ abstract class QM_Output_Html extends QM_Output {
226
  }
227
 
228
  $out .= '</span>';
229
- $out .= '<button class="qm-sort-controls">';
230
  $out .= '<span class="qm-sort-arrow" aria-hidden="true"></span>';
231
  $out .= '</button>';
232
  $out .= '</label>';
@@ -239,7 +306,7 @@ abstract class QM_Output_Html extends QM_Output {
239
  * @return string Markup for the column sorter controls.
240
  */
241
  protected static function build_toggler() {
242
- $out = '<button class="qm-toggle" data-on="+" data-off="-" aria-expanded="false"><span aria-hidden="true">+</span><span class="screen-reader-text">' . esc_html__( ' Toggle button', 'query-monitor' ) . '</span></button>';
243
  return $out;
244
  }
245
 
9
 
10
  protected static $file_link_format = null;
11
 
12
+ protected $current_id = null;
13
+ protected $current_name = null;
14
+
15
  public function admin_menu( array $menu ) {
16
 
17
+ $menu[ $this->collector->id() ] = $this->menu( array(
18
  'title' => esc_html( $this->collector->name() ),
19
  ) );
20
  return $menu;
37
  $name = $this->collector->name();
38
  }
39
 
40
+ $this->current_id = $id;
41
+ $this->current_name = $name;
42
+
43
  printf(
44
  '<div class="qm" id="%1$s" role="group" aria-labelledby="%1$s-caption" tabindex="-1">',
45
  esc_attr( $id )
57
  protected function after_tabular_output() {
58
  echo '</table>';
59
  echo '</div>';
60
+
61
+ $this->output_concerns();
62
  }
63
 
64
  protected function before_non_tabular_output( $id = null, $name = null ) {
69
  $name = $this->collector->name();
70
  }
71
 
72
+ $this->current_id = $id;
73
+ $this->current_name = $name;
74
+
75
  printf(
76
  '<div class="qm qm-non-tabular" id="%1$s" role="group" aria-labelledby="%1$s-caption" tabindex="-1">',
77
  esc_attr( $id )
89
  protected function after_non_tabular_output() {
90
  echo '</div>';
91
  echo '</div>';
92
+
93
+ $this->output_concerns();
94
+ }
95
+
96
+ protected function output_concerns() {
97
+ $concerns = array(
98
+ 'concerned_actions' => array(
99
+ __( 'Related Hooks with Actions Attached', 'query-monitor' ),
100
+ __( 'Action', 'query-monitor' ),
101
+ ),
102
+ 'concerned_filters' => array(
103
+ __( 'Related Hooks with Filters Attached', 'query-monitor' ),
104
+ __( 'Filter', 'query-monitor' ),
105
+ ),
106
+ );
107
+
108
+ if ( empty( $this->collector->concerned_actions ) && empty( $this->collector->concerned_filters ) ) {
109
+ return;
110
+ }
111
+
112
+ printf(
113
+ '<div class="qm qm-concerns" id="%1$s" role="group" aria-labelledby="%1$s" tabindex="-1">',
114
+ esc_attr( $this->current_id . '-concerned_hooks' )
115
+ );
116
+
117
+ echo '<table>';
118
+
119
+ printf(
120
+ '<caption><h2 id="%1$s-caption">%2$s</h2></caption>',
121
+ esc_attr( $this->current_id . '-concerned_hooks' ),
122
+ esc_html__( 'Related Hooks with Filters or Actions Attached', 'query-monitor' )
123
+ );
124
+
125
+ echo '<thead>';
126
+ echo '<tr>';
127
+ echo '<th scope="col">' . esc_html__( 'Hook', 'query-monitor' ) . '</th>';
128
+ echo '<th scope="col">' . esc_html__( 'Priority', 'query-monitor' ) . '</th>';
129
+ echo '<th scope="col">' . esc_html__( 'Callback', 'query-monitor' ) . '</th>';
130
+ echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
131
+ echo '</tr>';
132
+ echo '</thead>';
133
+
134
+ echo '<tbody>';
135
+
136
+ foreach ( $concerns as $key => $labels ) {
137
+ if ( empty( $this->collector->$key ) ) {
138
+ continue;
139
+ }
140
+
141
+ QM_Output_Html_Hooks::output_hook_table( $this->collector->$key );
142
+ }
143
+
144
+ echo '</tbody>';
145
+ echo '</table>';
146
+
147
+ echo '</div>';
148
  }
149
 
150
  protected function before_debug_bar_output( $id = null, $name = null ) {
185
 
186
  public static function output_inner( $vars ) {
187
 
188
+ echo '<table>';
189
 
190
  foreach ( $vars as $key => $value ) {
191
  echo '<tr>';
192
  echo '<td>' . esc_html( $key ) . '</td>';
193
  if ( is_array( $value ) ) {
194
+ echo '<td>';
195
  self::output_inner( $value );
196
  echo '</td>';
197
  } elseif ( is_object( $value ) ) {
198
+ echo '<td>';
199
  self::output_inner( get_object_vars( $value ) );
200
  echo '</td>';
201
  } elseif ( is_bool( $value ) ) {
293
  }
294
 
295
  $out .= '</span>';
296
+ $out .= '<button class="qm-sort-controls" aria-label="' . esc_attr__( 'Sort data by this column', 'query-monitor' ) . '">';
297
  $out .= '<span class="qm-sort-arrow" aria-hidden="true"></span>';
298
  $out .= '</button>';
299
  $out .= '</label>';
306
  * @return string Markup for the column sorter controls.
307
  */
308
  protected static function build_toggler() {
309
+ $out = '<button class="qm-toggle" data-on="+" data-off="-" aria-expanded="false" aria-label="' . esc_attr__( 'Toggle more information', 'query-monitor' ) . '"><span aria-hidden="true">+</span></button>';
310
  return $out;
311
  }
312
 
output/html/assets.php CHANGED
@@ -5,7 +5,7 @@
5
  * @package query-monitor
6
  */
7
 
8
- class QM_Output_Html_Assets extends QM_Output_Html {
9
 
10
  public function __construct( QM_Collector $collector ) {
11
  parent::__construct( $collector );
@@ -13,269 +13,146 @@ class QM_Output_Html_Assets extends QM_Output_Html {
13
  add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
14
  }
15
 
 
 
16
  public function output() {
17
 
18
  $data = $this->collector->get_data();
19
 
20
- if ( empty( $data['raw'] ) ) {
21
  return;
22
  }
23
 
24
  $position_labels = array(
 
25
  'missing' => __( 'Missing', 'query-monitor' ),
26
  'broken' => __( 'Missing Dependencies', 'query-monitor' ),
27
  'header' => __( 'Header', 'query-monitor' ),
28
  'footer' => __( 'Footer', 'query-monitor' ),
29
  );
30
 
31
- $type_labels = array(
32
- 'scripts' => array(
33
- /* translators: %s: Total number of enqueued scripts */
34
- 'total' => _x( 'Total: %s', 'Enqueued scripts', 'query-monitor' ),
35
- 'plural' => __( 'Scripts', 'query-monitor' ),
36
- ),
37
- 'styles' => array(
38
- /* translators: %s: Total number of enqueued styles */
39
- 'total' => _x( 'Total: %s', 'Enqueued styles', 'query-monitor' ),
40
- 'plural' => __( 'Styles', 'query-monitor' ),
41
- ),
42
- );
43
-
44
- foreach ( $type_labels as $type => $type_label ) {
45
-
46
- $types = array();
47
- $all_dependencies = array();
48
- $all_dependents = array();
49
-
50
- foreach ( $position_labels as $position => $label ) {
51
- if ( ! empty( $data[ $position ][ $type ] ) ) {
52
- $types[ $position ] = $label;
53
-
54
- $handles = $data[ $position ][ $type ];
55
-
56
- foreach ( $handles as $handle ) {
57
- $dependency = $data['raw'][ $type ]->query( $handle );
58
-
59
- if ( ! $dependency ) {
60
- continue;
61
- }
62
 
63
- $dependencies = $dependency->deps;
64
- $all_dependencies = array_merge( $all_dependencies, $dependencies );
65
-
66
- $dependents = $this->collector->get_dependents( $dependency, $data['raw'][ $type ] );
67
- $all_dependents = array_merge( $all_dependents, $dependents );
68
- }
69
- }
70
- }
71
- $all_dependencies = array_unique( $all_dependencies );
72
- sort( $all_dependencies );
73
-
74
- $all_dependents = array_unique( $all_dependents );
75
- sort( $all_dependents );
76
 
77
- $hosts = array(
78
- __( 'Other', 'query-monitor' ),
79
- );
80
 
81
- $panel_id = sprintf(
82
- '%s-%s',
83
- $this->collector->id(),
84
- $type
85
- );
86
 
87
- $this->before_tabular_output( $panel_id, $type_label['plural'] );
88
-
89
- echo '<thead>';
90
- echo '<tr>';
91
- echo '<th scope="col">' . esc_html__( 'Position', 'query-monitor' ) . '</th>';
92
- echo '<th scope="col">' . esc_html__( 'Handle', 'query-monitor' ) . '</th>';
93
- echo '<th scope="col" class="qm-filterable-column">';
94
- $args = array(
95
- 'prepend' => array(
96
- // phpcs:ignore WordPress.VIP.ValidatedSanitizedInput
97
- 'local' => wp_unslash( $_SERVER['HTTP_HOST'] ),
98
- ),
99
- );
100
- echo $this->build_filter( $type . '-host', $hosts, __( 'Host', 'query-monitor' ), $args ); // WPCS: XSS ok.
101
- echo '</th>';
102
- echo '<th scope="col">' . esc_html__( 'Source', 'query-monitor' ) . '</th>';
103
- echo '<th scope="col" class="qm-filterable-column">';
104
- echo $this->build_filter( $type . '-dependencies', $all_dependencies, __( 'Dependencies', 'query-monitor' ) ); // WPCS: XSS ok.
105
- echo '</th>';
106
- echo '<th scope="col" class="qm-filterable-column">';
107
- echo $this->build_filter( $type . '-dependents', $all_dependents, __( 'Dependents', 'query-monitor' ) ); // WPCS: XSS ok.
108
- echo '</th>';
109
- echo '<th scope="col">' . esc_html__( 'Version', 'query-monitor' ) . '</th>';
110
- echo '</tr>';
111
- echo '</thead>';
112
-
113
- echo '<tbody>';
114
-
115
- $total = 0;
116
-
117
- foreach ( $position_labels as $position => $label ) {
118
- if ( ! empty( $data[ $position ][ $type ] ) ) {
119
- $this->dependency_rows( $data[ $position ][ $type ], $data['raw'][ $type ], $label, $type );
120
- $total += count( $data[ $position ][ $type ] );
121
  }
 
122
  }
123
-
124
- echo '</tbody>';
125
-
126
- echo '<tfoot>';
127
-
128
- echo '<tr>';
129
- printf(
130
- '<td colspan="7">%1$s</td>',
131
- sprintf(
132
- esc_html( $type_label['total'] ),
133
- '<span class="qm-items-number">' . esc_html( number_format_i18n( $total ) ) . '</span>'
134
- )
135
- );
136
- echo '</tr>';
137
- echo '</tfoot>';
138
-
139
- $this->after_tabular_output();
140
  }
141
 
142
- }
143
-
144
- protected function dependency_rows( array $handles, WP_Dependencies $dependencies, $label, $type ) {
145
- foreach ( $handles as $handle ) {
146
-
147
- $dependency = $dependencies->query( $handle );
148
-
149
- list( $src, $host, $source, $local ) = $this->get_dependency_data( $dependency, $dependencies, $type );
150
-
151
- $dependencies_list = $dependency->deps;
152
- // $dependencies_list[] = $handle;
153
- $dependencies_list = implode( ' ', $dependencies_list );
154
-
155
- $dependents_list = $this->collector->get_dependents( $dependency, $dependencies );
156
- // $dependents_list[] = $handle;
157
- $dependents_list = implode( ' ', $dependents_list );
158
 
159
- $qm_host = ( $local ) ? 'local' : __( 'Other', 'query-monitor' );
160
 
161
- if ( in_array( $handle, $dependencies->done, true ) ) {
162
- echo '<tr data-qm-subject="' . esc_attr( $type . '-' . $handle ) . '" data-qm-' . esc_attr( $type ) . '-host="' . esc_attr( $qm_host ) . '" data-qm-' . esc_attr( $type ) . '-dependents="' . esc_attr( $dependents_list ) . '" data-qm-' . esc_attr( $type ) . '-dependencies="' . esc_attr( $dependencies_list ) . '">';
163
- echo '<td class="qm-nowrap">' . esc_html( $label ) . '</td>';
164
- } else {
165
- echo '<tr data-qm-subject="' . esc_attr( $type . '-' . $handle ) . '" data-qm-' . esc_attr( $type ) . '-host="' . esc_attr( $qm_host ) . '" data-qm-' . esc_attr( $type ) . '-dependents="' . esc_attr( $dependents_list ) . '" data-qm-' . esc_attr( $type ) . '-dependencies="' . esc_attr( $dependencies_list ) . '" class="qm-warn">';
166
- echo '<td class="qm-nowrap"><span class="dashicons dashicons-warning" aria-hidden="true"></span>' . esc_html( $label ) . '</td>';
167
- }
168
-
169
- $this->dependency_row( $dependency, $dependencies, $type );
 
170
 
171
- echo '</tr>';
172
- }
173
  }
174
 
175
- protected function get_dependency_data( _WP_Dependency $dependency, WP_Dependencies $dependencies, $type ) {
176
  $data = $this->collector->get_data();
177
 
178
- $loader = rtrim( $type, 's' );
179
- $src = $dependency->src;
180
-
181
- if ( ! empty( $src ) && ! empty( $dependency->ver ) ) {
182
- $src = add_query_arg( 'ver', $dependency->ver, $src );
183
- }
184
-
185
- /**
186
- * Filter the asset loader source.
187
- *
188
- * The variable {$loader} can be either 'script' or 'style'.
189
- *
190
- * @since 2.9.0
191
- *
192
- * @param string $src Script or style loader source path.
193
- * @param string $handle Script or style handle.
194
- */
195
- $source = apply_filters( "{$loader}_loader_src", $src, $dependency->handle );
196
-
197
- $host = (string) wp_parse_url( $source, PHP_URL_HOST );
198
- $scheme = (string) wp_parse_url( $source, PHP_URL_SCHEME );
199
- // phpcs:ignore WordPress.VIP.ValidatedSanitizedInput
200
- $http_host = wp_unslash( $_SERVER['HTTP_HOST'] );
201
-
202
- if ( empty( $host ) && ! empty( $http_host ) ) {
203
- $host = $http_host;
204
- }
205
-
206
- $insecure = ( $scheme && $data['is_ssl'] && ( 'https' !== $scheme ) );
207
-
208
- if ( $insecure ) {
209
- $source = new WP_Error( 'insecure_content', __( 'Insecure content', 'query-monitor' ), array(
210
- 'src' => $source,
211
- ) );
212
- }
213
-
214
- if ( is_wp_error( $source ) ) {
215
- $src = $source->get_error_message();
216
- $error_data = $source->get_error_data();
217
- if ( $error_data && isset( $error_data['src'] ) ) {
218
- $src .= ' (' . $error_data['src'] . ')';
219
- $host = (string) wp_parse_url( $error_data['src'], PHP_URL_HOST );
220
- }
221
- } elseif ( empty( $source ) ) {
222
- $src = '';
223
- $host = '';
224
- } else {
225
- $src = $source;
226
- }
227
 
228
- $local = ( $http_host === $host );
 
229
 
230
- return array( $src, $host, $source, $local );
231
- }
232
 
233
- protected function dependency_row( _WP_Dependency $dependency, WP_Dependencies $dependencies, $type ) {
234
 
235
- if ( empty( $dependency->ver ) ) {
236
- $ver = '';
237
- } else {
238
- $ver = $dependency->ver;
239
  }
240
 
241
- list( $src, $host, $source, $local ) = $this->get_dependency_data( $dependency, $dependencies, $type );
242
-
243
- $dependents = $this->collector->get_dependents( $dependency, $dependencies );
244
- $deps = $dependency->deps;
245
- sort( $deps );
246
 
247
- foreach ( $deps as & $dep ) {
248
- if ( ! $dependencies->query( $dep ) ) {
249
- /* translators: %s: Script or style dependency name */
250
- $dep = sprintf( __( '%s (missing)', 'query-monitor' ), $dep );
251
- }
252
  }
253
 
254
- $this->type = $type;
255
-
256
- $highlight_deps = array_map( array( $this, '_prefix_type' ), $deps );
257
- $highlight_dependents = array_map( array( $this, '_prefix_type' ), $dependents );
258
 
259
- echo '<td class="qm-nowrap qm-ltr">' . esc_html( $dependency->handle ) . '</td>';
260
- echo '<td class="qm-nowrap qm-ltr">' . esc_html( $host ) . '</td>';
261
  echo '<td class="qm-ltr">';
262
- if ( is_wp_error( $source ) ) {
263
- printf(
264
- '<span class="qm-warn">%s</span>',
265
- esc_html( $src )
266
- );
267
- } elseif ( ! empty( $src ) ) {
 
 
 
 
 
 
 
 
 
268
  printf(
269
  '<a href="%s" class="qm-link">%s</a>',
270
- esc_attr( $src ),
271
- esc_html( ltrim( str_replace( home_url(), '', remove_query_arg( 'ver', $src ) ), '/' ) )
272
  );
273
  }
274
  echo '</td>';
275
- echo '<td class="qm-ltr qm-highlighter" data-qm-highlight="' . esc_attr( implode( ' ', $highlight_deps ) ) . '">' . implode( ', ', array_map( 'esc_html', $deps ) ) . '</td>';
276
- echo '<td class="qm-ltr qm-highlighter" data-qm-highlight="' . esc_attr( implode( ' ', $highlight_dependents ) ) . '">' . implode( ', ', array_map( 'esc_html', $dependents ) ) . '</td>';
277
- echo '<td class="qm-ltr">' . esc_html( $ver ) . '</td>';
278
 
 
279
  }
280
 
281
  public function _prefix_type( $val ) {
@@ -296,38 +173,30 @@ class QM_Output_Html_Assets extends QM_Output_Html {
296
 
297
  public function admin_menu( array $menu ) {
298
 
299
- $data = $this->collector->get_data();
300
- $labels = array(
301
- 'scripts' => __( 'Scripts', 'query-monitor' ),
302
- 'styles' => __( 'Styles', 'query-monitor' ),
303
- );
304
 
305
- foreach ( $labels as $type => $label ) {
306
- $args = array(
307
- 'title' => esc_html( $label ),
308
- 'id' => esc_attr( "query-monitor-{$this->collector->id}-{$type}" ),
309
- 'href' => esc_attr( '#' . $this->collector->id() . '-' . $type ),
310
- );
311
 
312
- if ( ! empty( $data['broken'][ $type ] ) || ! empty( $data['missing'][ $type ] ) ) {
313
- $args['meta']['classname'] = 'qm-error';
314
- }
 
 
 
 
 
315
 
316
- $menu[] = $this->menu( $args );
 
317
  }
318
 
 
 
 
319
  return $menu;
320
 
321
  }
322
 
323
  }
324
-
325
- function register_qm_output_html_assets( array $output, QM_Collectors $collectors ) {
326
- $collector = $collectors::get( 'assets' );
327
- if ( $collector ) {
328
- $output['assets'] = new QM_Output_Html_Assets( $collector );
329
- }
330
- return $output;
331
- }
332
-
333
- add_filter( 'qm/outputter/html', 'register_qm_output_html_assets', 80, 2 );
5
  * @package query-monitor
6
  */
7
 
8
+ abstract class QM_Output_Html_Assets extends QM_Output_Html {
9
 
10
  public function __construct( QM_Collector $collector ) {
11
  parent::__construct( $collector );
13
  add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
14
  }
15
 
16
+ abstract public function get_type_labels();
17
+
18
  public function output() {
19
 
20
  $data = $this->collector->get_data();
21
 
22
+ if ( empty( $data['assets'] ) ) {
23
  return;
24
  }
25
 
26
  $position_labels = array(
27
+ // @TODO translator comments or context:
28
  'missing' => __( 'Missing', 'query-monitor' ),
29
  'broken' => __( 'Missing Dependencies', 'query-monitor' ),
30
  'header' => __( 'Header', 'query-monitor' ),
31
  'footer' => __( 'Footer', 'query-monitor' ),
32
  );
33
 
34
+ $type_label = $this->get_type_labels();
35
+ $type = $this->collector->get_dependency_type();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ $this->type = $type;
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ $hosts = array(
40
+ __( 'Other', 'query-monitor' ),
41
+ );
42
 
43
+ $this->before_tabular_output();
 
 
 
 
44
 
45
+ echo '<thead>';
46
+ echo '<tr>';
47
+ echo '<th scope="col">' . esc_html__( 'Position', 'query-monitor' ) . '</th>';
48
+ echo '<th scope="col">' . esc_html__( 'Handle', 'query-monitor' ) . '</th>';
49
+ echo '<th scope="col" class="qm-filterable-column">';
50
+ $args = array(
51
+ 'prepend' => array(
52
+ 'local' => $data['host'],
53
+ ),
54
+ );
55
+ echo $this->build_filter( $type . '-host', $hosts, __( 'Host', 'query-monitor' ), $args ); // WPCS: XSS ok.
56
+ echo '</th>';
57
+ echo '<th scope="col">' . esc_html__( 'Source', 'query-monitor' ) . '</th>';
58
+ echo '<th scope="col" class="qm-filterable-column">';
59
+ echo $this->build_filter( $type . '-dependencies', $data['dependencies'], __( 'Dependencies', 'query-monitor' ) ); // WPCS: XSS ok.
60
+ echo '</th>';
61
+ echo '<th scope="col" class="qm-filterable-column">';
62
+ echo $this->build_filter( $type . '-dependents', $data['dependents'], __( 'Dependents', 'query-monitor' ) ); // WPCS: XSS ok.
63
+ echo '</th>';
64
+ echo '<th scope="col">' . esc_html__( 'Version', 'query-monitor' ) . '</th>';
65
+ echo '</tr>';
66
+ echo '</thead>';
67
+
68
+ echo '<tbody>';
69
+
70
+ $total = 0;
71
+
72
+ foreach ( $position_labels as $position => $label ) {
73
+ if ( ! empty( $data['assets'][ $position ] ) ) {
74
+ foreach ( $data['assets'][ $position ] as $handle => $asset ) {
75
+ $this->dependency_row( $handle, $asset, $label );
 
 
 
76
  }
77
+ $total += count( $data['assets'][ $position ] );
78
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
 
81
+ echo '</tbody>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
+ echo '<tfoot>';
84
 
85
+ echo '<tr>';
86
+ printf(
87
+ '<td colspan="7">%1$s</td>',
88
+ sprintf(
89
+ esc_html( $type_label['total'] ),
90
+ '<span class="qm-items-number">' . esc_html( number_format_i18n( $total ) ) . '</span>'
91
+ )
92
+ );
93
+ echo '</tr>';
94
+ echo '</tfoot>';
95
 
96
+ $this->after_tabular_output();
 
97
  }
98
 
99
+ protected function dependency_row( $handle, array $asset, $label ) {
100
  $data = $this->collector->get_data();
101
 
102
+ $highlight_deps = array_map( array( $this, '_prefix_type' ), $asset['dependencies'] );
103
+ $highlight_dependents = array_map( array( $this, '_prefix_type' ), $asset['dependents'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
+ $dependencies_list = implode( ' ', $asset['dependencies'] );
106
+ $dependents_list = implode( ' ', $asset['dependents'] );
107
 
108
+ $qm_host = ( $asset['local'] ) ? 'local' : __( 'Other', 'query-monitor' );
 
109
 
110
+ $class = '';
111
 
112
+ if ( $asset['warning'] ) {
113
+ $class = 'qm-warn';
 
 
114
  }
115
 
116
+ echo '<tr data-qm-subject="' . esc_attr( $this->type . '-' . $handle ) . '" data-qm-' . esc_attr( $this->type ) . '-host="' . esc_attr( $qm_host ) . '" data-qm-' . esc_attr( $this->type ) . '-dependents="' . esc_attr( $dependents_list ) . '" data-qm-' . esc_attr( $this->type ) . '-dependencies="' . esc_attr( $dependencies_list ) . '" class="' . esc_attr( $class ) . '">';
117
+ echo '<td class="qm-nowrap">';
 
 
 
118
 
119
+ if ( $asset['warning'] ) {
120
+ echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
 
 
 
121
  }
122
 
123
+ echo esc_html( $label );
124
+ echo '</td>';
 
 
125
 
126
+ echo '<td class="qm-nowrap qm-ltr">' . esc_html( $handle ) . '</td>';
127
+ echo '<td class="qm-nowrap qm-ltr">' . esc_html( $asset['host'] ) . '</td>';
128
  echo '<td class="qm-ltr">';
129
+ if ( is_wp_error( $asset['source'] ) ) {
130
+ $error_data = $asset['source']->get_error_data();
131
+ if ( $error_data && isset( $error_data['src'] ) ) {
132
+ printf(
133
+ '<span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%1$s:</span><br><a href="%2$s" class="qm-link">%2$s</a>',
134
+ esc_html( $asset['source']->get_error_message() ),
135
+ esc_html( $error_data['src'] )
136
+ );
137
+ } else {
138
+ printf(
139
+ '<span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%s</span>',
140
+ esc_html( $asset['source']->get_error_message() )
141
+ );
142
+ }
143
+ } elseif ( ! empty( $asset['source'] ) ) {
144
  printf(
145
  '<a href="%s" class="qm-link">%s</a>',
146
+ esc_attr( $asset['source'] ),
147
+ esc_html( $asset['display'] )
148
  );
149
  }
150
  echo '</td>';
151
+ echo '<td class="qm-ltr qm-highlighter" data-qm-highlight="' . esc_attr( implode( ' ', $highlight_deps ) ) . '">' . implode( ', ', array_map( 'esc_html', $asset['dependencies'] ) ) . '</td>';
152
+ echo '<td class="qm-ltr qm-highlighter" data-qm-highlight="' . esc_attr( implode( ' ', $highlight_dependents ) ) . '">' . implode( ', ', array_map( 'esc_html', $asset['dependents'] ) ) . '</td>';
153
+ echo '<td class="qm-ltr">' . esc_html( $asset['ver'] ) . '</td>';
154
 
155
+ echo '</tr>';
156
  }
157
 
158
  public function _prefix_type( $val ) {
173
 
174
  public function admin_menu( array $menu ) {
175
 
176
+ $data = $this->collector->get_data();
 
 
 
 
177
 
178
+ if ( empty( $data['assets'] ) ) {
179
+ return $menu;
180
+ }
 
 
 
181
 
182
+ $type = $this->collector->get_dependency_type();
183
+ $label = $this->collector->name();
184
+
185
+ $args = array(
186
+ 'title' => esc_html( $label ),
187
+ 'id' => esc_attr( "query-monitor-{$this->collector->id}" ),
188
+ 'href' => esc_attr( '#' . $this->collector->id() ),
189
+ );
190
 
191
+ if ( ! empty( $data['broken'] ) || ! empty( $data['missing'] ) ) {
192
+ $args['meta']['classname'] = 'qm-error';
193
  }
194
 
195
+ $id = $this->collector->id();
196
+ $menu[ $id ] = $this->menu( $args );
197
+
198
  return $menu;
199
 
200
  }
201
 
202
  }
 
 
 
 
 
 
 
 
 
 
output/html/assets_scripts.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Enqueued scripts output for HTML pages.
4
+ *
5
+ * @package query-monitor
6
+ */
7
+
8
+ class QM_Output_Html_Assets_Scripts extends QM_Output_Html_Assets {
9
+
10
+ public function get_type_labels() {
11
+ return array(
12
+ /* translators: %s: Total number of enqueued scripts */
13
+ 'total' => _x( 'Total: %s', 'Enqueued scripts', 'query-monitor' ),
14
+ 'plural' => __( 'Scripts', 'query-monitor' ),
15
+ );
16
+ }
17
+
18
+ }
19
+
20
+ function register_qm_output_html_assets_scripts( array $output, QM_Collectors $collectors ) {
21
+ $collector = $collectors::get( 'assets_scripts' );
22
+ if ( $collector ) {
23
+ $output['assets_scripts'] = new QM_Output_Html_Assets_Scripts( $collector );
24
+ }
25
+ return $output;
26
+ }
27
+
28
+ add_filter( 'qm/outputter/html', 'register_qm_output_html_assets_scripts', 80, 2 );
output/html/assets_styles.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Enqueued styles output for HTML pages.
4
+ *
5
+ * @package query-monitor
6
+ */
7
+
8
+ class QM_Output_Html_Assets_Styles extends QM_Output_Html_Assets {
9
+
10
+ public function get_type_labels() {
11
+ return array(
12
+ /* translators: %s: Total number of enqueued styles */
13
+ 'total' => _x( 'Total: %s', 'Enqueued styles', 'query-monitor' ),
14
+ 'plural' => __( 'Styles', 'query-monitor' ),
15
+ );
16
+ }
17
+
18
+ }
19
+
20
+ function register_qm_output_html_assets_styles( array $output, QM_Collectors $collectors ) {
21
+ $collector = $collectors::get( 'assets_styles' );
22
+ if ( $collector ) {
23
+ $output['assets_styles'] = new QM_Output_Html_Assets_Styles( $collector );
24
+ }
25
+ return $output;
26
+ }
27
+
28
+ add_filter( 'qm/outputter/html', 'register_qm_output_html_assets_styles', 80, 2 );
output/html/block_editor.php CHANGED
@@ -38,6 +38,11 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
38
  echo '<th scope="col">' . esc_html__( 'Block Name', 'query-monitor' ) . '</th>';
39
  echo '<th scope="col">' . esc_html__( 'Attributes', 'query-monitor' ) . '</th>';
40
  echo '<th scope="col">' . esc_html__( 'Render Callback', 'query-monitor' ) . '</th>';
 
 
 
 
 
41
  echo '<th scope="col">' . esc_html__( 'Inner HTML', 'query-monitor' ) . '</th>';
42
  echo '</tr>';
43
  echo '</thead>';
@@ -53,7 +58,7 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
53
  echo '<tfoot>';
54
  echo '<tr>';
55
  printf(
56
- '<td colspan="5">%1$s</td>',
57
  sprintf(
58
  /* translators: %s: Total number of content blocks used */
59
  esc_html_x( 'Total: %s', 'Content blocks used', 'query-monitor' ),
@@ -67,7 +72,7 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
67
  }
68
 
69
  protected static function render_block( $i, array $block, array $data ) {
70
- $block_error = ( empty( $block['blockName'] ) && trim( $block['innerHTML'] ) );
71
  $row_class = '';
72
  $referenced_post = null;
73
  $referenced_type = null;
@@ -104,7 +109,7 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
104
  'core/video' => 'id',
105
  );
106
 
107
- if ( isset( $media_blocks[ $block['blockName'] ] ) && ! empty( $block['attrs'][ $media_blocks[ $block['blockName'] ] ] ) ) {
108
  $referenced_post = get_post( $block['attrs'][ $media_blocks[ $block['blockName'] ] ] );
109
 
110
  if ( ! $referenced_post ) {
@@ -135,18 +140,15 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
135
 
136
  echo '<td class="qm-row-block-name"><span class="qm-sticky">';
137
 
138
- if ( $block_error ) {
139
- echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
140
- }
141
-
142
  if ( $block['blockName'] ) {
143
  echo esc_html( $block['blockName'] );
144
  } else {
145
- echo '<em>' . esc_html__( 'None', 'query-monitor' ) . '</em>';
146
  }
147
 
148
  if ( $error_message ) {
149
  echo '<br>';
 
150
  echo $error_message; // WPCS: XSS ok;
151
  }
152
 
@@ -158,9 +160,8 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
158
  echo '</span></td>';
159
 
160
  echo '<td class="qm-row-block-attrs">';
161
- if ( $block['attrs'] ) {
162
- $json = json_encode( $block['attrs'], JSON_PRETTY_PRINT );
163
- echo '<pre class="qm-pre-wrap"><code>' . esc_html( $json ) . '</code></pre>';
164
  }
165
  echo '</td>';
166
 
@@ -189,7 +190,7 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
189
  echo '<code>' . esc_html( $block['callback']['name'] ) . '</code>';
190
 
191
  if ( isset( $block['callback']['error'] ) ) {
192
- echo '<br>';
193
  echo esc_html( sprintf(
194
  /* translators: %s: Error message text */
195
  __( 'Error: %s', 'query-monitor' ),
@@ -199,17 +200,29 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
199
 
200
  echo '</td>';
201
  }
 
 
 
 
 
 
 
 
202
  } else {
203
  echo '<td></td>';
 
 
 
 
204
  }
205
 
206
  $inner_html = trim( $block['innerHTML'] );
207
 
208
- if ( $block['size'] > 600 ) {
209
  echo '<td class="qm-ltr qm-has-toggle qm-row-block-html"><div class="qm-toggler">';
210
  echo self::build_toggler(); // WPCS: XSS ok;
211
  echo '<div class="qm-inverse-toggled"><pre class="qm-pre-wrap"><code>';
212
- echo esc_html( substr( $inner_html, 0, 500 ) ) . '<br><b>&hellip;</b>';
213
  echo '</code></pre></div>';
214
  echo '<div class="qm-toggled"><pre class="qm-pre-wrap"><code>';
215
  echo esc_html( $inner_html );
@@ -226,7 +239,7 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
226
  if ( ! empty( $block['innerBlocks'] ) ) {
227
  foreach ( $block['innerBlocks'] as $j => $inner_block ) {
228
  $x = ++$j;
229
- self::render_block( "{$i}-{$x}", $inner_block, $data );
230
  }
231
  }
232
  }
@@ -238,7 +251,7 @@ class QM_Output_Html_Block_Editor extends QM_Output_Html {
238
  return $menu;
239
  }
240
 
241
- $menu[] = $this->menu( array(
242
  'title' => esc_html__( 'Blocks', 'query-monitor' ),
243
  ) );
244
 
38
  echo '<th scope="col">' . esc_html__( 'Block Name', 'query-monitor' ) . '</th>';
39
  echo '<th scope="col">' . esc_html__( 'Attributes', 'query-monitor' ) . '</th>';
40
  echo '<th scope="col">' . esc_html__( 'Render Callback', 'query-monitor' ) . '</th>';
41
+
42
+ if ( isset( $data['has_block_timing'] ) ) {
43
+ echo '<th scope="col" class="qm-num">' . esc_html__( 'Render Time', 'query-monitor' ) . '</th>';
44
+ }
45
+
46
  echo '<th scope="col">' . esc_html__( 'Inner HTML', 'query-monitor' ) . '</th>';
47
  echo '</tr>';
48
  echo '</thead>';
58
  echo '<tfoot>';
59
  echo '<tr>';
60
  printf(
61
+ '<td colspan="6">%1$s</td>',
62
  sprintf(
63
  /* translators: %s: Total number of content blocks used */
64
  esc_html_x( 'Total: %s', 'Content blocks used', 'query-monitor' ),
72
  }
73
 
74
  protected static function render_block( $i, array $block, array $data ) {
75
+ $block_error = false;
76
  $row_class = '';
77
  $referenced_post = null;
78
  $referenced_type = null;
109
  'core/video' => 'id',
110
  );
111
 
112
+ if ( isset( $media_blocks[ $block['blockName'] ] ) && is_array( $block['attrs'] ) && ! empty( $block['attrs'][ $media_blocks[ $block['blockName'] ] ] ) ) {
113
  $referenced_post = get_post( $block['attrs'][ $media_blocks[ $block['blockName'] ] ] );
114
 
115
  if ( ! $referenced_post ) {
140
 
141
  echo '<td class="qm-row-block-name"><span class="qm-sticky">';
142
 
 
 
 
 
143
  if ( $block['blockName'] ) {
144
  echo esc_html( $block['blockName'] );
145
  } else {
146
+ echo '<em>' . esc_html__( 'None (Classic block)', 'query-monitor' ) . '</em>';
147
  }
148
 
149
  if ( $error_message ) {
150
  echo '<br>';
151
+ echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
152
  echo $error_message; // WPCS: XSS ok;
153
  }
154
 
160
  echo '</span></td>';
161
 
162
  echo '<td class="qm-row-block-attrs">';
163
+ if ( $block['attrs'] && is_array( $block['attrs'] ) ) {
164
+ echo '<pre class="qm-pre-wrap"><code>' . esc_html( QM_Util::json_format( $block['attrs'] ) ) . '</code></pre>';
 
165
  }
166
  echo '</td>';
167
 
190
  echo '<code>' . esc_html( $block['callback']['name'] ) . '</code>';
191
 
192
  if ( isset( $block['callback']['error'] ) ) {
193
+ echo '<br><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
194
  echo esc_html( sprintf(
195
  /* translators: %s: Error message text */
196
  __( 'Error: %s', 'query-monitor' ),
200
 
201
  echo '</td>';
202
  }
203
+
204
+ if ( $data['has_block_timing'] ) {
205
+ echo '<td class="qm-num">';
206
+ if ( isset( $block['timing'] ) ) {
207
+ echo esc_html( number_format_i18n( $block['timing'], 4 ) );
208
+ }
209
+ echo '</td>';
210
+ }
211
  } else {
212
  echo '<td></td>';
213
+
214
+ if ( $data['has_block_timing'] ) {
215
+ echo '<td></td>';
216
+ }
217
  }
218
 
219
  $inner_html = trim( $block['innerHTML'] );
220
 
221
+ if ( $block['size'] > 300 ) {
222
  echo '<td class="qm-ltr qm-has-toggle qm-row-block-html"><div class="qm-toggler">';
223
  echo self::build_toggler(); // WPCS: XSS ok;
224
  echo '<div class="qm-inverse-toggled"><pre class="qm-pre-wrap"><code>';
225
+ echo esc_html( substr( $inner_html, 0, 200 ) ) . '&nbsp;&hellip;';
226
  echo '</code></pre></div>';
227
  echo '<div class="qm-toggled"><pre class="qm-pre-wrap"><code>';
228
  echo esc_html( $inner_html );
239
  if ( ! empty( $block['innerBlocks'] ) ) {
240
  foreach ( $block['innerBlocks'] as $j => $inner_block ) {
241
  $x = ++$j;
242
+ self::render_block( "{$i}.{$x}", $inner_block, $data );
243
  }
244
  }
245
  }
251
  return $menu;
252
  }
253
 
254
+ $menu[ $this->collector->id() ] = $this->menu( array(
255
  'title' => esc_html__( 'Blocks', 'query-monitor' ),
256
  ) );
257
 
output/html/caps.php CHANGED
@@ -186,7 +186,7 @@ class QM_Output_Html_Caps extends QM_Output_Html {
186
  $colspan = ( $show_user ) ? 5 : 4;
187
 
188
  echo '<tr>';
189
- echo '<td colspan="' . absint( $colspan ) . '">';
190
  printf(
191
  /* translators: %s: Number of user capability checks */
192
  esc_html_x( 'Total: %s', 'User capability checks', 'query-monitor' ),
@@ -208,7 +208,7 @@ class QM_Output_Html_Caps extends QM_Output_Html {
208
  }
209
 
210
  public function admin_menu( array $menu ) {
211
- $menu[] = $this->menu( array(
212
  'title' => $this->collector->name(),
213
  ) );
214
  return $menu;
186
  $colspan = ( $show_user ) ? 5 : 4;
187
 
188
  echo '<tr>';
189
+ echo '<td colspan="' . intval( $colspan ) . '">';
190
  printf(
191
  /* translators: %s: Number of user capability checks */
192
  esc_html_x( 'Total: %s', 'User capability checks', 'query-monitor' ),
208
  }
209
 
210
  public function admin_menu( array $menu ) {
211
+ $menu[ $this->collector->id() ] = $this->menu( array(
212
  'title' => $this->collector->name(),
213
  ) );
214
  return $menu;
output/html/conditionals.php CHANGED
@@ -21,17 +21,21 @@ class QM_Output_Html_Conditionals extends QM_Output_Html {
21
  echo '<section>';
22
  echo '<h3>' . esc_html__( 'True Conditionals', 'query-monitor' ) . '</h3>';
23
 
 
24
  foreach ( $data['conds']['true'] as $cond ) {
25
- echo '<p class="qm-item qm-ltr qm-true"><code>' . esc_html( $cond ) . '()</code></p>';
26
  }
 
27
 
28
  echo '</section>';
29
  echo '<section>';
30
  echo '<h3>' . esc_html__( 'False Conditionals', 'query-monitor' ) . '</h3>';
31
 
 
32
  foreach ( $data['conds']['false'] as $cond ) {
33
- echo '<p class="qm-item qm-ltr qm-false"><code>' . esc_html( $cond ) . '()</code></p>';
34
  }
 
35
 
36
  echo '</section>';
37
 
@@ -43,7 +47,8 @@ class QM_Output_Html_Conditionals extends QM_Output_Html {
43
  $data = $this->collector->get_data();
44
 
45
  foreach ( $data['conds']['true'] as $cond ) {
46
- $menu[ "conditionals-{$cond}" ] = $this->menu( array(
 
47
  'title' => esc_html( $cond . '()' ),
48
  'id' => 'query-monitor-conditionals-' . esc_attr( $cond ),
49
  'meta' => array(
@@ -61,10 +66,11 @@ class QM_Output_Html_Conditionals extends QM_Output_Html {
61
  $data = $this->collector->get_data();
62
 
63
  foreach ( $data['conds']['true'] as $cond ) {
64
- unset( $menu[ "conditionals-{$cond}" ] );
 
65
  }
66
 
67
- $menu['conditionals'] = $this->menu( array(
68
  'title' => esc_html__( 'Conditionals', 'query-monitor' ),
69
  'id' => 'query-monitor-conditionals',
70
  ) );
21
  echo '<section>';
22
  echo '<h3>' . esc_html__( 'True Conditionals', 'query-monitor' ) . '</h3>';
23
 
24
+ echo '<ul>';
25
  foreach ( $data['conds']['true'] as $cond ) {
26
+ echo '<li class="qm-ltr qm-true"><code>' . esc_html( $cond ) . '() </code></li>';
27
  }
28
+ echo '</ul>';
29
 
30
  echo '</section>';
31
  echo '<section>';
32
  echo '<h3>' . esc_html__( 'False Conditionals', 'query-monitor' ) . '</h3>';
33
 
34
+ echo '<ul>';
35
  foreach ( $data['conds']['false'] as $cond ) {
36
+ echo '<li class="qm-ltr qm-false"><code>' . esc_html( $cond ) . '() </code></li>';
37
  }
38
+ echo '</ul>';
39
 
40
  echo '</section>';
41
 
47
  $data = $this->collector->get_data();
48
 
49
  foreach ( $data['conds']['true'] as $cond ) {
50
+ $id = $this->collector->id() . '-' . $cond;
51
+ $menu[ $id ] = $this->menu( array(
52
  'title' => esc_html( $cond . '()' ),
53
  'id' => 'query-monitor-conditionals-' . esc_attr( $cond ),
54
  'meta' => array(
66
  $data = $this->collector->get_data();
67
 
68
  foreach ( $data['conds']['true'] as $cond ) {
69
+ $id = $this->collector->id() . '-' . $cond;
70
+ unset( $menu[ $id ] );
71
  }
72
 
73
+ $menu[ $this->collector->id() ] = $this->menu( array(
74
  'title' => esc_html__( 'Conditionals', 'query-monitor' ),
75
  'id' => 'query-monitor-conditionals',
76
  ) );
output/html/db_callers.php CHANGED
@@ -9,7 +9,7 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
9
 
10
  public function __construct( QM_Collector $collector ) {
11
  parent::__construct( $collector );
12
- add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 30 );
13
  }
14
 
15
  public function output() {
@@ -48,13 +48,13 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
48
  $stime = number_format_i18n( $row['ltime'], 4 );
49
 
50
  echo '<tr>';
51
- echo '<td class="qm-ltr"><a href="#" class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="' . esc_attr( $row['caller'] ) . '"><code>' . esc_html( $row['caller'] ) . '</code></a></td>';
52
 
53
  foreach ( $data['types'] as $type_name => $type_count ) {
54
  if ( isset( $row['types'][ $type_name ] ) ) {
55
  echo "<td class='qm-num'>" . esc_html( number_format_i18n( $row['types'][ $type_name ] ) ) . '</td>';
56
  } else {
57
- echo "<td class='qm-num'>&nbsp;</td>";
58
  }
59
  }
60
 
@@ -69,7 +69,7 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
69
  $total_stime = number_format_i18n( $total_time, 4 );
70
 
71
  echo '<tr>';
72
- echo '<td>&nbsp;</td>';
73
 
74
  foreach ( $data['types'] as $type_name => $type_count ) {
75
  echo '<td class="qm-num">' . esc_html( number_format_i18n( $type_count ) ) . '</td>';
@@ -92,14 +92,14 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
92
  }
93
  }
94
 
95
- public function admin_menu( array $menu ) {
96
  $dbq = QM_Collectors::get( 'db_queries' );
97
 
98
  if ( $dbq ) {
99
  $dbq_data = $dbq->get_data();
100
  if ( isset( $dbq_data['times'] ) ) {
101
- $menu[] = $this->menu( array(
102
- 'title' => esc_html__( 'Queries by Caller', 'query-monitor' ),
103
  ) );
104
  }
105
  }
9
 
10
  public function __construct( QM_Collector $collector ) {
11
  parent::__construct( $collector );
12
+ add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 30 );
13
  }
14
 
15
  public function output() {
48
  $stime = number_format_i18n( $row['ltime'], 4 );
49
 
50
  echo '<tr>';
51
+ echo '<td class="qm-ltr"><button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="' . esc_attr( $row['caller'] ) . '"><code>' . esc_html( $row['caller'] ) . '</code></button></td>';
52
 
53
  foreach ( $data['types'] as $type_name => $type_count ) {
54
  if ( isset( $row['types'][ $type_name ] ) ) {
55
  echo "<td class='qm-num'>" . esc_html( number_format_i18n( $row['types'][ $type_name ] ) ) . '</td>';
56
  } else {
57
+ echo "<td class='qm-num'></td>";
58
  }
59
  }
60
 
69
  $total_stime = number_format_i18n( $total_time, 4 );
70
 
71
  echo '<tr>';
72
+ echo '<td></td>';
73
 
74
  foreach ( $data['types'] as $type_name => $type_count ) {
75
  echo '<td class="qm-num">' . esc_html( number_format_i18n( $type_count ) ) . '</td>';
92
  }
93
  }
94
 
95
+ public function panel_menu( array $menu ) {
96
  $dbq = QM_Collectors::get( 'db_queries' );
97
 
98
  if ( $dbq ) {
99
  $dbq_data = $dbq->get_data();
100
  if ( isset( $dbq_data['times'] ) ) {
101
+ $menu['qm-db_queries-$wpdb']['children'][] = $this->menu( array(
102
+ 'title' => '└ ' . esc_html__( 'Queries by Caller', 'query-monitor' ),
103
  ) );
104
  }
105
  }
output/html/db_components.php CHANGED
@@ -9,7 +9,7 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
9
 
10
  public function __construct( QM_Collector $collector ) {
11
  parent::__construct( $collector );
12
- add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 40 );
13
  }
14
 
15
  public function output() {
@@ -49,7 +49,7 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
49
  $total_time += $row['ltime'];
50
 
51
  echo '<tr>';
52
- echo '<td class="qm-row-component"><a href="#" class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="component" data-qm-value="' . esc_attr( $row['component'] ) . '">' . esc_html( $row['component'] ) . '</a></td>';
53
 
54
  foreach ( $data['types'] as $type_name => $type_count ) {
55
  if ( isset( $row['types'][ $type_name ] ) ) {
@@ -83,7 +83,7 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
83
  $this->after_tabular_output();
84
  }
85
 
86
- public function admin_menu( array $menu ) {
87
  $data = $this->collector->get_data();
88
 
89
  if ( empty( $data['types'] ) || empty( $data['times'] ) ) {
@@ -95,8 +95,8 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
95
  if ( $dbq ) {
96
  $dbq_data = $dbq->get_data();
97
  if ( isset( $dbq_data['component_times'] ) ) {
98
- $menu[] = $this->menu( array(
99
- 'title' => esc_html__( 'Queries by Component', 'query-monitor' ),
100
  ) );
101
  }
102
  }
9
 
10
  public function __construct( QM_Collector $collector ) {
11
  parent::__construct( $collector );
12
+ add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 40 );
13
  }
14
 
15
  public function output() {
49
  $total_time += $row['ltime'];
50
 
51
  echo '<tr>';
52
+ echo '<td class="qm-row-component"><button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="component" data-qm-value="' . esc_attr( $row['component'] ) . '">' . esc_html( $row['component'] ) . '</button></td>';
53
 
54
  foreach ( $data['types'] as $type_name => $type_count ) {
55
  if ( isset( $row['types'][ $type_name ] ) ) {
83
  $this->after_tabular_output();
84
  }
85
 
86
+ public function panel_menu( array $menu ) {
87
  $data = $this->collector->get_data();
88
 
89
  if ( empty( $data['types'] ) || empty( $data['times'] ) ) {
95
  if ( $dbq ) {
96
  $dbq_data = $dbq->get_data();
97
  if ( isset( $dbq_data['component_times'] ) ) {
98
+ $menu['qm-db_queries-$wpdb']['children'][] = $this->menu( array(
99
+ 'title' => '└ ' . esc_html__( 'Queries by Component', 'query-monitor' ),
100
  ) );
101
  }
102
  }
output/html/db_dupes.php CHANGED
@@ -10,6 +10,7 @@ class QM_Output_Html_DB_Dupes extends QM_Output_Html {
10
  public function __construct( QM_Collector $collector ) {
11
  parent::__construct( $collector );
12
  add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 45 );
 
13
  }
14
 
15
  public function output() {
@@ -61,7 +62,7 @@ class QM_Output_Html_DB_Dupes extends QM_Output_Html {
61
  echo '<td class="qm-row-caller qm-nowrap qm-ltr">';
62
  foreach ( $data['dupe_callers'][ $sql ] as $caller => $calls ) {
63
  printf(
64
- '<a href="#" class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="%s"><code>%s</code></a><br><span class="qm-info qm-supplemental">%s</span><br>',
65
  esc_attr( $caller ),
66
  esc_html( $caller ),
67
  esc_html( sprintf(
@@ -110,7 +111,7 @@ class QM_Output_Html_DB_Dupes extends QM_Output_Html {
110
  if ( $dbq ) {
111
  $dbq_data = $dbq->get_data();
112
  if ( isset( $dbq_data['dupes'] ) && count( $dbq_data['dupes'] ) ) {
113
- $menu[] = $this->menu( array(
114
  'title' => esc_html( sprintf(
115
  /* translators: %s: Number of duplicate database queries */
116
  __( 'Duplicate Queries (%s)', 'query-monitor' ),
@@ -123,6 +124,18 @@ class QM_Output_Html_DB_Dupes extends QM_Output_Html {
123
 
124
  }
125
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
 
128
  function register_qm_output_html_db_dupes( array $output, QM_Collectors $collectors ) {
10
  public function __construct( QM_Collector $collector ) {
11
  parent::__construct( $collector );
12
  add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 45 );
13
+ add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 25 );
14
  }
15
 
16
  public function output() {
62
  echo '<td class="qm-row-caller qm-nowrap qm-ltr">';
63
  foreach ( $data['dupe_callers'][ $sql ] as $caller => $calls ) {
64
  printf(
65
+ '<button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="%s"><code>%s</code></button><br><span class="qm-info qm-supplemental">%s</span><br>',
66
  esc_attr( $caller ),
67
  esc_html( $caller ),
68
  esc_html( sprintf(
111
  if ( $dbq ) {
112
  $dbq_data = $dbq->get_data();
113
  if ( isset( $dbq_data['dupes'] ) && count( $dbq_data['dupes'] ) ) {
114
+ $menu[ $this->collector->id() ] = $this->menu( array(
115
  'title' => esc_html( sprintf(
116
  /* translators: %s: Number of duplicate database queries */
117
  __( 'Duplicate Queries (%s)', 'query-monitor' ),
124
 
125
  }
126
 
127
+ public function panel_menu( array $menu ) {
128
+ $id = $this->collector->id();
129
+ if ( isset( $menu[ $id ] ) ) {
130
+ $menu[ $id ]['title'] = '└ ' . $menu[ $id ]['title'];
131
+
132
+ $menu['qm-db_queries-$wpdb']['children'][] = $menu[ $id ];
133
+ unset( $menu[ $id ] );
134
+ }
135
+
136
+ return $menu;
137
+ }
138
+
139
  }
140
 
141
  function register_qm_output_html_db_dupes( array $output, QM_Collectors $collectors ) {
output/html/db_queries.php CHANGED
@@ -12,6 +12,7 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
12
  public function __construct( QM_Collector $collector ) {
13
  parent::__construct( $collector );
14
  add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 20 );
 
15
  add_filter( 'qm/output/title', array( $this, 'admin_title' ), 20 );
16
  add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
17
  }
@@ -160,7 +161,7 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
160
  */
161
  if ( apply_filters( 'qm/show_extended_query_prompt', true ) && ! $db->has_trace && ( '$wpdb' === $name ) ) {
162
  echo '<tr>';
163
- echo '<th colspan="' . absint( $span ) . '" class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
164
  if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) {
165
  /* translators: 1: Symlink file name, 2: URL to wiki page */
166
  $message = __( 'Extended query information such as the component and affected rows is not available. A conflicting %1$s file is present. <a href="%2$s" target="_blank" class="qm-external-link">See this wiki page for more information.</a>', 'query-monitor' );
@@ -258,7 +259,7 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
258
  $total_stime = number_format_i18n( $db->total_time, 4 );
259
 
260
  echo '<tr>';
261
- echo '<td colspan="' . absint( $span - 1 ) . '">';
262
  printf(
263
  /* translators: %s: Number of database queries */
264
  esc_html_x( 'Total: %s', 'Database queries', 'query-monitor' ),
@@ -292,7 +293,6 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
292
  }
293
 
294
  $stime = number_format_i18n( $row['ltime'], 4 );
295
- $td = $this->collector->is_expensive( $row ) ? ' qm-warn' : '';
296
 
297
  $sql = self::format_sql( $row['sql'] );
298
 
@@ -361,7 +361,7 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
361
  echo "<tr{$attr}>"; // WPCS: XSS ok.
362
 
363
  if ( isset( $cols['row'] ) ) {
364
- echo '<th scope="row" class="qm-row-num qm-num">' . absint( ++$this->query_row ) . '</th>';
365
  }
366
 
367
  if ( isset( $cols['sql'] ) ) {
@@ -421,7 +421,17 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
421
  }
422
 
423
  if ( isset( $cols['time'] ) ) {
424
- echo '<td class="qm-num qm-row-time' . esc_attr( $td ) . '" data-qm-sort-weight="' . esc_attr( $row['ltime'] ) . '">' . esc_html( $stime ) . "</td>\n";
 
 
 
 
 
 
 
 
 
 
425
  }
426
 
427
  echo '</tr>';
@@ -473,8 +483,31 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
473
  $errors = $this->collector->get_errors();
474
  $expensive = $this->collector->get_expensive();
475
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
476
  if ( $errors ) {
477
- $menu[] = $this->menu( array(
 
478
  'id' => 'query-monitor-errors',
479
  'href' => '#qm-query-errors',
480
  'title' => esc_html( sprintf(
@@ -485,7 +518,8 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
485
  ) );
486
  }
487
  if ( $expensive ) {
488
- $menu[] = $this->menu( array(
 
489
  'id' => 'query-monitor-expensive',
490
  'href' => '#qm-query-expensive',
491
  'title' => esc_html( sprintf(
@@ -496,27 +530,22 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
496
  ) );
497
  }
498
 
499
- if ( isset( $data['dbs'] ) && count( $data['dbs'] ) > 1 ) {
500
- foreach ( $data['dbs'] as $name => $db ) {
501
- $menu[] = $this->menu( array(
502
- 'id' => esc_attr( sprintf( 'query-monitor-%s-db-%s', $this->collector->id(), sanitize_title_with_dashes( $name ) ) ),
503
- 'title' => esc_html( sprintf(
504
- /* translators: %s: Name of database controller */
505
- __( 'Queries: %s', 'query-monitor' ),
506
- $name
507
- ) ),
508
- 'href' => esc_attr( sprintf( '#%s-%s', $this->collector->id(), sanitize_title_with_dashes( $name ) ) ),
509
- ) );
 
510
  }
511
- } else {
512
- $menu[] = $this->menu( array(
513
- 'title' => esc_html__( 'Queries', 'query-monitor' ),
514
- 'href' => esc_attr( sprintf( '#%s-wpdb', $this->collector->id() ) ),
515
- ) );
516
  }
517
 
518
  return $menu;
519
-
520
  }
521
 
522
  }
12
  public function __construct( QM_Collector $collector ) {
13
  parent::__construct( $collector );
14
  add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 20 );
15
+ add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 20 );
16
  add_filter( 'qm/output/title', array( $this, 'admin_title' ), 20 );
17
  add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
18
  }
161
  */
162
  if ( apply_filters( 'qm/show_extended_query_prompt', true ) && ! $db->has_trace && ( '$wpdb' === $name ) ) {
163
  echo '<tr>';
164
+ echo '<th colspan="' . intval( $span ) . '" class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
165
  if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) {
166
  /* translators: 1: Symlink file name, 2: URL to wiki page */
167
  $message = __( 'Extended query information such as the component and affected rows is not available. A conflicting %1$s file is present. <a href="%2$s" target="_blank" class="qm-external-link">See this wiki page for more information.</a>', 'query-monitor' );
259
  $total_stime = number_format_i18n( $db->total_time, 4 );
260
 
261
  echo '<tr>';
262
+ echo '<td colspan="' . intval( $span - 1 ) . '">';
263
  printf(
264
  /* translators: %s: Number of database queries */
265
  esc_html_x( 'Total: %s', 'Database queries', 'query-monitor' ),
293
  }
294
 
295
  $stime = number_format_i18n( $row['ltime'], 4 );
 
296
 
297
  $sql = self::format_sql( $row['sql'] );
298
 
361
  echo "<tr{$attr}>"; // WPCS: XSS ok.
362
 
363
  if ( isset( $cols['row'] ) ) {
364
+ echo '<th scope="row" class="qm-row-num qm-num">' . intval( ++$this->query_row ) . '</th>';
365
  }
366
 
367
  if ( isset( $cols['sql'] ) ) {
421
  }
422
 
423
  if ( isset( $cols['time'] ) ) {
424
+ $expensive = $this->collector->is_expensive( $row );
425
+ $td_class = ( $expensive ) ? ' qm-warn' : '';
426
+
427
+ echo '<td class="qm-num qm-row-time' . esc_attr( $td_class ) . '" data-qm-sort-weight="' . esc_attr( $row['ltime'] ) . '">';
428
+
429
+ if ( $expensive ) {
430
+ echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
431
+ }
432
+
433
+ echo esc_html( $stime );
434
+ echo "</td>\n";
435
  }
436
 
437
  echo '</tr>';
483
  $errors = $this->collector->get_errors();
484
  $expensive = $this->collector->get_expensive();
485
 
486
+ if ( isset( $data['dbs'] ) && count( $data['dbs'] ) > 1 ) {
487
+ foreach ( $data['dbs'] as $name => $db ) {
488
+ $name_attr = sanitize_title_with_dashes( $name );
489
+ $id = $this->collector->id() . '-' . $name_attr;
490
+ $menu[ $id ] = $this->menu( array(
491
+ 'id' => esc_attr( sprintf( 'query-monitor-%s-db-%s', $this->collector->id(), $name_attr ) ),
492
+ 'title' => esc_html( sprintf(
493
+ /* translators: %s: Name of database controller */
494
+ __( 'Queries: %s', 'query-monitor' ),
495
+ $name
496
+ ) ),
497
+ 'href' => esc_attr( sprintf( '#%s-%s', $this->collector->id(), $name_attr ) ),
498
+ ) );
499
+ }
500
+ } else {
501
+ $id = $this->collector->id() . '-$wpdb';
502
+ $menu[ $id ] = $this->menu( array(
503
+ 'title' => esc_html__( 'Queries', 'query-monitor' ),
504
+ 'href' => esc_attr( sprintf( '#%s-wpdb', $this->collector->id() ) ),
505
+ ) );
506
+ }
507
+
508
  if ( $errors ) {
509
+ $id = $this->collector->id() . '-errors';
510
+ $menu[ $id ] = $this->menu( array(
511
  'id' => 'query-monitor-errors',
512
  'href' => '#qm-query-errors',
513
  'title' => esc_html( sprintf(
518
  ) );
519
  }
520
  if ( $expensive ) {
521
+ $id = $this->collector->id() . '-expensive';
522
+ $menu[ $id ] = $this->menu( array(
523
  'id' => 'query-monitor-expensive',
524
  'href' => '#qm-query-expensive',
525
  'title' => esc_html( sprintf(
530
  ) );
531
  }
532
 
533
+ return $menu;
534
+
535
+ }
536
+
537
+ public function panel_menu( array $menu ) {
538
+ foreach ( array( 'errors', 'expensive' ) as $sub ) {
539
+ $id = $this->collector->id() . '-' . $sub;
540
+ if ( isset( $menu[ $id ] ) ) {
541
+ $menu[ $id ]['title'] = '└ ' . $menu[ $id ]['title'];
542
+
543
+ $menu['qm-db_queries-$wpdb']['children'][] = $menu[ $id ];
544
+ unset( $menu[ $id ] );
545
  }
 
 
 
 
 
546
  }
547
 
548
  return $menu;
 
549
  }
550
 
551
  }
output/html/environment.php CHANGED
@@ -183,7 +183,7 @@ class QM_Output_Html_Environment extends QM_Output_Html {
183
  echo '<th scope="row">' . esc_html( $label ) . '</th>';
184
 
185
  if ( ! isset( $db['info'][ $field ] ) ) {
186
- echo '<td><span class="qm-warn">' . esc_html__( 'Unknown', 'query-monitor' ) . '</span></td>';
187
  } else {
188
  echo '<td>' . esc_html( $db['info'][ $field ] ) . '</td>';
189
  }
@@ -192,34 +192,14 @@ class QM_Output_Html_Environment extends QM_Output_Html {
192
 
193
  }
194
 
195
- echo '<tr>';
196
-
197
- $first = true;
198
- $search = 'https://www.google.com/search?q=mysql+performance+%s';
199
-
200
  foreach ( $db['variables'] as $setting ) {
201
 
202
- // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
203
  $key = $setting->Variable_name;
204
- // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
205
  $val = $setting->Value;
206
 
207
- $append = '';
208
- $show_warning = false;
209
-
210
- if ( ( true === $db['vars'][ $key ] ) && empty( $val ) ) {
211
- $show_warning = true;
212
- } elseif ( is_string( $db['vars'][ $key ] ) && ( $val !== $db['vars'][ $key ] ) ) {
213
- $show_warning = true;
214
- }
215
-
216
- if ( $show_warning ) {
217
- $append .= sprintf(
218
- '&nbsp;<span class="qm-info">(<a href="%s" target="_blank" class="qm-external-link">%s</a>)</span>',
219
- esc_url( sprintf( $search, rawurlencode( $key ) ) ),
220
- esc_html__( 'Help', 'query-monitor' )
221
- );
222
- }
223
 
224
  if ( is_numeric( $val ) && ( $val >= ( 1024 * 1024 ) ) ) {
225
  $append .= sprintf(
@@ -228,11 +208,7 @@ class QM_Output_Html_Environment extends QM_Output_Html {
228
  );
229
  }
230
 
231
- $class = ( $show_warning ) ? 'qm-warn' : '';
232
-
233
- if ( ! $first ) {
234
- echo '<tr class="' . esc_attr( $class ) . '">';
235
- }
236
 
237
  echo '<th scope="row">' . esc_html( $key ) . '</th>';
238
  echo '<td>';
@@ -241,9 +217,6 @@ class QM_Output_Html_Environment extends QM_Output_Html {
241
  echo '</td>';
242
 
243
  echo '</tr>';
244
-
245
- $first = false;
246
-
247
  }
248
 
249
  echo '</tbody>';
183
  echo '<th scope="row">' . esc_html( $label ) . '</th>';
184
 
185
  if ( ! isset( $db['info'][ $field ] ) ) {
186
+ echo '<td><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>' . esc_html__( 'Unknown', 'query-monitor' ) . '</span></td>';
187
  } else {
188
  echo '<td>' . esc_html( $db['info'][ $field ] ) . '</td>';
189
  }
192
 
193
  }
194
 
 
 
 
 
 
195
  foreach ( $db['variables'] as $setting ) {
196
 
197
+ // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
198
  $key = $setting->Variable_name;
199
+ // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
200
  $val = $setting->Value;
201
 
202
+ $append = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
  if ( is_numeric( $val ) && ( $val >= ( 1024 * 1024 ) ) ) {
205
  $append .= sprintf(
208
  );
209
  }
210
 
211
+ echo '<tr>';
 
 
 
 
212
 
213
  echo '<th scope="row">' . esc_html( $key ) . '</th>';
214
  echo '<td>';
217
  echo '</td>';
218
 
219
  echo '</tr>';
 
 
 
220
  }
221
 
222
  echo '</tbody>';
output/html/hooks.php CHANGED
@@ -22,59 +22,37 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
22
  return;
23
  }
24
 
25
- if ( is_multisite() && is_network_admin() ) {
26
- $screen = preg_replace( '|-network$|', '', $data['screen'] );
27
- } else {
28
- $screen = $data['screen'];
29
- }
30
-
31
- $parts = $data['parts'];
32
- $components = $data['components'];
33
-
34
- usort( $parts, 'strcasecmp' );
35
- usort( $components, 'strcasecmp' );
36
-
37
  $this->before_tabular_output();
38
 
39
  echo '<thead>';
40
  echo '<tr>';
41
  echo '<th scope="col" class="qm-filterable-column">';
42
- echo $this->build_filter( 'name', $parts, __( 'Hook', 'query-monitor' ) ); // WPCS: XSS ok.
43
  echo '</th>';
44
  echo '<th scope="col">' . esc_html__( 'Priority', 'query-monitor' ) . '</th>';
45
  echo '<th scope="col">' . esc_html__( 'Action', 'query-monitor' ) . '</th>';
46
  echo '<th scope="col" class="qm-filterable-column">';
47
- echo $this->build_filter( 'component', $components, __( 'Component', 'query-monitor' ), 'subject' ); // WPCS: XSS ok.
48
  echo '</th>';
49
  echo '</tr>';
50
  echo '</thead>';
51
 
52
  echo '<tbody>';
53
- self::output_hook_table( $data['hooks'], $screen );
54
  echo '</tbody>';
55
 
56
  $this->after_tabular_output();
57
  }
58
 
59
- public static function output_hook_table( array $hooks, $screen = '' ) {
60
- foreach ( $hooks as $hook ) {
61
-
62
- if ( ! empty( $screen ) ) {
63
-
64
- if ( false !== strpos( $hook['name'], $screen . '.php' ) ) {
65
- $hook_name = str_replace( '-' . $screen . '.php', '-<span class="qm-current">' . $screen . '.php</span>', esc_html( $hook['name'] ) );
66
- } else {
67
- $hook_name = str_replace( '-' . $screen, '-<span class="qm-current">' . $screen . '</span>', esc_html( $hook['name'] ) );
68
- }
69
- } else {
70
- $hook_name = esc_html( $hook['name'] );
71
- }
72
 
 
73
  $row_attr = array();
74
  $row_attr['data-qm-name'] = implode( ' ', $hook['parts'] );
75
  $row_attr['data-qm-component'] = implode( ' ', $hook['components'] );
76
 
77
- if ( ! empty( $row_attr['data-qm-component'] ) && 'Core' !== $row_attr['data-qm-component'] ) {
78
  $row_attr['data-qm-component'] .= ' non-core';
79
  }
80
 
@@ -103,7 +81,7 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
103
  $subject = $component;
104
  }
105
 
106
- if ( __( 'Core', 'query-monitor' ) !== $component ) {
107
  $subject .= ' non-core';
108
  }
109
 
@@ -115,10 +93,10 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
115
 
116
  if ( $first ) {
117
 
118
- echo '<th scope="row" rowspan="' . absint( $rowspan ) . '" class="qm-nowrap qm-ltr"><span class="qm-sticky">';
119
- echo '<code>' . $hook_name . '</code>'; // WPCS: XSS ok.
120
  if ( 'all' === $hook['name'] ) {
121
- echo '<br><span class="qm-warn">';
122
  printf(
123
  /* translators: %s: Action name */
124
  esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ),
@@ -136,7 +114,20 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
136
  $class = '';
137
  }
138
 
139
- echo '<td class="qm-num' . esc_attr( $class ) . '">' . intval( $action['priority'] ) . '</td>';
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
  if ( isset( $action['callback']['file'] ) ) {
142
  if ( self::has_clickable_links() ) {
@@ -156,7 +147,7 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
156
  echo '<code>' . esc_html( $action['callback']['name'] ) . '</code>';
157
 
158
  if ( isset( $action['callback']['error'] ) ) {
159
- echo '<br>';
160
  echo esc_html( sprintf(
161
  /* translators: %s: Error message text */
162
  __( 'Error: %s', 'query-monitor' ),
@@ -175,12 +166,12 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
175
  }
176
  } else {
177
  echo "<tr{$attr}>"; // WPCS: XSS ok.
178
- echo '<th scope="row" class="qm-ltr"><span class="qm-sticky">';
179
- echo '<code>' . $hook_name . '</code>'; // WPCS: XSS ok.
180
- echo '</span></th>';
181
- echo '<td>&nbsp;</td>';
182
- echo '<td>&nbsp;</td>';
183
- echo '<td>&nbsp;</td>';
184
  echo '</tr>';
185
  }
186
  }
22
  return;
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  $this->before_tabular_output();
26
 
27
  echo '<thead>';
28
  echo '<tr>';
29
  echo '<th scope="col" class="qm-filterable-column">';
30
+ echo $this->build_filter( 'name', $data['parts'], __( 'Hook', 'query-monitor' ) ); // WPCS: XSS ok.
31
  echo '</th>';
32
  echo '<th scope="col">' . esc_html__( 'Priority', 'query-monitor' ) . '</th>';
33
  echo '<th scope="col">' . esc_html__( 'Action', 'query-monitor' ) . '</th>';
34
  echo '<th scope="col" class="qm-filterable-column">';
35
+ echo $this->build_filter( 'component', $data['components'], __( 'Component', 'query-monitor' ), 'subject' ); // WPCS: XSS ok.
36
  echo '</th>';
37
  echo '</tr>';
38
  echo '</thead>';
39
 
40
  echo '<tbody>';
41
+ self::output_hook_table( $data['hooks'] );
42
  echo '</tbody>';
43
 
44
  $this->after_tabular_output();
45
  }
46
 
47
+ public static function output_hook_table( array $hooks ) {
48
+ $core = __( 'Core', 'query-monitor' );
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ foreach ( $hooks as $hook ) {
51
  $row_attr = array();
52
  $row_attr['data-qm-name'] = implode( ' ', $hook['parts'] );
53
  $row_attr['data-qm-component'] = implode( ' ', $hook['components'] );
54
 
55
+ if ( ! empty( $row_attr['data-qm-component'] ) && $core !== $row_attr['data-qm-component'] ) {
56
  $row_attr['data-qm-component'] .= ' non-core';
57
  }
58
 
81
  $subject = $component;
82
  }
83
 
84
+ if ( $core !== $component ) {
85
  $subject .= ' non-core';
86
  }
87
 
93
 
94
  if ( $first ) {
95
 
96
+ echo '<th scope="row" rowspan="' . intval( $rowspan ) . '" class="qm-nowrap qm-ltr"><span class="qm-sticky">';
97
+ echo '<code>' . esc_html( $hook['name'] ) . '</code>';
98
  if ( 'all' === $hook['name'] ) {
99
+ echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
100
  printf(
101
  /* translators: %s: Action name */
102
  esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ),
114
  $class = '';
115
  }
116
 
117
+ echo '<td class="qm-num' . esc_attr( $class ) . '">';
118
+
119
+ echo esc_html( $action['priority'] );
120
+
121
+ if ( PHP_INT_MAX === $action['priority'] ) {
122
+ echo ' <span class="qm-info">(PHP_INT_MAX)</span>';
123
+ // phpcs:ignore PHPCompatibility.Constants.NewConstants.php_int_minFound
124
+ } elseif ( defined( 'PHP_INT_MIN' ) && PHP_INT_MIN === $action['priority'] ) {
125
+ echo ' <span class="qm-info">(PHP_INT_MIN)</span>';
126
+ } elseif ( -PHP_INT_MAX === $action['priority'] ) {
127
+ echo ' <span class="qm-info">(-PHP_INT_MAX)</span>';
128
+ }
129
+
130
+ echo '</td>';
131
 
132
  if ( isset( $action['callback']['file'] ) ) {
133
  if ( self::has_clickable_links() ) {
147
  echo '<code>' . esc_html( $action['callback']['name'] ) . '</code>';
148
 
149
  if ( isset( $action['callback']['error'] ) ) {
150
+ echo '<br><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
151
  echo esc_html( sprintf(
152
  /* translators: %s: Error message text */
153
  __( 'Error: %s', 'query-monitor' ),
166
  }
167
  } else {
168
  echo "<tr{$attr}>"; // WPCS: XSS ok.
169
+ echo '<th scope="row" class="qm-ltr">';
170
+ echo '<code>' . esc_html( $hook['name'] ) . '</code>';
171
+ echo '</th>';
172
+ echo '<td></td>';
173
+ echo '<td></td>';
174
+ echo '<td></td>';
175
  echo '</tr>';
176
  }
177
  }
output/html/http.php CHANGED
@@ -19,14 +19,6 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
19
 
20
  $total_time = 0;
21
 
22
- $vars = array();
23
-
24
- if ( ! empty( $data['vars'] ) ) {
25
- foreach ( $data['vars'] as $key => $value ) {
26
- $vars[] = $key . ': ' . $value;
27
- }
28
- }
29
-
30
  if ( ! empty( $data['http'] ) ) {
31
  $statuses = array_keys( $data['types'] );
32
  $components = wp_list_pluck( $data['component_times'], 'component' );
@@ -164,7 +156,7 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
164
 
165
  if ( ! empty( $row['redirected_to'] ) ) {
166
  $url .= sprintf(
167
- '<br><span class="qm-warn">%1$s</span><br>%2$s',
168
  /* translators: An HTTP API request redirected to another URL */
169
  __( 'Redirected to:', 'query-monitor' ),
170
  self::format_url( $row['redirected_to'] )
@@ -296,13 +288,12 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
296
 
297
  echo '<tr>';
298
  printf(
299
- '<td colspan="6">%1$s<br>%2$s</td>',
300
  sprintf(
301
  /* translators: %s: Number of HTTP API requests */
302
  esc_html_x( 'Total: %s', 'HTTP API calls', 'query-monitor' ),
303
  '<span class="qm-items-number">' . esc_html( number_format_i18n( count( $data['http'] ) ) ) . '</span>'
304
- ),
305
- implode( '<br>', array_map( 'esc_html', $vars ) )
306
  );
307
  echo '<td class="qm-num qm-items-time">' . esc_html( $total_stime ) . '</td>';
308
  echo '</tr>';
@@ -359,7 +350,7 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
359
  $args['meta']['classname'] = 'qm-warning';
360
  }
361
 
362
- $menu[] = $this->menu( $args );
363
 
364
  return $menu;
365
 
19
 
20
  $total_time = 0;
21
 
 
 
 
 
 
 
 
 
22
  if ( ! empty( $data['http'] ) ) {
23
  $statuses = array_keys( $data['types'] );
24
  $components = wp_list_pluck( $data['component_times'], 'component' );
156
 
157
  if ( ! empty( $row['redirected_to'] ) ) {
158
  $url .= sprintf(
159
+ '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%1$s</span><br>%2$s',
160
  /* translators: An HTTP API request redirected to another URL */
161
  __( 'Redirected to:', 'query-monitor' ),
162
  self::format_url( $row['redirected_to'] )
288
 
289
  echo '<tr>';
290
  printf(
291
+ '<td colspan="6">%s</td>',
292
  sprintf(
293
  /* translators: %s: Number of HTTP API requests */
294
  esc_html_x( 'Total: %s', 'HTTP API calls', 'query-monitor' ),
295
  '<span class="qm-items-number">' . esc_html( number_format_i18n( count( $data['http'] ) ) ) . '</span>'
296
+ )
 
297
  );
298
  echo '<td class="qm-num qm-items-time">' . esc_html( $total_stime ) . '</td>';
299
  echo '</tr>';
350
  $args['meta']['classname'] = 'qm-warning';
351
  }
352
 
353
+ $menu[ $this->collector->id() ] = $this->menu( $args );
354
 
355
  return $menu;
356
 
output/html/languages.php CHANGED
@@ -27,14 +27,13 @@ class QM_Output_Html_Languages extends QM_Output_Html {
27
  echo '<thead>';
28
  echo '<tr>';
29
  echo '<th scope="col">' . esc_html__( 'Text Domain', 'query-monitor' ) . '</th>';
 
30
  echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
31
- echo '<th scope="col">' . esc_html__( 'MO File', 'query-monitor' ) . '</th>';
32
  echo '<th scope="col">' . esc_html__( 'Size', 'query-monitor' ) . '</th>';
33
  echo '</tr>';
34
  echo '</thead>';
35
 
36
- $not_found_class = ( substr( $data['locale'], 0, 3 ) === 'en_' ) ? '' : 'qm-warn';
37
-
38
  echo '<tbody>';
39
 
40
  foreach ( $data['languages'] as $textdomain => $mofiles ) {
@@ -43,6 +42,8 @@ class QM_Output_Html_Languages extends QM_Output_Html {
43
 
44
  echo '<td class="qm-ltr">' . esc_html( $mofile['domain'] ) . '</td>';
45
 
 
 
46
  if ( self::has_clickable_links() ) {
47
  echo '<td class="qm-nowrap qm-ltr">';
48
  echo self::output_filename( $mofile['caller']['display'], $mofile['caller']['file'], $mofile['caller']['line'] ); // WPCS: XSS ok.
@@ -57,7 +58,11 @@ class QM_Output_Html_Languages extends QM_Output_Html {
57
  }
58
 
59
  echo '<td class="qm-ltr">';
60
- echo esc_html( QM_Util::standard_dir( $mofile['mofile'], '' ) );
 
 
 
 
61
  echo '</td>';
62
 
63
  if ( $mofile['found'] ) {
@@ -65,7 +70,7 @@ class QM_Output_Html_Languages extends QM_Output_Html {
65
  echo esc_html( size_format( $mofile['found'] ) );
66
  echo '</td>';
67
  } else {
68
- echo '<td class="' . esc_attr( $not_found_class ) . '">';
69
  echo esc_html__( 'Not Found', 'query-monitor' );
70
  echo '</td>';
71
  }
@@ -87,7 +92,7 @@ class QM_Output_Html_Languages extends QM_Output_Html {
87
  'title' => esc_html( $this->collector->name() ),
88
  );
89
 
90
- $menu[] = $this->menu( $args );
91
 
92
  return $menu;
93
 
27
  echo '<thead>';
28
  echo '<tr>';
29
  echo '<th scope="col">' . esc_html__( 'Text Domain', 'query-monitor' ) . '</th>';
30
+ echo '<th scope="col">' . esc_html__( 'Type', 'query-monitor' ) . '</th>';
31
  echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
32
+ echo '<th scope="col">' . esc_html__( 'Translation File', 'query-monitor' ) . '</th>';
33
  echo '<th scope="col">' . esc_html__( 'Size', 'query-monitor' ) . '</th>';
34
  echo '</tr>';
35
  echo '</thead>';
36
 
 
 
37
  echo '<tbody>';
38
 
39
  foreach ( $data['languages'] as $textdomain => $mofiles ) {
42
 
43
  echo '<td class="qm-ltr">' . esc_html( $mofile['domain'] ) . '</td>';
44
 
45
+ echo '<td>' . esc_html( $mofile['type'] ) . '</td>';
46
+
47
  if ( self::has_clickable_links() ) {
48
  echo '<td class="qm-nowrap qm-ltr">';
49
  echo self::output_filename( $mofile['caller']['display'], $mofile['caller']['file'], $mofile['caller']['line'] ); // WPCS: XSS ok.
58
  }
59
 
60
  echo '<td class="qm-ltr">';
61
+ if ( $mofile['file'] ) {
62
+ echo esc_html( QM_Util::standard_dir( $mofile['file'], '' ) );
63
+ } else {
64
+ echo '<em>' . esc_html__( 'None', 'query-monitor' ) . '</em>';
65
+ }
66
  echo '</td>';
67
 
68
  if ( $mofile['found'] ) {
70
  echo esc_html( size_format( $mofile['found'] ) );
71
  echo '</td>';
72
  } else {
73
+ echo '<td>';
74
  echo esc_html__( 'Not Found', 'query-monitor' );
75
  echo '</td>';
76
  }
92
  'title' => esc_html( $this->collector->name() ),
93
  );
94
 
95
+ $menu[ $this->collector->id() ] = $this->menu( $args );
96
 
97
  return $menu;
98
 
output/html/logger.php CHANGED
@@ -61,7 +61,7 @@ class QM_Output_Html_Logger extends QM_Output_Html {
61
  $class = '';
62
  }
63
 
64
- echo '<tr ' . $attr . 'class="' . esc_attr( $class ) . '">'; // WPCS: XSS ok.
65
 
66
  echo '<td scope="row" class="qm-nowrap">';
67
 
@@ -75,7 +75,7 @@ class QM_Output_Html_Logger extends QM_Output_Html {
75
  echo '</td>';
76
 
77
  printf(
78
- '<td>%s</td>',
79
  esc_html( $row['message'] )
80
  );
81
 
@@ -145,7 +145,7 @@ class QM_Output_Html_Logger extends QM_Output_Html {
145
  }
146
  }
147
 
148
- $menu[] = $this->menu( array(
149
  'id' => "query-monitor-logger-{$key}",
150
  'title' => esc_html__( 'Logs', 'query-monitor' ),
151
  ) );
61
  $class = '';
62
  }
63
 
64
+ echo '<tr' . $attr . ' class="' . esc_attr( $class ) . '">'; // WPCS: XSS ok.
65
 
66
  echo '<td scope="row" class="qm-nowrap">';
67
 
75
  echo '</td>';
76
 
77
  printf(
78
+ '<td><pre>%s</pre></td>',
79
  esc_html( $row['message'] )
80
  );
81
 
145
  }
146
  }
147
 
148
+ $menu[ $this->collector->id() ] = $this->menu( array(
149
  'id' => "query-monitor-logger-{$key}",
150
  'title' => esc_html__( 'Logs', 'query-monitor' ),
151
  ) );
output/html/overview.php CHANGED
@@ -54,12 +54,12 @@ class QM_Output_Html_Overview extends QM_Output_Html {
54
 
55
  echo '<section>';
56
  echo '<h3>' . esc_html__( 'Page Generation Time', 'query-monitor' ) . '</h3>';
57
- echo '<p class="qm-item">';
58
  echo esc_html( number_format_i18n( $data['time_taken'], 4 ) );
59
 
60
  if ( $data['time_limit'] > 0 ) {
61
  if ( $data['display_time_usage_warning'] ) {
62
- echo '<br><span class="qm-warn">';
63
  } else {
64
  echo '<br><span class="qm-info">';
65
  }
@@ -85,7 +85,7 @@ class QM_Output_Html_Overview extends QM_Output_Html {
85
 
86
  echo '<section>';
87
  echo '<h3>' . esc_html__( 'Peak Memory Usage', 'query-monitor' ) . '</h3>';
88
- echo '<p class="qm-item">';
89
 
90
  if ( empty( $data['memory'] ) ) {
91
  esc_html_e( 'Unknown', 'query-monitor' );
@@ -98,7 +98,7 @@ class QM_Output_Html_Overview extends QM_Output_Html {
98
 
99
  if ( $data['memory_limit'] > 0 ) {
100
  if ( $data['display_memory_usage_warning'] ) {
101
- echo '<br><span class="qm-warn">';
102
  } else {
103
  echo '<br><span class="qm-info">';
104
  }
@@ -127,19 +127,19 @@ class QM_Output_Html_Overview extends QM_Output_Html {
127
  if ( isset( $db_query_num ) ) {
128
  echo '<section>';
129
  echo '<h3>' . esc_html__( 'Database Query Time', 'query-monitor' ) . '</h3>';
130
- echo '<p class="qm-item">';
131
  echo esc_html( number_format_i18n( $db_queries_data['total_time'], 4 ) );
132
  echo '</p>';
133
  echo '</section>';
134
 
135
  echo '<section>';
136
  echo '<h3>' . esc_html__( 'Database Queries', 'query-monitor' ) . '</h3>';
137
- echo '<p class="qm-item">';
138
 
139
  if ( ! isset( $db_query_num['SELECT'] ) || count( $db_query_num ) > 1 ) {
140
  foreach ( $db_query_num as $type_name => $type_count ) {
141
  printf(
142
- '<a href="#" class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="type" data-qm-value="%1$s">%2$s: %3$s</a><br>',
143
  esc_attr( $type_name ),
144
  esc_html( $type_name ),
145
  esc_html( number_format_i18n( $type_count ) )
@@ -147,7 +147,11 @@ class QM_Output_Html_Overview extends QM_Output_Html {
147
  }
148
  }
149
 
150
- echo esc_html__( 'Total', 'query-monitor' ) . ': ' . esc_html( number_format_i18n( $db_queries_data['total_qs'] ) );
 
 
 
 
151
 
152
  echo '</p>';
153
  echo '</section>';
@@ -155,9 +159,9 @@ class QM_Output_Html_Overview extends QM_Output_Html {
155
 
156
  echo '<section>';
157
  echo '<h3>' . esc_html__( 'Object Cache', 'query-monitor' ) . '</h3>';
158
- echo '<p class="qm-item">';
159
 
160
  if ( isset( $cache_hit_percentage ) ) {
 
161
  echo esc_html( sprintf(
162
  /* translators: 1: Cache hit rate percentage, 2: number of cache hits, 3: number of cache misses */
163
  __( '%1$s%% hit rate (%2$s hits, %3$s misses)', 'query-monitor' ),
@@ -165,6 +169,7 @@ class QM_Output_Html_Overview extends QM_Output_Html {
165
  number_format_i18n( $cache_data['stats']['cache_hits'], 0 ),
166
  number_format_i18n( $cache_data['stats']['cache_misses'], 0 )
167
  ) );
 
168
  if ( $cache_data['display_hit_rate_warning'] ) {
169
  printf(
170
  '<br><a href="%s" class="qm-external-link">%s</a>',
@@ -172,31 +177,60 @@ class QM_Output_Html_Overview extends QM_Output_Html {
172
  esc_html__( 'Why is this value 100%?', 'query-monitor' )
173
  );
174
  }
175
- if ( $cache_data['ext_object_cache'] ) {
176
- echo '<br><span class="qm-info">';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  printf(
178
  '<a href="%s" class="qm-link">%s</a>',
179
  esc_url( network_admin_url( 'plugins.php?plugin_status=dropins' ) ),
180
  esc_html__( 'External object cache in use', 'query-monitor' )
181
  );
182
- echo '</span>';
183
  } else {
184
- echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
185
  echo esc_html__( 'External object cache not in use', 'query-monitor' );
186
- echo '</span>';
187
 
188
- $potentials = array_filter( $cache_data['extensions'] );
189
 
190
  if ( ! empty( $potentials ) ) {
191
  echo '<ul>';
192
  foreach ( $potentials as $name => $value ) {
193
- echo '<li class="qm-warn">';
194
  echo esc_html( sprintf(
195
  /* translators: %s: PHP extension name */
196
  __( 'The %s extension for PHP is installed but is not in use by WordPress', 'query-monitor' ),
197
  $name
198
  ) );
199
- echo '</li>';
200
  }
201
  echo '</ul>';
202
  }
@@ -207,7 +241,6 @@ class QM_Output_Html_Overview extends QM_Output_Html {
207
  echo '</span>';
208
  }
209
 
210
- echo '</p>';
211
  echo '</section>';
212
 
213
  $this->after_non_tabular_output();
54
 
55
  echo '<section>';
56
  echo '<h3>' . esc_html__( 'Page Generation Time', 'query-monitor' ) . '</h3>';
57
+ echo '<p>';
58
  echo esc_html( number_format_i18n( $data['time_taken'], 4 ) );
59
 
60
  if ( $data['time_limit'] > 0 ) {
61
  if ( $data['display_time_usage_warning'] ) {
62
+ echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
63
  } else {
64
  echo '<br><span class="qm-info">';
65
  }
85
 
86
  echo '<section>';
87
  echo '<h3>' . esc_html__( 'Peak Memory Usage', 'query-monitor' ) . '</h3>';
88
+ echo '<p>';
89
 
90
  if ( empty( $data['memory'] ) ) {
91
  esc_html_e( 'Unknown', 'query-monitor' );
98
 
99
  if ( $data['memory_limit'] > 0 ) {
100
  if ( $data['display_memory_usage_warning'] ) {
101
+ echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
102
  } else {
103
  echo '<br><span class="qm-info">';
104
  }
127
  if ( isset( $db_query_num ) ) {
128
  echo '<section>';
129
  echo '<h3>' . esc_html__( 'Database Query Time', 'query-monitor' ) . '</h3>';
130
+ echo '<p>';
131
  echo esc_html( number_format_i18n( $db_queries_data['total_time'], 4 ) );
132
  echo '</p>';
133
  echo '</section>';
134
 
135
  echo '<section>';
136
  echo '<h3>' . esc_html__( 'Database Queries', 'query-monitor' ) . '</h3>';
137
+ echo '<p>';
138
 
139
  if ( ! isset( $db_query_num['SELECT'] ) || count( $db_query_num ) > 1 ) {
140
  foreach ( $db_query_num as $type_name => $type_count ) {
141
  printf(
142
+ '<button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="type" data-qm-value="%1$s">%2$s: %3$s</button><br>',
143
  esc_attr( $type_name ),
144
  esc_html( $type_name ),
145
  esc_html( number_format_i18n( $type_count ) )
147
  }
148
  }
149
 
150
+ echo esc_html( sprintf(
151
+ /* translators: %s: Total number of database queries */
152
+ _x( 'Total: %s', 'database queries', 'query-monitor' ),
153
+ number_format_i18n( $db_queries_data['total_qs'] )
154
+ ) );
155
 
156
  echo '</p>';
157
  echo '</section>';
159
 
160
  echo '<section>';
161
  echo '<h3>' . esc_html__( 'Object Cache', 'query-monitor' ) . '</h3>';
 
162
 
163
  if ( isset( $cache_hit_percentage ) ) {
164
+ echo '<p>';
165
  echo esc_html( sprintf(
166
  /* translators: 1: Cache hit rate percentage, 2: number of cache hits, 3: number of cache misses */
167
  __( '%1$s%% hit rate (%2$s hits, %3$s misses)', 'query-monitor' ),
169
  number_format_i18n( $cache_data['stats']['cache_hits'], 0 ),
170
  number_format_i18n( $cache_data['stats']['cache_misses'], 0 )
171
  ) );
172
+
173
  if ( $cache_data['display_hit_rate_warning'] ) {
174
  printf(
175
  '<br><a href="%s" class="qm-external-link">%s</a>',
177
  esc_html__( 'Why is this value 100%?', 'query-monitor' )
178
  );
179
  }
180
+
181
+ echo '</p>';
182
+
183
+ $installed_opcode_caches = array_filter( $cache_data['opcode_cache_extensions'] );
184
+
185
+ if ( $cache_data['has_opcode_cache'] ) {
186
+ foreach ( $installed_opcode_caches as $opcache_name => $opcache_state ) {
187
+ echo '<p>';
188
+ echo esc_html( sprintf(
189
+ /* translators: %s: Name of cache driver */
190
+ __( 'Opcode cache in use: %s', 'query-monitor' ),
191
+ $opcache_name
192
+ ) );
193
+ echo '</p>';
194
+ }
195
+ } elseif ( ! empty( $installed_opcode_caches ) ) {
196
+ echo '<ul>';
197
+ foreach ( $installed_opcode_caches as $name => $value ) {
198
+ echo '<li><span class="qm-warn">';
199
+ echo esc_html( sprintf(
200
+ /* translators: %s: PHP opcode cache extension name */
201
+ __( 'The %s opcode cache is installed but not enabled', 'query-monitor' ),
202
+ $name
203
+ ) );
204
+ echo '</span></li>';
205
+ }
206
+ echo '</ul>';
207
+ }
208
+
209
+ if ( $cache_data['has_object_cache'] ) {
210
+ echo '<p><span class="qm-info">';
211
  printf(
212
  '<a href="%s" class="qm-link">%s</a>',
213
  esc_url( network_admin_url( 'plugins.php?plugin_status=dropins' ) ),
214
  esc_html__( 'External object cache in use', 'query-monitor' )
215
  );
216
+ echo '</span></p>';
217
  } else {
218
+ echo '<p><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
219
  echo esc_html__( 'External object cache not in use', 'query-monitor' );
220
+ echo '</span></p>';
221
 
222
+ $potentials = array_filter( $cache_data['object_cache_extensions'] );
223
 
224
  if ( ! empty( $potentials ) ) {
225
  echo '<ul>';
226
  foreach ( $potentials as $name => $value ) {
227
+ echo '<li><span class="qm-warn">';
228
  echo esc_html( sprintf(
229
  /* translators: %s: PHP extension name */
230
  __( 'The %s extension for PHP is installed but is not in use by WordPress', 'query-monitor' ),
231
  $name
232
  ) );
233
+ echo '</span></li>';
234
  }
235
  echo '</ul>';
236
  }
241
  echo '</span>';
242
  }
243
 
 
244
  echo '</section>';
245
 
246
  $this->after_non_tabular_output();
output/html/php_errors.php CHANGED
@@ -231,7 +231,7 @@ class QM_Output_Html_PHP_Errors extends QM_Output_Html {
231
  $title = __( 'PHP Errors', 'query-monitor' );
232
  }
233
 
234
- $menu['php_errors'] = $this->menu( array(
235
  'id' => "query-monitor-{$key}s",
236
  'title' => $title,
237
  ) );
@@ -240,8 +240,8 @@ class QM_Output_Html_PHP_Errors extends QM_Output_Html {
240
  }
241
 
242
  public function panel_menu( array $menu ) {
243
- if ( isset( $menu['php_errors'] ) ) {
244
- $menu['php_errors']['title'] = __( 'PHP Errors', 'query-monitor' );
245
  }
246
 
247
  return $menu;
231
  $title = __( 'PHP Errors', 'query-monitor' );
232
  }
233
 
234
+ $menu[ $this->collector->id() ] = $this->menu( array(
235
  'id' => "query-monitor-{$key}s",
236
  'title' => $title,
237
  ) );
240
  }
241
 
242
  public function panel_menu( array $menu ) {
243
+ if ( isset( $menu[ $this->collector->id() ] ) ) {
244
+ $menu[ $this->collector->id() ]['title'] = __( 'PHP Errors', 'query-monitor' );
245
  }
246
 
247
  return $menu;
output/html/request.php CHANGED
@@ -79,7 +79,7 @@ class QM_Output_Html_Request extends QM_Output_Html {
79
  $db_queries_data = $db_queries->get_data();
80
  if ( ! empty( $db_queries_data['dbs']['$wpdb']->has_main_query ) ) {
81
  printf(
82
- '<p><a href="#" class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="qm-main-query">%s</a></p>',
83
  esc_html__( 'View Main Query', 'query-monitor' )
84
  );
85
  }
@@ -176,7 +176,7 @@ class QM_Output_Html_Request extends QM_Output_Html {
176
  /* translators: %s: Number of additional query variables */
177
  : __( 'Request (+%s)', 'query-monitor' );
178
 
179
- $menu[] = $this->menu( array(
180
  'title' => esc_html( sprintf(
181
  $title,
182
  number_format_i18n( $count )
79
  $db_queries_data = $db_queries->get_data();
80
  if ( ! empty( $db_queries_data['dbs']['$wpdb']->has_main_query ) ) {
81
  printf(
82
+ '<p><button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="qm-main-query">%s</button></p>',
83
  esc_html__( 'View Main Query', 'query-monitor' )
84
  );
85
  }
176
  /* translators: %s: Number of additional query variables */
177
  : __( 'Request (+%s)', 'query-monitor' );
178
 
179
+ $menu[ $this->collector->id() ] = $this->menu( array(
180
  'title' => esc_html( sprintf(
181
  $title,
182
  number_format_i18n( $count )
output/html/theme.php CHANGED
@@ -104,7 +104,7 @@ class QM_Output_Html_Theme extends QM_Output_Html {
104
 
105
  if ( ! empty( $data['timber_files'] ) ) {
106
  echo '<section>';
107
- echo '<h3>' . esc_html__( 'Timber Files', 'query-monitor' ) . '</h3>';
108
  echo '<ul class="qm-ltr">';
109
 
110
  foreach ( $data['timber_files'] as $filename ) {
@@ -142,7 +142,7 @@ class QM_Output_Html_Theme extends QM_Output_Html {
142
  $name = __( 'Unknown', 'query-monitor' );
143
  }
144
 
145
- $menu['theme'] = $this->menu( array(
146
  'title' => esc_html( sprintf(
147
  /* translators: %s: Template file name */
148
  __( 'Template: %s', 'query-monitor' ),
@@ -155,8 +155,8 @@ class QM_Output_Html_Theme extends QM_Output_Html {
155
  }
156
 
157
  public function panel_menu( array $menu ) {
158
- if ( isset( $menu['theme'] ) ) {
159
- $menu['theme']['title'] = __( 'Template', 'query-monitor' );
160
  }
161
 
162
  return $menu;
104
 
105
  if ( ! empty( $data['timber_files'] ) ) {
106
  echo '<section>';
107
+ echo '<h3>' . esc_html__( 'Twig Template Files', 'query-monitor' ) . '</h3>';
108
  echo '<ul class="qm-ltr">';
109
 
110
  foreach ( $data['timber_files'] as $filename ) {
142
  $name = __( 'Unknown', 'query-monitor' );
143
  }
144
 
145
+ $menu[ $this->collector->id() ] = $this->menu( array(
146
  'title' => esc_html( sprintf(
147
  /* translators: %s: Template file name */
148
  __( 'Template: %s', 'query-monitor' ),
155
  }
156
 
157
  public function panel_menu( array $menu ) {
158
+ if ( isset( $menu[ $this->collector->id() ] ) ) {
159
+ $menu[ $this->collector->id() ]['title'] = __( 'Template', 'query-monitor' );
160
  }
161
 
162
  return $menu;
output/html/timing.php CHANGED
@@ -125,7 +125,7 @@ class QM_Output_Html_Timing extends QM_Output_Html {
125
  }
126
 
127
  printf(
128
- '<td colspan="2">%s</td>',
129
  esc_html( $row['message'] )
130
  );
131
 
@@ -154,7 +154,8 @@ class QM_Output_Html_Timing extends QM_Output_Html {
154
  }
155
  /* translators: %s: Number of function timing results that are available */
156
  $label = _n( 'Timings (%s)', 'Timings (%s)', $count, 'query-monitor' );
157
- $menu[] = $this->menu( array(
 
158
  'title' => esc_html( sprintf(
159
  $label,
160
  number_format_i18n( $count )
125
  }
126
 
127
  printf(
128
+ '<td colspan="2"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%s</td>',
129
  esc_html( $row['message'] )
130
  );
131
 
154
  }
155
  /* translators: %s: Number of function timing results that are available */
156
  $label = _n( 'Timings (%s)', 'Timings (%s)', $count, 'query-monitor' );
157
+
158
+ $menu[ $this->collector->id() ] = $this->menu( array(
159
  'title' => esc_html( sprintf(
160
  $label,
161
  number_format_i18n( $count )
output/html/transients.php CHANGED
@@ -124,7 +124,7 @@ class QM_Output_Html_Transients extends QM_Output_Html {
124
  /* translators: %s: Number of transient values that were updated */
125
  : __( 'Transient Updates (%s)', 'query-monitor' );
126
 
127
- $menu[] = $this->menu( array(
128
  'title' => esc_html( sprintf(
129
  $title,
130
  number_format_i18n( $count )
124
  /* translators: %s: Number of transient values that were updated */
125
  : __( 'Transient Updates (%s)', 'query-monitor' );
126
 
127
+ $menu[ $this->collector->id() ] = $this->menu( array(
128
  'title' => esc_html( sprintf(
129
  $title,
130
  number_format_i18n( $count )
query-monitor.php CHANGED
@@ -5,14 +5,14 @@
5
  * @package query-monitor
6
  * @link https://github.com/johnbillion/query-monitor
7
  * @author John Blackbourn <john@johnblackbourn.com>
8
- * @copyright 2009-2018 John Blackbourn
9
  * @license GPL v2 or later
10
  *
11
  * Plugin Name: Query Monitor
12
  * Description: The Developer Tools Panel for WordPress.
13
- * Version: 3.2.2
14
  * Plugin URI: https://querymonitor.com/
15
- * Author: John Blackbourn & contributors
16
  * Author URI: https://querymonitor.com/
17
  * Text Domain: query-monitor
18
  * Domain Path: /languages/
5
  * @package query-monitor
6
  * @link https://github.com/johnbillion/query-monitor
7
  * @author John Blackbourn <john@johnblackbourn.com>
8
+ * @copyright 2009-2019 John Blackbourn
9
  * @license GPL v2 or later
10
  *
11
  * Plugin Name: Query Monitor
12
  * Description: The Developer Tools Panel for WordPress.
13
+ * Version: 3.3.0
14
  * Plugin URI: https://querymonitor.com/
15
+ * Author: John Blackbourn
16
  * Author URI: https://querymonitor.com/
17
  * Text Domain: query-monitor
18
  * Domain Path: /languages/
readme.txt CHANGED
@@ -1,103 +1,103 @@
1
- === Query Monitor ===
2
- Contributors: johnbillion
3
- Tags: debug, debug-bar, debugging, development, developer, performance, profiler, queries, query monitor, rest-api
4
- Requires at least: 3.7
5
- Tested up to: 5.0
6
- Stable tag: 3.2.2
7
- License: GPLv2 or later
8
- Requires PHP: 5.3
9
-
10
- Query Monitor is the developer tools panel for WordPress.
11
-
12
- == Description ==
13
-
14
- Query Monitor is the developer tools panel for WordPress. It enables debugging of database queries, PHP errors, hooks and actions, block editor blocks, enqueued scripts and stylesheets, HTTP API calls, and more.
15
-
16
- It includes some advanced features such as debugging of Ajax calls, REST API calls, and user capability checks. It includes the ability to narrow down much of its output by plugin or theme, allowing you to quickly determine poorly performing plugins, themes, or functions.
17
-
18
- Query Monitor focuses heavily on presenting its information in a useful manner, for example by showing aggregate database queries grouped by the plugins, themes, or functions that are responsible for them. It adds an admin toolbar menu showing an overview of the current page, with complete debugging information shown in panels once you select a menu item.
19
-
20
- For complete information, please see [the Query Monitor website](https://querymonitor.com/).
21
-
22
- Here's an overview of what's shown for each page load:
23
-
24
- * Database queries, including notifications for slow, duplicate, or erroneous queries. Allows filtering by query type (`SELECT`, `UPDATE`, `DELETE`, etc), responsible component (plugin, theme, WordPress core), and calling function, and provides separate aggregate views for each.
25
- * The template filename, the complete template hierarchy, and names of all template parts used.
26
- * PHP errors presented nicely along with their responsible component and call stack, and a visible warning in the admin toolbar.
27
- * Blocks and associated properties in post content when using WordPress 5.0+ or the Gutenberg plugin.
28
- * Matched rewrite rules, associated query strings, and query vars.
29
- * Enqueued scripts and stylesheets, along with their dependencies, dependents, and alerts for broken dependencies.
30
- * Language settings and loaded translation files (MO files) for each text domain.
31
- * HTTP API requests, with response code, responsible component, and time taken, with alerts for failed or erroneous requests.
32
- * User capability checks, along with the result and any parameters passed to the capability check.
33
- * Environment information, including detailed information about PHP, the database, WordPress, and the web server.
34
- * The values of all WordPress conditional functions such as `is_single()`, `is_home()`, etc.
35
- * Transients that were updated.
36
-
37
- In addition:
38
-
39
- * Whenever a redirect occurs, Query Monitor adds an HTTP header containing the call stack, so you can use your favourite HTTP inspector or browser developer tools to trace what triggered the redirect.
40
- * The response from any jQuery-initiated Ajax request on the page will contain various debugging information in its headers. PHP errors also get output to the browser's developer console.
41
- * The response from an authenticated WordPress REST API request will contain various debugging information in its headers, as long as the authenticated user has permission to view Query Monitor's output.
42
-
43
- By default, Query Monitor's output is only shown to Administrators on single-site installations, and Super Admins on Multisite installations.
44
-
45
- In addition to this, you can set an authentication cookie which allows you to view Query Monitor output when you're not logged in (or if you're logged in as a non-Administrator). See the Settings panel for details.
46
-
47
- = Privacy Statement =
48
-
49
- Query Monitor does not persistently store any of the data that it collects. It does not send data to any third party, nor does it include any third party resources.
50
-
51
- [Query Monitor's full privacy statement can be found here](https://github.com/johnbillion/query-monitor/wiki/Privacy-Statement).
52
-
53
- == Screenshots ==
54
-
55
- 1. The admin toolbar menu showing an overview
56
- 2. Aggregate database queries by component
57
- 3. User capability checks with an active filter
58
- 4. Database queries complete with filter controls
59
- 5. Hooks and actions
60
- 6. HTTP requests (showing an HTTP error)
61
- 7. Aggregate database queries grouped by calling function
62
-
63
- == Frequently Asked Questions ==
64
-
65
- = Who can see Query Monitor's output? =
66
-
67
- By default, Query Monitor's output is only shown to Administrators on single-site installations, and Super Admins on Multisite installations.
68
-
69
- In addition to this, you can set an authentication cookie which allows you to view Query Monitor output when you're not logged in (or if you're logged in as a non-Administrator). See the Settings panel for details.
70
-
71
- = Does Query Monitor itself impact the page generation time or memory usage? =
72
-
73
- Short answer: Yes, but only a little.
74
-
75
- Long answer: Query Monitor has a small impact on page generation time because it hooks into WordPress in the same way that other plugins do. The impact is low; typically between 10ms and 100ms depending on the complexity of your site.
76
-
77
- Query Monitor's memory usage typically accounts for around 10% of the total memory used to generate the page.
78
-
79
- = Are there any add-on plugins for Query Monitor? =
80
-
81
- [A list of add-on plugins for Query Monitor can be found here.](https://github.com/johnbillion/query-monitor/wiki/Query-Monitor-Add-on-Plugins)
82
-
83
- In addition, Query Monitor transparently supports add-ons for the Debug Bar plugin. If you have any Debug Bar add-ons installed, just deactivate Debug Bar and the add-ons will show up in Query Monitor's menu.
84
-
85
- = Where can I suggest a new feature or report a bug? =
86
-
87
- Please use [the issue tracker on Query Monitor's GitHub repo](https://github.com/johnbillion/query-monitor/issues) as it's easier to keep track of issues there, rather than on the wordpress.org support forums.
88
-
89
- = Is Query Monitor available on WordPress.com VIP Go? =
90
-
91
- Yep! You just need to add `define( 'WPCOM_VIP_QM_ENABLE', true );` to your `vip-config/vip-config.php` file.
92
-
93
- = I'm using multiple instances of `wpdb`. How do I get my additional instances to show up in Query Monitor? =
94
-
95
- You'll need to hook into the `qm/collect/db_objects` filter and add an item to the array with your connection name as the key and the `wpdb` instance as the value. Your `wpdb` instance will then show up as a separate panel, and the query time and query count will show up separately in the admin toolbar menu. Aggregate information (queries by caller and component) will not be separated.
96
-
97
- = Do you accept donations? =
98
-
99
- No, I do not accept donations. If you like the plugin, I'd love for you to [leave a review](https://wordpress.org/support/view/plugin-reviews/query-monitor). Tell all your friends about the plugin too!
100
-
101
- == Changelog ==
102
-
103
- For Query Monitor's changelog, please see [the Releases page on GitHub](https://github.com/johnbillion/query-monitor/releases).
1
+ === Query Monitor ===
2
+ Contributors: johnbillion
3
+ Tags: debug, debug-bar, debugging, development, developer, performance, profiler, queries, query monitor, rest-api
4
+ Requires at least: 3.7
5
+ Tested up to: 5.1
6
+ Stable tag: 3.3.0
7
+ License: GPLv2 or later
8
+ Requires PHP: 5.3
9
+
10
+ Query Monitor is the developer tools panel for WordPress.
11
+
12
+ == Description ==
13
+
14
+ Query Monitor is the developer tools panel for WordPress. It enables debugging of database queries, PHP errors, hooks and actions, block editor blocks, enqueued scripts and stylesheets, HTTP API calls, and more.
15
+
16
+ It includes some advanced features such as debugging of Ajax calls, REST API calls, and user capability checks. It includes the ability to narrow down much of its output by plugin or theme, allowing you to quickly determine poorly performing plugins, themes, or functions.
17
+
18
+ Query Monitor focuses heavily on presenting its information in a useful manner, for example by showing aggregate database queries grouped by the plugins, themes, or functions that are responsible for them. It adds an admin toolbar menu showing an overview of the current page, with complete debugging information shown in panels once you select a menu item.
19
+
20
+ For complete information, please see [the Query Monitor website](https://querymonitor.com/).
21
+
22
+ Here's an overview of what's shown for each page load:
23
+
24
+ * Database queries, including notifications for slow, duplicate, or erroneous queries. Allows filtering by query type (`SELECT`, `UPDATE`, `DELETE`, etc), responsible component (plugin, theme, WordPress core), and calling function, and provides separate aggregate views for each.
25
+ * The template filename, the complete template hierarchy, and names of all template parts used.
26
+ * PHP errors presented nicely along with their responsible component and call stack, and a visible warning in the admin toolbar.
27
+ * Blocks and associated properties in post content when using WordPress 5.0+ or the Gutenberg plugin.
28
+ * Matched rewrite rules, associated query strings, and query vars.
29
+ * Enqueued scripts and stylesheets, along with their dependencies, dependents, and alerts for broken dependencies.
30
+ * Language settings and loaded translation files (MO files) for each text domain.
31
+ * HTTP API requests, with response code, responsible component, and time taken, with alerts for failed or erroneous requests.
32
+ * User capability checks, along with the result and any parameters passed to the capability check.
33
+ * Environment information, including detailed information about PHP, the database, WordPress, and the web server.
34
+ * The values of all WordPress conditional functions such as `is_single()`, `is_home()`, etc.
35
+ * Transients that were updated.
36
+
37
+ In addition:
38
+
39
+ * Whenever a redirect occurs, Query Monitor adds an HTTP header containing the call stack, so you can use your favourite HTTP inspector or browser developer tools to trace what triggered the redirect.
40
+ * The response from any jQuery-initiated Ajax request on the page will contain various debugging information in its headers. PHP errors also get output to the browser's developer console.
41
+ * The response from an authenticated WordPress REST API request will contain various debugging information in its headers, as long as the authenticated user has permission to view Query Monitor's output.
42
+
43
+ By default, Query Monitor's output is only shown to Administrators on single-site installations, and Super Admins on Multisite installations.
44
+
45
+ In addition to this, you can set an authentication cookie which allows you to view Query Monitor output when you're not logged in (or if you're logged in as a non-Administrator). See the Settings panel for details.
46
+
47
+ = Privacy Statement =
48
+
49
+ Query Monitor does not persistently store any of the data that it collects. It does not send data to any third party, nor does it include any third party resources.
50
+
51
+ [Query Monitor's full privacy statement can be found here](https://github.com/johnbillion/query-monitor/wiki/Privacy-Statement).
52
+
53
+ == Screenshots ==
54
+
55
+ 1. The admin toolbar menu showing an overview
56
+ 2. Aggregate database queries by component
57
+ 3. User capability checks with an active filter
58
+ 4. Database queries complete with filter controls
59
+ 5. Hooks and actions
60
+ 6. HTTP requests (showing an HTTP error)
61
+ 7. Aggregate database queries grouped by calling function
62
+
63
+ == Frequently Asked Questions ==
64
+
65
+ = Who can see Query Monitor's output? =
66
+
67
+ By default, Query Monitor's output is only shown to Administrators on single-site installations, and Super Admins on Multisite installations.
68
+
69
+ In addition to this, you can set an authentication cookie which allows you to view Query Monitor output when you're not logged in (or if you're logged in as a non-Administrator). See the Settings panel for details.
70
+
71
+ = Does Query Monitor itself impact the page generation time or memory usage? =
72
+
73
+ Short answer: Yes, but only a little.
74
+
75
+ Long answer: Query Monitor has a small impact on page generation time because it hooks into WordPress in the same way that other plugins do. The impact is low; typically between 10ms and 100ms depending on the complexity of your site.
76
+
77
+ Query Monitor's memory usage typically accounts for around 10% of the total memory used to generate the page.
78
+
79
+ = Are there any add-on plugins for Query Monitor? =
80
+
81
+ [A list of add-on plugins for Query Monitor can be found here.](https://github.com/johnbillion/query-monitor/wiki/Query-Monitor-Add-on-Plugins)
82
+
83
+ In addition, Query Monitor transparently supports add-ons for the Debug Bar plugin. If you have any Debug Bar add-ons installed, just deactivate Debug Bar and the add-ons will show up in Query Monitor's menu.
84
+
85
+ = Where can I suggest a new feature or report a bug? =
86
+
87
+ Please use [the issue tracker on Query Monitor's GitHub repo](https://github.com/johnbillion/query-monitor/issues) as it's easier to keep track of issues there, rather than on the wordpress.org support forums.
88
+
89
+ = Is Query Monitor available on WordPress.com VIP Go? =
90
+
91
+ Yep! You just need to add `define( 'WPCOM_VIP_QM_ENABLE', true );` to your `vip-config/vip-config.php` file.
92
+
93
+ = I'm using multiple instances of `wpdb`. How do I get my additional instances to show up in Query Monitor? =
94
+
95
+ You'll need to hook into the `qm/collect/db_objects` filter and add an item to the array with your connection name as the key and the `wpdb` instance as the value. Your `wpdb` instance will then show up as a separate panel, and the query time and query count will show up separately in the admin toolbar menu. Aggregate information (queries by caller and component) will not be separated.
96
+
97
+ = Do you accept donations? =
98
+
99
+ No, I do not accept donations. If you like the plugin, I'd love for you to [leave a review](https://wordpress.org/support/view/plugin-reviews/query-monitor). Tell all your friends about the plugin too!
100
+
101
+ == Changelog ==
102
+
103
+ For Query Monitor's changelog, please see [the Releases page on GitHub](https://github.com/johnbillion/query-monitor/releases).
wp-content/db.php CHANGED
@@ -135,5 +135,5 @@ class QM_DB extends wpdb {
135
 
136
  }
137
 
138
- // phpcs:ignore WordPress.WP.GlobalVariablesOverride.OverrideProhibited
139
  $wpdb = new QM_DB( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
135
 
136
  }
137
 
138
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
139
  $wpdb = new QM_DB( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );