From 96f14524827802290833690bb4a20231cbcc8633 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Tue, 19 Feb 2019 00:27:14 -0500 Subject: [PATCH 01/22] init implementation of johnbillion/query-monitor#405 (third option) --- assets/query-monitor.css | 3 +- collectors/hooks.php | 46 +++++++++++++++++++++++++++ output/html/hooks.php | 67 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/assets/query-monitor.css b/assets/query-monitor.css index 1af641606..6dfc5072d 100644 --- a/assets/query-monitor.css +++ b/assets/query-monitor.css @@ -539,7 +539,8 @@ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover font-size: 14px !important; margin: 20px !important; } -#query-monitor-main .qm-concerns table { +#query-monitor-main .qm-concerns table, +#query-monitor-main .qm-discovered table { border-top: 1px solid #e0e0e0 !important; margin-bottom: 20px !important; } diff --git a/collectors/hooks.php b/collectors/hooks.php index 99f37a649..e07cb317d 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -14,6 +14,52 @@ public function name() { return __( 'Hooks & Actions', 'query-monitor' ); } + public function __construct() { + parent::__construct(); + add_action( 'qm/listen/start', array( $this, 'action_function_listen_start' ), 10, 1 ); + add_action( 'qm/listen/stop', array( $this, 'action_function_listen_stop' ), 10, 1 ); + } + + public function action_function_listen_start( $label ) { + if ( !array_key_exists( 'discovered_hooks', $this->data ) ) + $this->data['discovered_hooks'] = array(); + + if ( array_key_exists( $label, $this->data['discovered_hooks'] ) ) + return; + + $this->data['discovered_hooks'][$label] = array(); + + add_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); + } + + public function action_function_listen_all( $var ) { + if ( in_array( current_action(), array( + 'qm/listen/start', + 'qm/listen/stop', + ) ) ) + return; + + end( $this->data['discovered_hooks'] ); + $label = key( $this->data['discovered_hooks'] ); + $last = end( $this->data['discovered_hooks'][$label] ); + + if ( current_action() === $last['action'] ) { + $i = key( $this->data['discovered_hooks'][$label] ); + $this->data['discovered_hooks'][$label][$i]['count']++; + } else { + $this->data['discovered_hooks'][$label][] = array( + 'action' => current_action(), + 'count' => 1, + ); + } + + return $var; + } + + public function action_function_listen_stop( $label ) { + remove_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); + } + public function process() { global $wp_actions, $wp_filter; diff --git a/output/html/hooks.php b/output/html/hooks.php index 9bda68c06..749dc5c4f 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -11,9 +11,24 @@ class QM_Output_Html_Hooks extends QM_Output_Html { public function __construct( QM_Collector $collector ) { parent::__construct( $collector ); + add_filter( 'qm/output/panel_menus', array( $this, 'panel_menus' ) ); add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 80 ); } + public function panel_menus( $panel_menu ) { + $data = $this->collector->get_data(); + + if ( empty( $data['discovered_hooks'] ) ) + return; + + $panel_menu[ 'qm-' . $this->id ]['children'][ 'qm-' . $this->id . '-discovered_hooks' ] = array( + 'href' => esc_attr( '#' . $this->collector->id() . '-discovered_hooks' ), + 'title' => '└ ' . __( 'Discovered Hooks', 'query-monitor' ), + ); + + return $panel_menu; + } + public function output() { $data = $this->collector->get_data(); @@ -178,6 +193,58 @@ public static function output_hook_table( array $hooks ) { } + protected function after_tabular_output() { + echo ''; + echo ''; + + $this->output_discovered(); + } + + function output_discovered() { + printf( + '
', + esc_attr( $this->current_id . '-discovered_hooks' ) + ); + + echo '
'; + + printf( + '', + esc_attr( $this->current_id . '-discovered_hooks' ), + esc_html__( 'Discovered Hooks', 'query-monitor' ) + ); + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + + $data = $this->collector->get_data(); + + foreach ( $data['discovered_hooks'] as $label => $hooks ) { + foreach ( $hooks as $i => $hook ) { + echo ''; + + if ( 0 === $i ) + echo ''; + + echo ''; + echo ''; + echo ''; + } + } + + echo ''; + echo '

%2$s

