diff --git a/features/profile-stage.feature b/features/profile-stage.feature index a91085e..d37b0db 100644 --- a/features/profile-stage.feature +++ b/features/profile-stage.feature @@ -65,6 +65,25 @@ Feature: Profile the template render stage | wp_footer:after | | total (13) | + When I run `wp profile stage template --fields=hook --orderby=hook --order=DESC` + Then STDOUT should be a table containing rows: + | hook | + | wp_head:before | + | wp_head | + | wp_footer:before | + | wp_footer:after | + | wp_footer | + | template_redirect:before | + | template_redirect | + | template_include:before | + | template_include | + | loop_start:before | + | loop_start | + | loop_end:before | + | loop_end | + | total (13) | + + Scenario: Use --all flag to profile all stages Given a WP install diff --git a/features/profile.feature b/features/profile.feature index 29544e9..8714d1a 100644 --- a/features/profile.feature +++ b/features/profile.feature @@ -6,10 +6,10 @@ Feature: Basic profile usage When I run `wp profile` Then STDOUT should be: """ - usage: wp profile eval [--hook[=]] [--fields=] [--format=] - or: wp profile eval-file [--hook[=]] [--fields=] [--format=] - or: wp profile hook [] [--all] [--spotlight] [--url=] [--fields=] [--format=] - or: wp profile stage [] [--all] [--spotlight] [--url=] [--fields=] [--format=] + usage: wp profile eval [--hook[=]] [--fields=] [--format=] [--order=] [--orderby=] + or: wp profile eval-file [--hook[=]] [--fields=] [--format=] [--order=] [--orderby=] + or: wp profile hook [] [--all] [--spotlight] [--url=] [--fields=] [--format=] [--order=] [--orderby=] + or: wp profile stage [] [--all] [--spotlight] [--url=] [--fields=] [--format=] [--order=] [--orderby=] See 'wp help profile ' for more information on a specific command. """ diff --git a/inc/class-command.php b/inc/class-command.php index f2bf32f..9f2e316 100644 --- a/inc/class-command.php +++ b/inc/class-command.php @@ -70,6 +70,19 @@ class Command { * * [--format=] * : Render output in a particular format. + * + * [--order=] + * : Ascending or Descending order. + * --- + * default: ASC + * options: + * - ASC + * - DESC + * --- + * + * [--orderby=] + * : Order by fields. + * * --- * default: table * options: @@ -84,7 +97,10 @@ class Command { public function stage( $args, $assoc_args ) { global $wpdb; - $focus = 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 ); + + $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); + $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); $valid_stages = array( 'bootstrap', 'main_query', 'template' ); if ( $focus && ( true !== $focus && ! in_array( $focus, $valid_stages, true ) ) ) { @@ -132,7 +148,8 @@ class Command { if ( Utils\get_flag_value( $assoc_args, 'spotlight' ) ) { $loggers = self::shine_spotlight( $loggers, $metrics ); } - $formatter->display_items( $loggers ); + + $formatter->display_items( $loggers, true, $order, $orderby ); } /** @@ -160,7 +177,19 @@ class Command { * * [--format=] * : Render output in a particular format. + * + * [--order=] + * : Ascending or Descending order. * --- + * default: ASC + * options: + * - ASC + * - DESC + * --- + * + * [--orderby=] + * : Order by fields. + * * default: table * options: * - table @@ -175,6 +204,9 @@ class Command { $focus = Utils\get_flag_value( $assoc_args, 'all', isset( $args[0] ) ? $args[0] : null ); + $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); + $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); + $profiler = new Profiler( 'hook', $focus ); $profiler->run(); @@ -206,7 +238,7 @@ class Command { if ( Utils\get_flag_value( $assoc_args, 'spotlight' ) ) { $loggers = self::shine_spotlight( $loggers, $metrics ); } - $formatter->display_items( $loggers ); + $formatter->display_items( $loggers, true, $order, $orderby ); } /** @@ -229,6 +261,19 @@ class Command { * * [--format=] * : Render output in a particular format. + * + * [--order=] + * : Ascending or Descending order. + * --- + * default: ASC + * options: + * - ASC + * - DESC + * --- + * + * [--orderby=] + * : Order by fields. + * * --- * default: table * options: @@ -242,9 +287,13 @@ class Command { */ public function eval_( $args, $assoc_args ) { $statement = $args[0]; + + $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); + $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); + self::profile_eval_ish( $assoc_args, function() use ( $statement ) { eval( $statement ); - }); + }, $order, $orderby ); } /** @@ -267,6 +316,19 @@ class Command { * * [--format=] * : Render output in a particular format. + * + * [--order=] + * : Ascending or Descending order. + * --- + * default: ASC + * options: + * - ASC + * - DESC + * --- + * + * [--orderby=] + * : Order by fields. + * * --- * default: table * options: @@ -281,13 +343,17 @@ class Command { public function eval_file( $args, $assoc_args ) { $file = $args[0]; + + $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); + $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); + if ( ! file_exists( $file ) ) { WP_CLI::error( "'$file' does not exist." ); } self::profile_eval_ish( $assoc_args, function() use ( $file ) { self::include_file( $file ); - }); + }, $order, $orderby ); } /** @@ -330,7 +396,7 @@ class Command { 'request_count', ) ); $formatter = new Formatter( $assoc_args, $fields ); - $formatter->display_items( $loggers, false ); + $formatter->display_items( $loggers, false, $order, $orderby ); } /** diff --git a/inc/class-formatter.php b/inc/class-formatter.php index 6a73659..fa0d5c6 100644 --- a/inc/class-formatter.php +++ b/inc/class-formatter.php @@ -42,21 +42,39 @@ class Formatter { * * @param array $items */ - public function display_items( $items, $include_total = true ) { + public function display_items( $items, $include_total = true, $order, $orderby ) { if ( 'table' === $this->args['format'] && empty( $this->args['field'] ) ) { - $this->show_table( $items, $this->args['fields'], $include_total ); + $this->show_table( $order, $orderby, $items, $this->args['fields'], $include_total ); } else { $this->formatter->display_items( $items ); } } + /** + * Function to compare floats. + * + * @param double $a Floating number. + * @param double $b Floating number. + */ + private function compare_float( $a, $b ) { + $a = number_format( $a, 4 ); + $b = number_format( $b, 4 ); + if ( 0 === $a - $b ) { + return 0; + } else if ( $a - $b < 0 ) { + return -1; + } else { + return 1; + } + } + /** * Show items in a \cli\Table. * * @param array $items * @param array $fields */ - private function show_table( $items, $fields, $include_total ) { + private function show_table( $order, $orderby, $items, $fields, $include_total ) { $table = new \cli\Table(); $enabled = \cli\Colors::shouldColorize(); @@ -70,6 +88,19 @@ class Formatter { if ( ! is_null( $this->total_cell_index ) ) { $totals[ $this->total_cell_index ] = 'total (' . count( $items ) . ')'; } + + if ( $orderby ) { + usort( $items, function( $a, $b ) use ( $order, $orderby ) { + list( $first, $second ) = 'ASC' === $order ? array( $a, $b ) : array( $b, $a ); + + if ( is_numeric( $first->$orderby ) && is_numeric( $second->$orderby ) ) { + return $this->compare_float( $first->$orderby, $second->$orderby ); + } + + return strcmp( $first->$orderby, $second->$orderby ); + }); + } + $location_index = array_search( 'location', $fields ); foreach ( $items as $item ) { $values = array_values( \WP_CLI\Utils\pick_fields( $item, $fields ) );