diff --git a/features/profile-hook.feature b/features/profile-hook.feature index 5f1f3f6..f7ed06f 100644 --- a/features/profile-hook.feature +++ b/features/profile-hook.feature @@ -1,5 +1,14 @@ Feature: Profile a specific hook + Scenario: Profile all hooks when a specific hook isn't specified + Given a WP install + + When I run `wp profile hook --fields=hook,callback_count` + Then STDOUT should be a table containing rows: + | hook | callback_count | + | plugins_loaded | 3 | + And STDERR should be empty + Scenario: Profile a hook before the template is loaded Given a WP install diff --git a/features/profile.feature b/features/profile.feature index bc3f680..b673665 100644 --- a/features/profile.feature +++ b/features/profile.feature @@ -8,7 +8,7 @@ Feature: Basic profile usage """ usage: wp profile eval [--fields=] [--format=] or: wp profile eval-file [--fields=] [--format=] - or: wp profile hook [--url=] [--fields=] [--format=] + or: wp profile hook [] [--url=] [--fields=] [--format=] or: wp profile stage [] [--all] [--url=] [--fields=] [--format=] See 'wp help profile ' for more information on a specific command. diff --git a/inc/class-command.php b/inc/class-command.php index f70fd96..c5b941d 100644 --- a/inc/class-command.php +++ b/inc/class-command.php @@ -40,17 +40,17 @@ class Command { public function stage( $args, $assoc_args ) { global $wpdb; - $focus_stage = Utils\get_flag_value( $assoc_args, 'all', isset( $args[0] ) ? $args[0] : null ); + $focus = Utils\get_flag_value( $assoc_args, 'all', isset( $args[0] ) ? $args[0] : null ); $valid_stages = array( 'bootstrap', 'main_query', 'template' ); - if ( $focus_stage && ( true !== $focus_stage && ! in_array( $focus_stage, $valid_stages, true ) ) ) { + if ( $focus && ( true !== $focus && ! in_array( $focus, $valid_stages, true ) ) ) { WP_CLI::error( 'Invalid stage. Must be one of ' . implode( ', ', $valid_stages ) . ', or use --all.' ); } - $profiler = new Profiler( 'stage', $focus_stage ); + $profiler = new Profiler( 'stage', $focus ); $profiler->run(); - if ( $focus_stage ) { + if ( $focus ) { $fields = array( 'hook', 'callback_count', @@ -83,12 +83,12 @@ class Command { } /** - * Profile key metrics for a WordPress hook (action or filter). + * Profile key metrics for WordPress hooks (actions and filters). * * ## OPTIONS * - * - * : WordPress hook (action or filter) to profile. + * [] + * : Drill into key metrics for a specific WordPress hook (action or filter). * * [--url=] * : Execute a request against a specified URL. Defaults to the home URL. @@ -111,7 +111,7 @@ class Command { */ public function hook( $args, $assoc_args ) { - $focus = $args[0]; + $focus = isset( $args[0] ) ? $args[0] : null; $profiler = new Profiler( 'hook', $focus ); $profiler->run(); @@ -123,9 +123,12 @@ class Command { remove_all_actions( 'shutdown' ); } - $fields = array( - 'callback', - 'location', + if ( $focus ) { + $base = array( 'callback', 'location' ); + } else { + $base = array( 'hook', 'callback_count' ); + } + $metrics = array( 'time', 'query_time', 'query_count', @@ -135,6 +138,7 @@ class Command { 'request_time', 'request_count', ); + $fields = array_merge( $base, $metrics ); $formatter = new Formatter( $assoc_args, $fields ); $formatter->display_items( $profiler->get_loggers() ); } diff --git a/inc/class-profiler.php b/inc/class-profiler.php index 731b281..47b628d 100644 --- a/inc/class-profiler.php +++ b/inc/class-profiler.php @@ -83,7 +83,8 @@ class Profiler { } $current_filter = current_filter(); - if ( 'stage' === $this->type && in_array( $current_filter, $this->current_stage_hooks ) ) { + if ( ( 'stage' === $this->type && in_array( $current_filter, $this->current_stage_hooks ) ) + || ( 'hook' === $this->type && ! $this->focus ) ) { $pseudo_hook = "before {$current_filter}"; if ( isset( $this->loggers[ $pseudo_hook ] ) ) { $this->loggers[ $pseudo_hook ]->stop(); @@ -164,17 +165,20 @@ class Profiler { $this->filter_depth = 0; } - if ( 'stage' === $this->type && in_array( $current_filter, $this->current_stage_hooks ) ) { + if ( ( 'stage' === $this->type && in_array( $current_filter, $this->current_stage_hooks ) ) + || ( 'hook' === $this->type && ! $this->focus ) ) { $this->loggers[ $current_filter ]->stop(); - $key = array_search( $current_filter, $this->current_stage_hooks ); - if ( false !== $key && isset( $this->current_stage_hooks[ $key + 1 ] ) ) { - $pseudo_hook = "before {$this->current_stage_hooks[$key+1]}"; - $this->loggers[ $pseudo_hook ] = new Logger( array( 'hook' => '' ) ); - $this->loggers[ $pseudo_hook ]->start(); - } else { - $pseudo_hook = 'wp_profile_last_hook'; - $this->loggers[ $pseudo_hook ] = new Logger( array( 'hook' => '' ) ); - $this->loggers[ $pseudo_hook ]->start(); + if ( 'stage' === $this->type ) { + $key = array_search( $current_filter, $this->current_stage_hooks ); + if ( false !== $key && isset( $this->current_stage_hooks[ $key + 1 ] ) ) { + $pseudo_hook = "before {$this->current_stage_hooks[$key+1]}"; + $this->loggers[ $pseudo_hook ] = new Logger( array( 'hook' => '' ) ); + $this->loggers[ $pseudo_hook ]->start(); + } else { + $pseudo_hook = 'wp_profile_last_hook'; + $this->loggers[ $pseudo_hook ] = new Logger( array( 'hook' => '' ) ); + $this->loggers[ $pseudo_hook ]->start(); + } } }