' . esc_html__( 'Label', 'query-monitor' ) . '' . esc_html__( 'Hook', 'query-monitor' ) . '' . esc_html__( 'Successive Uses', 'query-monitor' ) . '
' . esc_html( $label ) . '' . esc_html( $hook['action'] ) . '' . esc_html( $hook['count'] ) . '
'; + + echo '
'; + } + } function register_qm_output_html_hooks( array $output, QM_Collectors $collectors ) { From a8fc8f785be35a9ac559e87f7401ef2daa15d151 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Tue, 19 Feb 2019 00:34:16 -0500 Subject: [PATCH 02/22] return variable for filter --- output/html/hooks.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/output/html/hooks.php b/output/html/hooks.php index 749dc5c4f..8a688d5d5 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -18,8 +18,9 @@ public function __construct( QM_Collector $collector ) { public function panel_menus( $panel_menu ) { $data = $this->collector->get_data(); - if ( empty( $data['discovered_hooks'] ) ) - return; + if ( empty( $data['discovered_hooks'] ) ) { + return $panel_menu; + } $panel_menu[ 'qm-' . $this->id ]['children'][ 'qm-' . $this->id . '-discovered_hooks' ] = array( 'href' => esc_attr( '#' . $this->collector->id() . '-discovered_hooks' ), From 174afeaed6097bf75d105fad8883fc985002578f Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Tue, 19 Feb 2019 00:34:27 -0500 Subject: [PATCH 03/22] follow code guidelines --- collectors/hooks.php | 11 +++++++---- output/html/hooks.php | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index e07cb317d..5373b6314 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -21,11 +21,13 @@ public function __construct() { } public function action_function_listen_start( $label ) { - if ( !array_key_exists( 'discovered_hooks', $this->data ) ) + if ( !array_key_exists( 'discovered_hooks', $this->data ) ) { $this->data['discovered_hooks'] = array(); + } - if ( array_key_exists( $label, $this->data['discovered_hooks'] ) ) + if ( array_key_exists( $label, $this->data['discovered_hooks'] ) ) { return; + } $this->data['discovered_hooks'][$label] = array(); @@ -36,8 +38,9 @@ public function action_function_listen_all( $var ) { if ( in_array( current_action(), array( 'qm/listen/start', 'qm/listen/stop', - ) ) ) - return; + ) ) ) { + return $var; + } end( $this->data['discovered_hooks'] ); $label = key( $this->data['discovered_hooks'] ); diff --git a/output/html/hooks.php b/output/html/hooks.php index 8a688d5d5..3b2a40339 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -231,8 +231,9 @@ function output_discovered() { foreach ( $hooks as $i => $hook ) { echo ''; - if ( 0 === $i ) + if ( 0 === $i ) { echo '' . esc_html( $label ) . ''; + } echo '' . esc_html( $hook['action'] ) . ''; echo '' . esc_html( $hook['count'] ) . ''; From 5acbe408641e1862f4bd7bbe27af09d15aa87f2f Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Tue, 19 Feb 2019 00:39:17 -0500 Subject: [PATCH 04/22] more code guidelines --- collectors/hooks.php | 16 ++++++++-------- output/html/hooks.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index 5373b6314..7ec8e0f94 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -17,11 +17,11 @@ public function name() { public function __construct() { parent::__construct(); add_action( 'qm/listen/start', array( $this, 'action_function_listen_start' ), 10, 1 ); - add_action( 'qm/listen/stop', array( $this, 'action_function_listen_stop' ), 10, 1 ); + add_action( 'qm/listen/stop', array( $this, 'action_function_listen_stop' ), 10, 1 ); } public function action_function_listen_start( $label ) { - if ( !array_key_exists( 'discovered_hooks', $this->data ) ) { + if ( ! array_key_exists( 'discovered_hooks', $this->data ) ) { $this->data['discovered_hooks'] = array(); } @@ -29,7 +29,7 @@ public function action_function_listen_start( $label ) { return; } - $this->data['discovered_hooks'][$label] = array(); + $this->data['discovered_hooks'][ $label ] = array(); add_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); } @@ -42,15 +42,15 @@ public function action_function_listen_all( $var ) { return $var; } - end( $this->data['discovered_hooks'] ); + end( $this->data['discovered_hooks'] ); $label = key( $this->data['discovered_hooks'] ); - $last = end( $this->data['discovered_hooks'][$label] ); + $last = end( $this->data['discovered_hooks'][ $label ] ); if ( current_action() === $last['action'] ) { - $i = key( $this->data['discovered_hooks'][$label] ); - $this->data['discovered_hooks'][$label][$i]['count']++; + $i = key( $this->data['discovered_hooks'][ $label ] ); + $this->data['discovered_hooks'][ $label ][ $i ]['count']++; } else { - $this->data['discovered_hooks'][$label][] = array( + $this->data['discovered_hooks'][ $label ][] = array( 'action' => current_action(), 'count' => 1, ); diff --git a/output/html/hooks.php b/output/html/hooks.php index 3b2a40339..b8da9109f 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -201,7 +201,7 @@ protected function after_tabular_output() { $this->output_discovered(); } - function output_discovered() { + public function output_discovered() { printf( '
', esc_attr( $this->current_id . '-discovered_hooks' ) From fd339b20752002a7d9394b99eeee12afd33585e5 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Tue, 19 Feb 2019 00:41:33 -0500 Subject: [PATCH 05/22] change key name --- collectors/hooks.php | 4 ++-- output/html/hooks.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index 7ec8e0f94..666574f9c 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -46,12 +46,12 @@ public function action_function_listen_all( $var ) { $label = key( $this->data['discovered_hooks'] ); $last = end( $this->data['discovered_hooks'][ $label ] ); - if ( current_action() === $last['action'] ) { + if ( current_action() === $last['hook'] ) { $i = key( $this->data['discovered_hooks'][ $label ] ); $this->data['discovered_hooks'][ $label ][ $i ]['count']++; } else { $this->data['discovered_hooks'][ $label ][] = array( - 'action' => current_action(), + 'hook' => current_action(), 'count' => 1, ); } diff --git a/output/html/hooks.php b/output/html/hooks.php index b8da9109f..d198a9e0a 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -235,7 +235,7 @@ public function output_discovered() { echo '' . esc_html( $label ) . ''; } - echo '' . esc_html( $hook['action'] ) . ''; + echo '' . esc_html( $hook['hook'] ) . ''; echo '' . esc_html( $hook['count'] ) . ''; echo ''; } From 32857cb3fc242b1ceb847e43f64aad0215e0fca4 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Tue, 19 Feb 2019 00:43:35 -0500 Subject: [PATCH 06/22] add selector to SCSS --- assets/_styles.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/_styles.scss b/assets/_styles.scss index c08994b2c..1f2408880 100644 --- a/assets/_styles.scss +++ b/assets/_styles.scss @@ -590,7 +590,8 @@ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover margin: 20px !important; } - .qm-concerns table { + .qm-concerns table, + .qm-discovered table { border-top: 1px solid $qm-cell-border !important; margin-bottom: 20px !important; } From f4ee2a01527eb79d45a6b350282cf7c482023e5d Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 01:18:55 -0500 Subject: [PATCH 07/22] improve print of number of successive hook fires --- output/html/hooks.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/output/html/hooks.php b/output/html/hooks.php index d198a9e0a..552e92b3e 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -235,7 +235,13 @@ public function output_discovered() { echo '' . esc_html( $label ) . ''; } - echo '' . esc_html( $hook['hook'] ) . ''; + echo ''; + echo '' . esc_html( $hook['hook'] ) . ''; + + if ( 1 < $hook['count'] ) { + echo '
Fired ' . esc_html( $hook['count'] ) . ' times'; + } + echo ''; echo '' . esc_html( $hook['count'] ) . ''; echo ''; } From 241ee681f2ca9449353834f365b0b54198943941 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 01:33:57 -0500 Subject: [PATCH 08/22] print hook type --- collectors/hooks.php | 3 +++ output/html/hooks.php | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index 666574f9c..21e0dab6e 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -42,6 +42,8 @@ public function action_function_listen_all( $var ) { return $var; } + global $wp_actions; + end( $this->data['discovered_hooks'] ); $label = key( $this->data['discovered_hooks'] ); $last = end( $this->data['discovered_hooks'][ $label ] ); @@ -51,6 +53,7 @@ public function action_function_listen_all( $var ) { $this->data['discovered_hooks'][ $label ][ $i ]['count']++; } else { $this->data['discovered_hooks'][ $label ][] = array( + 'is_action' => array_key_exists( current_action(), $wp_actions ), 'hook' => current_action(), 'count' => 1, ); diff --git a/output/html/hooks.php b/output/html/hooks.php index 552e92b3e..e647b2128 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -219,7 +219,7 @@ public function output_discovered() { echo ''; echo '' . esc_html__( 'Label', 'query-monitor' ) . ''; echo '' . esc_html__( 'Hook', 'query-monitor' ) . ''; - echo '' . esc_html__( 'Successive Uses', 'query-monitor' ) . ''; + echo '' . esc_html__( 'Type', 'query-monitor' ) . ''; echo ''; echo ''; @@ -242,7 +242,7 @@ public function output_discovered() { echo '
Fired ' . esc_html( $hook['count'] ) . ' times'; } echo ''; - echo '' . esc_html( $hook['count'] ) . ''; + echo '' . ( $hook['is_action'] ? 'Action' : 'Filter' ) . ''; echo ''; } } From 44c2b6e511403c460ea4a7eace6f151981a60624 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 01:34:26 -0500 Subject: [PATCH 09/22] set default parameter value (to prevent returning a non-existent var) --- collectors/hooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index 21e0dab6e..9b1ec20f7 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -34,7 +34,7 @@ public function action_function_listen_start( $label ) { add_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); } - public function action_function_listen_all( $var ) { + public function action_function_listen_all( $var = null ) { if ( in_array( current_action(), array( 'qm/listen/start', 'qm/listen/stop', From dba3f024edd1415e95feee1b7ce3f1af958cace9 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 01:37:18 -0500 Subject: [PATCH 10/22] remove extra space --- output/html/hooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/output/html/hooks.php b/output/html/hooks.php index e647b2128..ad809065d 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -242,7 +242,7 @@ public function output_discovered() { echo '
Fired ' . esc_html( $hook['count'] ) . ' times'; } echo ''; - echo '' . ( $hook['is_action'] ? 'Action' : 'Filter' ) . ''; + echo '' . ( $hook['is_action'] ? 'Action' : 'Filter' ) . ''; echo ''; } } From b2756d4124dddfb0d513e89f98ecdc4b6cf40d05 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 18:56:36 -0500 Subject: [PATCH 11/22] add notice to 'all' warning --- output/html/hooks.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/output/html/hooks.php b/output/html/hooks.php index ad809065d..fc941f462 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -118,6 +118,16 @@ public static function output_hook_table( array $hooks ) { esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ), 'all' ); + + $data = $this->collector->get_data(); + if ( !empty( $data['discovered_hooks'] ) ) { + echo '
'; + print_f( + esc_html__( '%s used for hook discovery.', + 'all' + ); // @todo Link to Discovered Hooks panel. + } + echo ''; } echo ''; From 065211c0c5fec92c0a7dd43f66d309c93b5d03e1 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 19:03:15 -0500 Subject: [PATCH 12/22] add missing closing parenthesis --- output/html/hooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/output/html/hooks.php b/output/html/hooks.php index fc941f462..19d452ad5 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -123,7 +123,7 @@ public static function output_hook_table( array $hooks ) { if ( !empty( $data['discovered_hooks'] ) ) { echo '
'; print_f( - esc_html__( '%s used for hook discovery.', + esc_html__( '%s used for hook discovery.' ), 'all' ); // @todo Link to Discovered Hooks panel. } From f207b38de8431cfb77a04d2dc2be3d302ee3469e Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 19:18:56 -0500 Subject: [PATCH 13/22] code guidelines fixes --- output/html/hooks.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/output/html/hooks.php b/output/html/hooks.php index 19d452ad5..53bd69750 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -118,16 +118,18 @@ public static function output_hook_table( array $hooks ) { esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ), 'all' ); - - $data = $this->collector->get_data(); - if ( !empty( $data['discovered_hooks'] ) ) { + + $data = self::$collector->get_data(); + + if ( ! empty( $data['discovered_hooks'] ) ) { echo '
'; print_f( - esc_html__( '%s used for hook discovery.' ), + /* translators: %s: Action name */ + esc_html__( '%s hook used for hook discovery.', 'query-monitor' ), 'all' ); // @todo Link to Discovered Hooks panel. } - + echo ''; } echo ''; From 7b15ede939dd9c957a24d346c9f12fd890e23a0e Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 19:59:58 -0500 Subject: [PATCH 14/22] add start and stop trace and rename data variable --- collectors/hooks.php | 27 +++++++++++++++++---------- output/html/hooks.php | 27 ++++++++++++++++++--------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index 9b1ec20f7..5e665066a 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -21,15 +21,21 @@ public function __construct() { } public function action_function_listen_start( $label ) { - if ( ! array_key_exists( 'discovered_hooks', $this->data ) ) { - $this->data['discovered_hooks'] = array(); + if ( ! array_key_exists( 'discoveries', $this->data ) ) { + $this->data['discoveries'] = array(); } - if ( array_key_exists( $label, $this->data['discovered_hooks'] ) ) { + if ( array_key_exists( $label, $this->data['discoveries'] ) ) { return; } - $this->data['discovered_hooks'][ $label ] = array(); + $this->data['discoveries'][ $label ] = array( + 'bounds' => array( + 'start' => new QM_Backtrace, + 'stop' => null, + ), + 'hooks' => array(), + ); add_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); } @@ -44,15 +50,15 @@ public function action_function_listen_all( $var = null ) { global $wp_actions; - end( $this->data['discovered_hooks'] ); - $label = key( $this->data['discovered_hooks'] ); - $last = end( $this->data['discovered_hooks'][ $label ] ); + end( $this->data['discoveries'] ); + $label = key( $this->data['discoveries'] ); + $last = end( $this->data['discoveries'][ $label ]['hooks'] ); if ( current_action() === $last['hook'] ) { - $i = key( $this->data['discovered_hooks'][ $label ] ); - $this->data['discovered_hooks'][ $label ][ $i ]['count']++; + $i = key( $this->data['discoveries'][ $label ]['hooks'] ); + $this->data['discoveries'][ $label ]['hooks'][ $i ]['count']++; } else { - $this->data['discovered_hooks'][ $label ][] = array( + $this->data['discoveries'][ $label ]['hooks'][] = array( 'is_action' => array_key_exists( current_action(), $wp_actions ), 'hook' => current_action(), 'count' => 1, @@ -64,6 +70,7 @@ public function action_function_listen_all( $var = null ) { public function action_function_listen_stop( $label ) { remove_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); + $this->data['discoveries'][ $label ]['bounds']['stop'] = new QM_Backtrace; } public function process() { diff --git a/output/html/hooks.php b/output/html/hooks.php index 53bd69750..856d0de67 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -18,12 +18,12 @@ public function __construct( QM_Collector $collector ) { public function panel_menus( $panel_menu ) { $data = $this->collector->get_data(); - if ( empty( $data['discovered_hooks'] ) ) { + if ( empty( $data['discoveries'] ) ) { return $panel_menu; } - $panel_menu[ 'qm-' . $this->id ]['children'][ 'qm-' . $this->id . '-discovered_hooks' ] = array( - 'href' => esc_attr( '#' . $this->collector->id() . '-discovered_hooks' ), + $panel_menu[ 'qm-' . $this->id ]['children'][ 'qm-' . $this->id . '-discoveries' ] = array( + 'href' => esc_attr( '#' . $this->collector->id() . '-discoveries' ), 'title' => '└ ' . __( 'Discovered Hooks', 'query-monitor' ), ); @@ -121,7 +121,7 @@ public static function output_hook_table( array $hooks ) { $data = self::$collector->get_data(); - if ( ! empty( $data['discovered_hooks'] ) ) { + if ( ! empty( $data['discoveries'] ) ) { echo '
'; print_f( /* translators: %s: Action name */ @@ -216,14 +216,14 @@ protected function after_tabular_output() { public function output_discovered() { printf( '
', - esc_attr( $this->current_id . '-discovered_hooks' ) + esc_attr( $this->current_id . '-discoveries' ) ); echo '
'; printf( '', - esc_attr( $this->current_id . '-discovered_hooks' ), + esc_attr( $this->current_id . '-discoveries' ), esc_html__( 'Discovered Hooks', 'query-monitor' ) ); @@ -239,12 +239,21 @@ public function output_discovered() { $data = $this->collector->get_data(); - foreach ( $data['discovered_hooks'] as $label => $hooks ) { - foreach ( $hooks as $i => $hook ) { + foreach ( $data['discoveries'] as $label => $listener ) { + $trace__start = $listener['bounds']['start']->get_trace(); + $trace__stop = $listener['bounds']['stop']->get_trace(); + + foreach ( $listener['hooks'] as $i => $hook ) { echo ''; if ( 0 === $i ) { - echo ''; + echo ''; } echo '

%2$s

' . esc_html( $label ) . ''; + echo ''; + echo esc_html( $label ); + echo self::output_filename( '', $trace__start[0]['file'], $trace__start[0]['line'] ); // WPCS: XSS ok. + echo self::output_filename( '', $trace__stop[0]['file'], $trace__stop[0]['line'] ); // WPCS: XSS ok. + echo ''; + echo ''; From 01cb6034824ad79bb916be3eae3dd86b87a8d7fb Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 20:06:08 -0500 Subject: [PATCH 15/22] fixes for performance notice --- output/html/hooks.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/output/html/hooks.php b/output/html/hooks.php index 856d0de67..a25b7791d 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -119,15 +119,10 @@ public static function output_hook_table( array $hooks ) { 'all' ); - $data = self::$collector->get_data(); + $data = QM_Collectors::get( 'hooks' )->get_data(); if ( ! empty( $data['discoveries'] ) ) { - echo '
'; - print_f( - /* translators: %s: Action name */ - esc_html__( '%s hook used for hook discovery.', 'query-monitor' ), - 'all' - ); // @todo Link to Discovered Hooks panel. + echo esc_html( ' (Used for discovering hooks.)' ); // @todo Link to Discovered Hooks panel. } echo ''; From e17055d6e6644a4513709a9d667a3f4a44614b68 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 20:07:30 -0500 Subject: [PATCH 16/22] add parentheses to object instantiation --- collectors/hooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index 5e665066a..5e96ef45a 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -31,7 +31,7 @@ public function action_function_listen_start( $label ) { $this->data['discoveries'][ $label ] = array( 'bounds' => array( - 'start' => new QM_Backtrace, + 'start' => new QM_Backtrace(), 'stop' => null, ), 'hooks' => array(), @@ -70,7 +70,7 @@ public function action_function_listen_all( $var = null ) { public function action_function_listen_stop( $label ) { remove_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); - $this->data['discoveries'][ $label ]['bounds']['stop'] = new QM_Backtrace; + $this->data['discoveries'][ $label ]['bounds']['stop'] = new QM_Backtrace(); } public function process() { From 4413d55346d89cc1a552fceb665f77b5a658d3bd Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 20:13:48 -0500 Subject: [PATCH 17/22] better performance notice --- output/html/hooks.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/output/html/hooks.php b/output/html/hooks.php index a25b7791d..698176c2a 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -113,18 +113,21 @@ public static function output_hook_table( array $hooks ) { echo '' . esc_html( $hook['name'] ) . ''; if ( 'all' === $hook['name'] ) { echo '
'; - printf( - /* translators: %s: Action name */ - esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ), - 'all' - ); + $use = 'Try to avoid using it.'; $data = QM_Collectors::get( 'hooks' )->get_data(); if ( ! empty( $data['discoveries'] ) ) { - echo esc_html( ' (Used for discovering hooks.)' ); // @todo Link to Discovered Hooks panel. + $use = '
Remove the hook discovery bounds when not actively using.'; // @todo Link to Discovered Hooks panel. } + printf( + /* translators: %s: Action name */ + esc_html__( 'Warning: The %s action is extremely resource intensive. %s', 'query-monitor' ), + 'all', + $use + ); + echo ''; } echo ''; From 3718cb623ce5f6cc12cfb587d2976b3919307758 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 20:17:49 -0500 Subject: [PATCH 18/22] add constant as flag to prevent hook discovery --- collectors/hooks.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index 5e96ef45a..51c06b41a 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -16,8 +16,11 @@ public function name() { public function __construct() { parent::__construct(); - add_action( 'qm/listen/start', array( $this, 'action_function_listen_start' ), 10, 1 ); - add_action( 'qm/listen/stop', array( $this, 'action_function_listen_stop' ), 10, 1 ); + + if ( ! defined( 'QM_DISABLE_HOOK_DISCOVERY' ) || ! QM_DISABLE_HOOK_DISCOVERY ) { + add_action( 'qm/listen/start', array( $this, 'action_function_listen_start' ), 10, 1 ); + add_action( 'qm/listen/stop', array( $this, 'action_function_listen_stop' ), 10, 1 ); + } } public function action_function_listen_start( $label ) { From 15786d565a9b5c4d50ba22d2cf27d9cc36b70251 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Thu, 21 Feb 2019 20:23:56 -0500 Subject: [PATCH 19/22] improve performance notice --- output/html/hooks.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/output/html/hooks.php b/output/html/hooks.php index 698176c2a..9549b73ce 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -114,20 +114,20 @@ public static function output_hook_table( array $hooks ) { if ( 'all' === $hook['name'] ) { echo '
'; - $use = 'Try to avoid using it.'; + printf( + /* translators: %s: Action name */ + esc_html__( 'Warning: The %1$s action is extremely resource intensive.', 'query-monitor' ), + 'all' + ); + $data = QM_Collectors::get( 'hooks' )->get_data(); if ( ! empty( $data['discoveries'] ) ) { - $use = '
Remove the hook discovery bounds when not actively using.'; // @todo Link to Discovered Hooks panel. + echo '
Remove the hook discovery bounds when not actively using.'; // @todo Link to Discovered Hooks panel. + } else { + echo ' Try to avoid using it.'; } - printf( - /* translators: %s: Action name */ - esc_html__( 'Warning: The %s action is extremely resource intensive. %s', 'query-monitor' ), - 'all', - $use - ); - echo ''; } echo ''; From 5a19152dceddc8edd58221eda7934afdf1f0038e Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Fri, 22 Feb 2019 21:57:34 -0500 Subject: [PATCH 20/22] reset hook collector and output --- collectors/hooks.php | 62 ---------------------------- output/html/hooks.php | 96 +------------------------------------------ 2 files changed, 1 insertion(+), 157 deletions(-) diff --git a/collectors/hooks.php b/collectors/hooks.php index 51c06b41a..99f37a649 100644 --- a/collectors/hooks.php +++ b/collectors/hooks.php @@ -14,68 +14,6 @@ public function name() { return __( 'Hooks & Actions', 'query-monitor' ); } - public function __construct() { - parent::__construct(); - - if ( ! defined( 'QM_DISABLE_HOOK_DISCOVERY' ) || ! QM_DISABLE_HOOK_DISCOVERY ) { - add_action( 'qm/listen/start', array( $this, 'action_function_listen_start' ), 10, 1 ); - add_action( 'qm/listen/stop', array( $this, 'action_function_listen_stop' ), 10, 1 ); - } - } - - public function action_function_listen_start( $label ) { - if ( ! array_key_exists( 'discoveries', $this->data ) ) { - $this->data['discoveries'] = array(); - } - - if ( array_key_exists( $label, $this->data['discoveries'] ) ) { - return; - } - - $this->data['discoveries'][ $label ] = array( - 'bounds' => array( - 'start' => new QM_Backtrace(), - 'stop' => null, - ), - 'hooks' => array(), - ); - - add_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); - } - - public function action_function_listen_all( $var = null ) { - if ( in_array( current_action(), array( - 'qm/listen/start', - 'qm/listen/stop', - ) ) ) { - return $var; - } - - global $wp_actions; - - end( $this->data['discoveries'] ); - $label = key( $this->data['discoveries'] ); - $last = end( $this->data['discoveries'][ $label ]['hooks'] ); - - if ( current_action() === $last['hook'] ) { - $i = key( $this->data['discoveries'][ $label ]['hooks'] ); - $this->data['discoveries'][ $label ]['hooks'][ $i ]['count']++; - } else { - $this->data['discoveries'][ $label ]['hooks'][] = array( - 'is_action' => array_key_exists( current_action(), $wp_actions ), - 'hook' => current_action(), - 'count' => 1, - ); - } - - return $var; - } - - public function action_function_listen_stop( $label ) { - remove_action( 'all', array( $this, 'action_function_listen_all' ), 0, 1 ); - $this->data['discoveries'][ $label ]['bounds']['stop'] = new QM_Backtrace(); - } - public function process() { global $wp_actions, $wp_filter; diff --git a/output/html/hooks.php b/output/html/hooks.php index 9549b73ce..9bda68c06 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -11,25 +11,9 @@ class QM_Output_Html_Hooks extends QM_Output_Html { public function __construct( QM_Collector $collector ) { parent::__construct( $collector ); - add_filter( 'qm/output/panel_menus', array( $this, 'panel_menus' ) ); add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 80 ); } - public function panel_menus( $panel_menu ) { - $data = $this->collector->get_data(); - - if ( empty( $data['discoveries'] ) ) { - return $panel_menu; - } - - $panel_menu[ 'qm-' . $this->id ]['children'][ 'qm-' . $this->id . '-discoveries' ] = array( - 'href' => esc_attr( '#' . $this->collector->id() . '-discoveries' ), - 'title' => '└ ' . __( 'Discovered Hooks', 'query-monitor' ), - ); - - return $panel_menu; - } - public function output() { $data = $this->collector->get_data(); @@ -113,21 +97,11 @@ public static function output_hook_table( array $hooks ) { echo '' . esc_html( $hook['name'] ) . ''; if ( 'all' === $hook['name'] ) { echo '
'; - printf( /* translators: %s: Action name */ - esc_html__( 'Warning: The %1$s action is extremely resource intensive.', 'query-monitor' ), + esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ), 'all' ); - - $data = QM_Collectors::get( 'hooks' )->get_data(); - - if ( ! empty( $data['discoveries'] ) ) { - echo '
Remove the hook discovery bounds when not actively using.'; // @todo Link to Discovered Hooks panel. - } else { - echo ' Try to avoid using it.'; - } - echo ''; } echo ''; @@ -204,74 +178,6 @@ public static function output_hook_table( array $hooks ) { } - protected function after_tabular_output() { - echo '
'; - echo '
'; - - $this->output_discovered(); - } - - public function output_discovered() { - printf( - '
', - esc_attr( $this->current_id . '-discoveries' ) - ); - - echo '
'; - - printf( - '', - esc_attr( $this->current_id . '-discoveries' ), - esc_html__( 'Discovered Hooks', 'query-monitor' ) - ); - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - echo ''; - - $data = $this->collector->get_data(); - - foreach ( $data['discoveries'] as $label => $listener ) { - $trace__start = $listener['bounds']['start']->get_trace(); - $trace__stop = $listener['bounds']['stop']->get_trace(); - - foreach ( $listener['hooks'] as $i => $hook ) { - echo ''; - - if ( 0 === $i ) { - echo ''; - } - - echo ''; - echo ''; - echo ''; - } - } - - echo ''; - echo '

%2$s

' . esc_html__( 'Label', 'query-monitor' ) . '' . esc_html__( 'Hook', 'query-monitor' ) . '' . esc_html__( 'Type', 'query-monitor' ) . '
'; - echo ''; - echo esc_html( $label ); - echo self::output_filename( '', $trace__start[0]['file'], $trace__start[0]['line'] ); // WPCS: XSS ok. - echo self::output_filename( '', $trace__stop[0]['file'], $trace__stop[0]['line'] ); // WPCS: XSS ok. - echo ''; - echo ''; - echo '' . esc_html( $hook['hook'] ) . ''; - - if ( 1 < $hook['count'] ) { - echo '
Fired ' . esc_html( $hook['count'] ) . ' times'; - } - echo '
' . ( $hook['is_action'] ? 'Action' : 'Filter' ) . '
'; - - echo '
'; - } - } function register_qm_output_html_hooks( array $output, QM_Collectors $collectors ) { From ac3b512de78d8d4a0f834bee00af5c7b4e934bea Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Sat, 23 Feb 2019 02:13:01 -0500 Subject: [PATCH 21/22] new collector and output and constants --- classes/Dispatcher.php | 4 + collectors/hooks_within_bounds.php | 138 ++++++++++++++++++++++++++++ dispatchers/Html.php | 24 +++-- output/html/hooks.php | 13 ++- output/html/hooks_within_bounds.php | 137 +++++++++++++++++++++++++++ 5 files changed, 306 insertions(+), 10 deletions(-) create mode 100644 collectors/hooks_within_bounds.php create mode 100644 output/html/hooks_within_bounds.php diff --git a/classes/Dispatcher.php b/classes/Dispatcher.php index 77b0416c4..2954f2e15 100644 --- a/classes/Dispatcher.php +++ b/classes/Dispatcher.php @@ -15,6 +15,10 @@ public function __construct( QM_Plugin $qm ) { define( 'QM_COOKIE', 'wp-query_monitor_' . COOKIEHASH ); } + if ( ! defined( 'QM_MAX_HOOKS_DISCOVERED' ) ) { + define( 'QM_MAX_HOOKS_DISCOVERED', 500 ); + } + add_action( 'init', array( $this, 'init' ) ); } diff --git a/collectors/hooks_within_bounds.php b/collectors/hooks_within_bounds.php new file mode 100644 index 000000000..078ab445a --- /dev/null +++ b/collectors/hooks_within_bounds.php @@ -0,0 +1,138 @@ +data = array( + 'hooks' => array(), + 'bounds' => array(), + 'counts' => array(), + ); + } + + function action_function_listener_start( $id ) { + if ( $this->is_active( $id ) ) { + return; + } + + if ( array_key_exists( $id, $this->data['bounds'] ) ) { + trigger_error( sprintf( + /* translators: %s: Hook discovery ID */ + esc_html__( 'Hook discovery ID %s already exists', 'query-monitor' ), + '' . $id . '' + ), E_USER_NOTICE ); + return; + } + + $this->maybe_add_all_callback(); + + $this->active[ $id ] = 1; + $this->data['hooks'][ $id ] = array(); + $this->data['bounds'][ $id ] = array( + 'start' => new QM_Backtrace(), + 'stop' => null, + ); + $this->data['counts'][ $id ] = 0; + } + + function action_function_all( $var = null ) { + if ( ! $this->is_active() ) { + remove_action( 'all', array( $this, 'action_function_all' ) ); + return $var; + } + + if ( in_array( current_action(), array( + 'qm/listen/start', + 'qm/listen/stop', + ) ) ) { + return $var; + } + + global $wp_actions; + + foreach ( array_keys( $this->active ) as $id ) { + end( $this->data['hooks'][ $id ] ); + $last = current( $this->data['hooks'][ $id ] ); + + if ( current_action() === $last['hook'] ) { + $i = key( $this->data['hooks'][ $id ] ); + $this->data['hooks'][ $id ][ $i ]['fires']++; + } else { + $this->data['hooks'][ $id ][] = array( + 'hook' => current_action(), + 'is_action' => array_key_exists( current_action(), $wp_actions ), + 'fires' => 1, + ); + } + + if ( QM_MAX_HOOKS_DISCOVERED < ++$this->data['counts'][ $id ] ) { + $this->action_function_listener_stop( $id ); + $this->data['bounds'][ $id ]['was_terminated'] = true; + } + + return $var; + } + } + + function action_function_listener_stop( $id ) { + if ( ! $this->is_active( $id ) && ! array_key_exists( $id, $this->data['hooks'] ) ) { + trigger_error( sprintf( + /* translators: %s: Hook discovery ID */ + esc_html__( 'Hook discovery starting bound for %s has not been set', 'query-monitor' ), + '' . $id . '' + ), E_USER_NOTICE ); + return; + } + + unset( $this->active[ $id ] ); + $this->data['bounds'][ $id ]['stop'] = new QM_Backtrace(); + + if ( ! $this->is_active() ) { + remove_action( 'all', array( $this, 'action_function_all' ) ); + } + } + + function action_function_shutdown() { + if ( $this->is_active() ) { + foreach ( array_keys( $this->active ) as $id ) { + $this->action_function_listener_stop( $id ); + } + } + } + + function is_active( $id = false ) { + return false !== $id ? array_key_exists( $id, $this->active ) : ! empty( $this->active ); + } + + function maybe_add_all_callback() { + if ( ! $this->is_active() ) { + add_action( 'all', array( $this, 'action_function_all' ), 0 ); + } + } + +} + +# Load early so early hooks can be discovered +QM_Collectors::add( new QM_Collector_Hooks_Within_Bounds() ); diff --git a/dispatchers/Html.php b/dispatchers/Html.php index 495edaf4a..e0dc3395d 100644 --- a/dispatchers/Html.php +++ b/dispatchers/Html.php @@ -381,39 +381,47 @@ protected function after_output() { echo '
'; $constants = array( - 'QM_DB_EXPENSIVE' => array( + 'QM_DB_EXPENSIVE' => array( /* translators: %s: The default value for a PHP constant */ 'label' => __( 'If an individual database query takes longer than this time to execute, it\'s considered "slow" and triggers a warning. Default value: %s.', 'query-monitor' ), 'default' => 0.05, ), - 'QM_DISABLED' => array( + 'QM_DISABLED' => array( 'label' => __( 'Disable Query Monitor entirely.', 'query-monitor' ), 'default' => false, ), - 'QM_DISABLE_ERROR_HANDLER' => array( + 'QM_DISABLE_ERROR_HANDLER' => array( 'label' => __( 'Disable the handling of PHP errors.', 'query-monitor' ), 'default' => false, ), - 'QM_ENABLE_CAPS_PANEL' => array( + 'QM_ENABLE_CAPS_PANEL' => array( 'label' => __( 'Enable the Capability Checks panel.', 'query-monitor' ), 'default' => false, ), - 'QM_HIDE_CORE_ACTIONS' => array( + 'QM_HIDE_CORE_ACTIONS' => array( 'label' => __( 'Hide WordPress core on the Hooks & Actions panel.', 'query-monitor' ), 'default' => false, ), - 'QM_HIDE_SELF' => array( + 'QM_HIDE_SELF' => array( 'label' => __( 'Hide Query Monitor itself from various panels.', 'query-monitor' ), 'default' => false, ), - 'QM_NO_JQUERY' => array( + 'QM_NO_JQUERY' => array( 'label' => __( 'Don\'t specify jQuery as a dependency of Query Monitor. If jQuery isn\'t enqueued then Query Monitor will still operate, but with some reduced functionality.', 'query-monitor' ), 'default' => false, ), - 'QM_SHOW_ALL_HOOKS' => array( + 'QM_SHOW_ALL_HOOKS' => array( 'label' => __( 'In the Hooks & Actions panel, show every hook that has an action or filter attached (instead of every action hook that fired during the request).', 'query-monitor' ), 'default' => false, ), + 'QM_DISABLE_HOOK_DISCOVERY' => array( + 'label' => __( 'Prevent hook discovery, to safeguard against performance degradation in production.' ), + 'default' => false, + ), + 'QM_MAX_HOOKS_DISCOVERED' => array( + 'label' => __( 'Maximum number of hooks to discover before auto-terminating.' ), + 'default' => 300, + ) ); echo '
'; diff --git a/output/html/hooks.php b/output/html/hooks.php index 9bda68c06..8da644523 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -96,11 +96,20 @@ public static function output_hook_table( array $hooks ) { echo ''; echo '' . esc_html( $hook['name'] ) . ''; if ( 'all' === $hook['name'] ) { + $_hooks_within_bounds = QM_Collectors::get( 'hooks_within_bounds' ); + $hooks_within_bounds = $_hooks_within_bounds->get_data(); + + $extra = ' Try to avoid using it.'; + + if ( $_hooks_within_bounds && !empty( $hooks_within_bounds['hooks'] ) ) + $extra = '
Remove or disable hook discovery when not actively using.'; // @TODO Link to panel. + echo '
'; printf( /* translators: %s: Action name */ - esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ), - 'all' + esc_html__( 'Warning: The %1$s action is extremely resource intensive.%2$s', 'query-monitor' ), + 'all', + $extra ); echo ''; } diff --git a/output/html/hooks_within_bounds.php b/output/html/hooks_within_bounds.php new file mode 100644 index 000000000..fe5db8d98 --- /dev/null +++ b/output/html/hooks_within_bounds.php @@ -0,0 +1,137 @@ +menu( array( + 'title' => '└ ' . esc_html__( 'Discovered Hooks', 'query-monitor' ), + ) ); + } + + return $menu; + } + + public function output() { + $data = $this->collector->get_data(); + + if ( empty( $data['hooks'] ) ) { + $this->before_non_tabular_output(); + + $_notice = 'No discovered hooks.'; + + if ( defined( 'QM_DISABLE_HOOK_DISCOVERY' ) && QM_DISABLE_HOOK_DISCOVERY ) { + $_notice = 'Hook discovery disabled.'; + } + + $notice = __( $_notice, 'query-monitor' ); + echo $this->build_notice( $notice ); // WPCS: XSS ok. + + $this->after_non_tabular_output(); + return; + } + + printf( + '
', + esc_attr( $this->collector->id() ) + ); + + echo '
'; + + printf( + '', + esc_attr( $this->collector->id() ), + esc_html__( 'Discovered Hooks', 'query-monitor' ) + ); + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + + foreach ( $data['hooks'] as $id => $hooks ) { + $trace_file__start + = $trace_file__stop + = ''; + + $bound__start = $data['bounds'][ $id ]['start']; + $bound__stop = $data['bounds'][ $id ]['stop']; + + if ( is_a( $bound__start, 'QM_Backtrace' ) ) { + $trace__start = $bound__start->get_trace(); + $trace_text__start = self::output_filename( '', $trace__start[0]['file'], $trace__start[0]['line'] ); + } + + if ( !empty( $data['bounds'][ $id ]['was_terminated'] ) ) { + $trace_text__stop = '
Auto-terminated (max hooks)'; + } else if ( is_a( $bound__stop, 'QM_Backtrace' ) ) { + $trace__stop = $bound__stop->get_trace(); + $trace_text__stop = self::output_filename( '', $trace__stop[0]['file'], $trace__stop[0]['line'] ); + } + + foreach ( $hooks as $i => $hook ) { + echo ''; + + if ( 0 === $i ) { + echo ''; + } + + echo ''; + + echo ''; + echo ''; + echo ''; + } + } + + echo ''; + echo '

%2$s

' . esc_html__( 'Label', 'query-monitor' ) . '' . esc_html__( 'Hook', 'query-monitor' ) . '' . esc_html__( 'Type', 'query-monitor' ) . '
'; + echo ''; + echo esc_html( $id ); + echo $trace_text__start; // WPCS: XSS ok. + echo $trace_text__stop; // WPCS: XSS ok. + echo ''; + echo '' . esc_html( ++$i ) . ''; + echo '' . esc_html( $hook['hook'] ) . ''; + + if ( 1 < $hook['fires'] ) { + echo '
Fired ' . esc_html( $hook['fires'] ) . ' times'; + } + echo '
' . ( $hook['is_action'] ? 'Action' : 'Filter' ) . '
'; + + echo '
'; + } + +} + +function register_qm_output_html_hooks_within_bounds( array $output, QM_Collectors $collectors ) { + $collector = $collectors::get( 'hooks_within_bounds' ); + if ( $collector ) { + $output['hooks_within_bounds'] = new QM_Output_Html_Hooks_Within_Bounds( $collector ); + } + return $output; +} + +add_filter( 'qm/outputter/html', 'register_qm_output_html_hooks_within_bounds', 80, 2 ); From 0b2de80d2d2472596f21b7c71a1eca9ff0bbb664 Mon Sep 17 00:00:00 2001 From: Caleb Stauffer Date: Sat, 23 Feb 2019 02:17:28 -0500 Subject: [PATCH 22/22] remove item from admin bar menu --- output/html/hooks_within_bounds.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/output/html/hooks_within_bounds.php b/output/html/hooks_within_bounds.php index fe5db8d98..ce56ccff7 100644 --- a/output/html/hooks_within_bounds.php +++ b/output/html/hooks_within_bounds.php @@ -11,8 +11,7 @@ class QM_Output_Html_Hooks_Within_Bounds extends QM_Output_Html { public function __construct( QM_Collector $collector ) { parent::__construct( $collector ); - add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 110 ); - add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 80 ); + add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 80 ); } public function panel_menu( array $menu ) {