diff --git a/.gitignore b/.gitignore index 930cf9e..fb1c9c4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ node_modules/ vendor/ *.zip *.tar.gz +*.log diff --git a/composer.json b/composer.json index 4b09770..173ec24 100644 --- a/composer.json +++ b/composer.json @@ -1,25 +1,24 @@ { "name": "wp-cli/profile-command", - "description": "Quickly identify what's slow with WordPress.", "type": "wp-cli-package", + "description": "Quickly identify what's slow with WordPress.", "homepage": "https://runcommand.io/wp/profile/", "license": "MIT", "authors": [], - "minimum-stability": "dev", - "prefer-stable": true, - "autoload": { - "files": [ "command.php" ] - }, "require": { "php": ">=5.4", - "wp-cli/wp-cli": "*" + "wp-cli/wp-cli": "^2" }, "require-dev": { - "behat/behat": "~2.5" + "wp-cli/wp-cli-tests": "^2.0.7" + }, + "config": { + "process-timeout": 7200, + "sort-packages": true }, "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "2.x-dev" }, "commands": [ "profile stage", @@ -38,5 +37,26 @@ "post": "bin/readme/overview-body.md" } } + }, + "autoload": { + "files": [ + "command.php" + ] + }, + "minimum-stability": "dev", + "prefer-stable": true, + "scripts": { + "behat": "run-behat-tests", + "behat-rerun": "rerun-behat-tests", + "lint": "run-linter-tests", + "phpcs": "run-phpcs-tests", + "phpunit": "run-php-unit-tests", + "prepare-tests": "install-package-tests", + "test": [ + "@lint", + "@phpcs", + "@phpunit", + "@behat" + ] } } diff --git a/features/profile-hook.feature b/features/profile-hook.feature index c927646..4b23b1d 100644 --- a/features/profile-hook.feature +++ b/features/profile-hook.feature @@ -3,12 +3,12 @@ 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` + When I run `wp profile hook --fields=hook` Then STDOUT should be a table containing rows: - | hook | callback_count | - | plugins_loaded | 3 | - | init | 11 | - | template_redirect | 7 | + | hook | + | plugins_loaded | + | init | + | template_redirect | And STDERR should be empty Scenario: Profile all callbacks when --all flag is used @@ -116,7 +116,7 @@ Feature: Profile a specific hook }); """ - When I run `wp profile hook init` + When I try `wp profile hook init` Then STDERR should be: """ Warning: Called 1 diff --git a/inc/class-command.php b/inc/class-command.php index 29c12d1..a44f978 100644 --- a/inc/class-command.php +++ b/inc/class-command.php @@ -96,7 +96,7 @@ 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 ); @@ -110,7 +110,7 @@ class Command { $profiler->run(); if ( $focus ) { - $base = array( + $base = array( 'hook', 'callback_count', ); @@ -125,7 +125,7 @@ class Command { 'request_count', ); } else { - $base = array( + $base = array( 'stage', ); $metrics = array( @@ -141,9 +141,9 @@ class Command { 'request_count', ); } - $fields = array_merge( $base, $metrics ); + $fields = array_merge( $base, $metrics ); $formatter = new Formatter( $assoc_args, $fields ); - $loggers = $profiler->get_loggers(); + $loggers = $profiler->get_loggers(); if ( Utils\get_flag_value( $assoc_args, 'spotlight' ) ) { $loggers = self::shine_spotlight( $loggers, $metrics ); } @@ -221,7 +221,7 @@ class Command { } else { $base = array( 'hook', 'callback_count' ); } - $metrics = array( + $metrics = array( 'time', 'query_time', 'query_count', @@ -231,9 +231,9 @@ class Command { 'request_time', 'request_count', ); - $fields = array_merge( $base, $metrics ); + $fields = array_merge( $base, $metrics ); $formatter = new Formatter( $assoc_args, $fields ); - $loggers = $profiler->get_loggers(); + $loggers = $profiler->get_loggers(); if ( Utils\get_flag_value( $assoc_args, 'spotlight' ) ) { $loggers = self::shine_spotlight( $loggers, $metrics ); } @@ -289,9 +289,14 @@ class Command { $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 ); + self::profile_eval_ish( + $assoc_args, + function() use ( $statement ) { + eval( $statement ); // phpcs:ignore Squiz.PHP.Eval.Discouraged -- no other way oround here + }, + $order, + $orderby + ); } /** @@ -348,22 +353,27 @@ class Command { WP_CLI::error( "'$file' does not exist." ); } - self::profile_eval_ish( $assoc_args, function() use ( $file ) { - self::include_file( $file ); - }, $order, $orderby ); + self::profile_eval_ish( + $assoc_args, + function() use ( $file ) { + self::include_file( $file ); + }, + $order, + $orderby + ); } /** * Profile an eval or eval-file statement. */ - private static function profile_eval_ish( $assoc_args, $profile_callback ) { - $hook = Utils\get_flag_value( $assoc_args, 'hook' ); - $type = $focus = false; + private static function profile_eval_ish( $assoc_args, $profile_callback, $order = 'ASC', $orderby = null ) { + $hook = Utils\get_flag_value( $assoc_args, 'hook' ); + $type = $focus = false; $fields = array(); if ( $hook ) { $type = 'hook'; if ( true !== $hook ) { - $focus = $hook; + $focus = $hook; $fields[] = 'callback'; $fields[] = 'location'; } else { @@ -382,16 +392,19 @@ class Command { $logger->stop(); $loggers = array( $logger ); } - $fields = array_merge( $fields, array( - 'time', - 'query_time', - 'query_count', - 'cache_ratio', - 'cache_hits', - 'cache_misses', - 'request_time', - 'request_count', - ) ); + $fields = array_merge( + $fields, + array( + 'time', + 'query_time', + 'query_count', + 'cache_ratio', + 'cache_hits', + 'cache_misses', + 'request_time', + 'request_count', + ) + ); $formatter = new Formatter( $assoc_args, $fields ); $formatter->display_items( $loggers, false, $order, $orderby ); } @@ -414,9 +427,9 @@ class Command { */ private static function shine_spotlight( $loggers, $metrics ) { - foreach( $loggers as $k => $logger ) { + foreach ( $loggers as $k => $logger ) { $non_zero = false; - foreach( $metrics as $metric ) { + foreach ( $metrics as $metric ) { switch ( $metric ) { // 100% cache ratio is fine by us case 'cache_ratio': diff --git a/inc/class-formatter.php b/inc/class-formatter.php index fa0d5c6..1a44f53 100644 --- a/inc/class-formatter.php +++ b/inc/class-formatter.php @@ -14,7 +14,7 @@ class Formatter { $format_args = array( 'format' => 'table', 'fields' => $fields, - 'field' => null + 'field' => null, ); foreach ( array( 'format', 'fields', 'field' ) as $key ) { @@ -33,7 +33,7 @@ class Formatter { $format_args['fields'] = array_map( 'trim', $format_args['fields'] ); - $this->args = $format_args; + $this->args = $format_args; $this->formatter = new \WP_CLI\Formatter( $assoc_args, $fields, $prefix ); } @@ -61,7 +61,7 @@ class Formatter { $b = number_format( $b, 4 ); if ( 0 === $a - $b ) { return 0; - } else if ( $a - $b < 0 ) { + } elseif ( $a - $b < 0 ) { return -1; } else { return 1; @@ -90,21 +90,24 @@ class Formatter { } if ( $orderby ) { - usort( $items, function( $a, $b ) use ( $order, $orderby ) { - list( $first, $second ) = 'ASC' === $order ? array( $a, $b ) : array( $b, $a ); + 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 ); + if ( is_numeric( $first->$orderby ) && is_numeric( $second->$orderby ) ) { + return $this->compare_float( $first->$orderby, $second->$orderby ); + } + + return strcmp( $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 ) ); - foreach( $values as $i => $value ) { + foreach ( $values as $i => $value ) { if ( ! is_null( $this->total_cell_index ) && $this->total_cell_index === $i ) { continue; } @@ -135,7 +138,7 @@ class Formatter { $table->addRow( $values ); } if ( $include_total ) { - foreach( $totals as $i => $value ) { + foreach ( $totals as $i => $value ) { if ( null === $value ) { continue; } @@ -153,7 +156,7 @@ class Formatter { $table->setFooters( $totals ); } - foreach( $table->getDisplayLines() as $line ) { + foreach ( $table->getDisplayLines() as $line ) { \WP_CLI::line( $line ); } diff --git a/inc/class-logger.php b/inc/class-logger.php index 963bdd6..040ee0f 100644 --- a/inc/class-logger.php +++ b/inc/class-logger.php @@ -4,29 +4,29 @@ namespace runcommand\Profile; class Logger { - public $time = 0; - public $query_count = 0; - public $query_time = 0; - public $cache_hits = 0; - public $cache_misses = 0; - public $cache_ratio = null; - public $hook_count = 0; - public $hook_time = 0; + public $time = 0; + public $query_count = 0; + public $query_time = 0; + public $cache_hits = 0; + public $cache_misses = 0; + public $cache_ratio = null; + public $hook_count = 0; + public $hook_time = 0; public $request_count = 0; - public $request_time = 0; + public $request_time = 0; - private $start_time = null; - private $query_offset = null; - private $cache_hit_offset = null; - private $cache_miss_offset = null; - private $hook_start_time = null; - private $hook_depth = 0; + private $start_time = null; + private $query_offset = null; + private $cache_hit_offset = null; + private $cache_miss_offset = null; + private $hook_start_time = null; + private $hook_depth = 0; private $request_start_time = null; public static $active_loggers = array(); public function __construct( $definition = array() ) { - foreach( $definition as $k => $v ) { + foreach ( $definition as $k => $v ) { $this->$k = $v; } } @@ -36,12 +36,12 @@ class Logger { */ public function start() { global $wpdb, $wp_object_cache; - $this->start_time = microtime( true ); + $this->start_time = microtime( true ); $this->query_offset = ! empty( $wpdb->queries ) ? count( $wpdb->queries ) : 0; if ( false === ( $key = array_search( $this, self::$active_loggers ) ) ) { self::$active_loggers[] = $this; } - $this->cache_hit_offset = ! empty( $wp_object_cache->cache_hits ) ? $wp_object_cache->cache_hits : 0; + $this->cache_hit_offset = ! empty( $wp_object_cache->cache_hits ) ? $wp_object_cache->cache_hits : 0; $this->cache_miss_offset = ! empty( $wp_object_cache->cache_misses ) ? $wp_object_cache->cache_misses : 0; } @@ -61,7 +61,7 @@ class Logger { if ( ! is_null( $this->start_time ) ) { $this->time += microtime( true ) - $this->start_time; } - if ( ! is_null( $this->query_offset ) && isset( $wpdb ) ) { + if ( ! is_null( $this->query_offset ) && isset( $wpdb ) && ! empty( $wpdb->queries ) ) { for ( $i = $this->query_offset; $i < count( $wpdb->queries ); $i++ ) { $this->query_time += $wpdb->queries[ $i ][1]; $this->query_count++; @@ -69,20 +69,20 @@ class Logger { } if ( ! is_null( $this->cache_hit_offset ) && ! is_null( $this->cache_miss_offset ) && isset( $wp_object_cache ) ) { - $cache_hits = ! empty( $wp_object_cache->cache_hits ) ? $wp_object_cache->cache_hits : 0; - $cache_misses = ! empty( $wp_object_cache->cache_misses ) ? $wp_object_cache->cache_misses : 0; - $this->cache_hits = $cache_hits - $this->cache_hit_offset; + $cache_hits = ! empty( $wp_object_cache->cache_hits ) ? $wp_object_cache->cache_hits : 0; + $cache_misses = ! empty( $wp_object_cache->cache_misses ) ? $wp_object_cache->cache_misses : 0; + $this->cache_hits = $cache_hits - $this->cache_hit_offset; $this->cache_misses = $cache_misses - $this->cache_miss_offset; - $cache_total = $this->cache_hits + $this->cache_misses; + $cache_total = $this->cache_hits + $this->cache_misses; if ( $cache_total ) { - $ratio = ( $this->cache_hits / $cache_total ) * 100; + $ratio = ( $this->cache_hits / $cache_total ) * 100; $this->cache_ratio = round( $ratio, 2 ) . '%'; } } - $this->start_time = null; - $this->query_offset = null; - $this->cache_hit_offset = null; + $this->start_time = null; + $this->query_offset = null; + $this->cache_hit_offset = null; $this->cache_miss_offset = null; if ( false !== ( $key = array_search( $this, self::$active_loggers ) ) ) { unset( self::$active_loggers[ $key ] ); diff --git a/inc/class-profiler.php b/inc/class-profiler.php index 5c662b0..b6a69cc 100644 --- a/inc/class-profiler.php +++ b/inc/class-profiler.php @@ -8,9 +8,9 @@ class Profiler { private $type; private $focus; - private $loggers = array(); - private $stage_hooks = array( - 'bootstrap' => array( + private $loggers = array(); + private $stage_hooks = array( + 'bootstrap' => array( 'muplugins_loaded', 'plugins_loaded', 'setup_theme', @@ -18,14 +18,14 @@ class Profiler { 'init', 'wp_loaded', ), - 'main_query' => array( + 'main_query' => array( 'parse_request', 'send_headers', 'pre_get_posts', 'the_posts', 'wp', ), - 'template' => array( + 'template' => array( 'template_redirect', 'template_include', 'wp_head', @@ -34,26 +34,26 @@ class Profiler { 'wp_footer', ), ); - private $current_stage_hooks = array(); - private $running_hook = null; - private $previous_filter = null; + private $current_stage_hooks = array(); + private $running_hook = null; + private $previous_filter = null; private $previous_filter_callbacks = null; - private $filter_depth = 0; + private $filter_depth = 0; - private $tick_callback = null; - private $tick_location = null; - private $tick_start_time = null; - private $tick_query_offset = null; - private $tick_cache_hit_offset = null; + private $tick_callback = null; + private $tick_location = null; + private $tick_start_time = null; + private $tick_query_offset = null; + private $tick_cache_hit_offset = null; private $tick_cache_miss_offset = null; public function __construct( $type, $focus ) { - $this->type = $type; + $this->type = $type; $this->focus = $focus; } public function get_loggers() { - foreach( $this->loggers as $i => $logger ) { + foreach ( $this->loggers as $i => $logger ) { if ( is_array( $logger ) ) { $this->loggers[ $i ] = $logger = new Logger( $logger ); } @@ -62,10 +62,10 @@ class Profiler { } if ( ! isset( $logger->location ) ) { list( $name, $location ) = self::get_name_location_from_callback( $logger->callback ); - $logger->callback = $name; - $logger->location = $location; + $logger->callback = $name; + $logger->location = $location; } - $logger->location = self::get_short_location( $logger->location ); + $logger->location = self::get_short_location( $logger->location ); $this->loggers[ $i ] = $logger; } return $this->loggers; @@ -75,29 +75,35 @@ class Profiler { * Run the profiler against WordPress */ public function run() { - WP_CLI::add_wp_hook( 'muplugins_loaded', function(){ - if ( $url = WP_CLI::get_runner()->config['url'] ) { - WP_CLI::set_url( trailingslashit( $url ) ); - } else { - WP_CLI::set_url( home_url( '/' ) ); + WP_CLI::add_wp_hook( + 'muplugins_loaded', + function() { + if ( $url = WP_CLI::get_runner()->config['url'] ) { + WP_CLI::set_url( trailingslashit( $url ) ); + } else { + WP_CLI::set_url( home_url( '/' ) ); + } } - }); - WP_CLI::add_hook( 'after_wp_config_load', function() { - if ( defined( 'SAVEQUERIES' ) && ! SAVEQUERIES ) { - WP_CLI::error( "'SAVEQUERIES' is defined as false, and must be true. Please check your wp-config.php" ); + ); + WP_CLI::add_hook( + 'after_wp_config_load', + function() { + if ( defined( 'SAVEQUERIES' ) && ! SAVEQUERIES ) { + WP_CLI::error( "'SAVEQUERIES' is defined as false, and must be true. Please check your wp-config.php" ); + } + if ( ! defined( 'SAVEQUERIES' ) ) { + define( 'SAVEQUERIES', true ); + } } - if ( ! defined( 'SAVEQUERIES' ) ) { - define( 'SAVEQUERIES', true ); - } - }); + ); if ( 'hook' === $this->type && ':before' === substr( $this->focus, -7, 7 ) ) { $stage_hooks = array(); - foreach( $this->stage_hooks as $hooks ) { + foreach ( $this->stage_hooks as $hooks ) { $stage_hooks = array_merge( $stage_hooks, $hooks ); } $end_hook = substr( $this->focus, 0, -7 ); - $key = array_search( $end_hook, $stage_hooks ); + $key = array_search( $end_hook, $stage_hooks ); if ( isset( $stage_hooks[ $key - 1 ] ) ) { $start_hook = $stage_hooks[ $key - 1 ]; WP_CLI::add_wp_hook( $start_hook, array( $this, 'wp_tick_profile_begin' ), 9999 ); @@ -105,7 +111,7 @@ class Profiler { WP_CLI::add_hook( 'after_wp_config_load', array( $this, 'wp_tick_profile_begin' ) ); } WP_CLI::add_wp_hook( $end_hook, array( $this, 'wp_tick_profile_end' ), -9999 ); - } else if ( 'hook' === $this->type + } elseif ( 'hook' === $this->type && ':after' === substr( $this->focus, -6, 6 ) ) { $start_hook = substr( $this->focus, 0, -6 ); WP_CLI::add_wp_hook( $start_hook, array( $this, 'wp_tick_profile_begin' ), 9999 ); @@ -123,24 +129,24 @@ class Profiler { public function wp_tick_profile_begin( $value = null ) { if ( version_compare( PHP_VERSION, '7.0.0' ) >= 0 ) { - WP_CLI::error( "Profiling intermediate hooks is broken in PHP 7, see https://bugs.php.net/bug.php?id=72966" ); + WP_CLI::error( 'Profiling intermediate hooks is broken in PHP 7, see https://bugs.php.net/bug.php?id=72966' ); } // Disable opcode optimizers. These "optimize" calls out of the stack // and hide calls from the tick handler and backtraces. // Copied from P3 Profiler if ( extension_loaded( 'xcache' ) ) { - @ini_set( 'xcache.optimizer', false ); + @ini_set( 'xcache.optimizer', false ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- ini_set can be disabled on server. } elseif ( extension_loaded( 'apc' ) ) { - @ini_set( 'apc.optimization', 0 ); + @ini_set( 'apc.optimization', 0 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- ini_set can be disabled on server. apc_clear_cache(); } elseif ( extension_loaded( 'eaccelerator' ) ) { - @ini_set( 'eaccelerator.optimizer', 0 ); + @ini_set( 'eaccelerator.optimizer', 0 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- ini_set can be disabled on server. if ( function_exists( 'eaccelerator_optimizer' ) ) { - @eaccelerator_optimizer( false ); + @eaccelerator_optimizer( false ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- disabling eaccelerator on runtime can faild } } elseif ( extension_loaded( 'Zend Optimizer+' ) ) { - @ini_set( 'zend_optimizerplus.optimization_level', 0 ); + @ini_set( 'zend_optimizerplus.optimization_level', 0 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- ini_set can be disabled on server. } register_tick_function( array( $this, 'handle_function_tick' ) ); @@ -162,7 +168,7 @@ class Profiler { */ public function wp_hook_begin() { - foreach( Logger::$active_loggers as $logger ) { + foreach ( Logger::$active_loggers as $logger ) { $logger->start_hook_timer(); } @@ -174,13 +180,18 @@ class Profiler { $this->loggers[ $pseudo_hook ]->stop(); } $callback_count = 0; - $callbacks = self::get_filter_callbacks( $current_filter ); + $callbacks = self::get_filter_callbacks( $current_filter ); if ( false !== $callbacks ) { - foreach( $callbacks as $priority => $cbs ) { + foreach ( $callbacks as $priority => $cbs ) { $callback_count += count( $cbs ); } } - $this->loggers[ $current_filter ] = new Logger( array( 'hook' => $current_filter, 'callback_count' => $callback_count ) ); + $this->loggers[ $current_filter ] = new Logger( + array( + 'hook' => $current_filter, + 'callback_count' => $callback_count, + ) + ); $this->loggers[ $current_filter ]->start(); } @@ -210,24 +221,26 @@ class Profiler { if ( false === $callbacks ) { return; } - $this->previous_filter = $current_filter; + $this->previous_filter = $current_filter; $this->previous_filter_callbacks = $callbacks; - foreach( $callbacks as $priority => $priority_callbacks ) { - foreach( $priority_callbacks as $i => $the_ ) { + foreach ( $callbacks as $priority => $priority_callbacks ) { + foreach ( $priority_callbacks as $i => $the_ ) { $callbacks[ $priority ][ $i ] = array( - 'function' => function() use( $the_, $i ) { + 'function' => function() use ( $the_, $i ) { if ( ! isset( $this->loggers[ $i ] ) ) { - $this->loggers[ $i ] = new Logger( array( - 'callback' => $the_['function'], - ) ); + $this->loggers[ $i ] = new Logger( + array( + 'callback' => $the_['function'], + ) + ); } $this->loggers[ $i ]->start(); $value = call_user_func_array( $the_['function'], func_get_args() ); $this->loggers[ $i ]->stop(); return $value; }, - 'accepted_args' => $the_['accepted_args'], + 'accepted_args' => $the_['accepted_args'], ); } } @@ -239,7 +252,7 @@ class Profiler { */ public function wp_hook_end( $filter_value = null ) { - foreach( Logger::$active_loggers as $logger ) { + foreach ( Logger::$active_loggers as $logger ) { $logger->stop_hook_timer(); } @@ -252,7 +265,7 @@ class Profiler { if ( false !== $key && isset( $this->current_stage_hooks[ $key + 1 ] ) ) { $pseudo_hook = "{$this->current_stage_hooks[$key+1]}:before"; } else { - $pseudo_hook = "{$this->current_stage_hooks[$key]}:after";; + $pseudo_hook = "{$this->current_stage_hooks[$key]}:after"; $this->running_hook = $pseudo_hook; } $this->loggers[ $pseudo_hook ] = new Logger( array( 'hook' => $pseudo_hook ) ); @@ -277,14 +290,14 @@ class Profiler { $callback_hash = md5( serialize( $this->tick_callback . $this->tick_location ) ); if ( ! isset( $this->loggers[ $callback_hash ] ) ) { $this->loggers[ $callback_hash ] = array( - 'callback' => $this->tick_callback, - 'location' => $this->tick_location, - 'time' => 0, - 'query_time' => 0, - 'query_count' => 0, - 'cache_hits' => 0, - 'cache_misses' => 0, - 'cache_ratio' => null, + 'callback' => $this->tick_callback, + 'location' => $this->tick_location, + 'time' => 0, + 'query_time' => 0, + 'query_count' => 0, + 'cache_hits' => 0, + 'cache_misses' => 0, + 'cache_ratio' => null, ); } @@ -298,9 +311,9 @@ class Profiler { } if ( isset( $wp_object_cache ) ) { - $hits = ! empty( $wp_object_cache->cache_hits ) ? $wp_object_cache->cache_hits : 0; + $hits = ! empty( $wp_object_cache->cache_hits ) ? $wp_object_cache->cache_hits : 0; $misses = ! empty( $wp_object_cache->cache_misses ) ? $wp_object_cache->cache_misses : 0; - $this->loggers[ $callback_hash ]['cache_hits'] = ( $hits - $this->tick_cache_hit_offset ) + $this->loggers[ $callback_hash ]['cache_hits']; + $this->loggers[ $callback_hash ]['cache_hits'] = ( $hits - $this->tick_cache_hit_offset ) + $this->loggers[ $callback_hash ]['cache_hits']; $this->loggers[ $callback_hash ]['cache_misses'] = ( $misses - $this->tick_cache_miss_offset ) + $this->loggers[ $callback_hash ]['cache_misses']; $total = $this->loggers[ $callback_hash ]['cache_hits'] + $this->loggers[ $callback_hash ]['cache_misses']; if ( $total ) { @@ -310,7 +323,7 @@ class Profiler { } } - $bt = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT, 2 ); + $bt = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT, 2 ); $frame = $bt[0]; if ( isset( $bt[1] ) ) { $frame = $bt[1]; @@ -319,11 +332,11 @@ class Profiler { $callback = $location = ''; if ( in_array( strtolower( $frame['function'] ), array( 'include', 'require', 'include_once', 'require_once' ) ) ) { $callback = $frame['function'] . " '" . $frame['args'][0] . "'"; - } else if ( isset( $frame['object'] ) && method_exists( $frame['object'], $frame['function'] ) ) { + } elseif ( isset( $frame['object'] ) && method_exists( $frame['object'], $frame['function'] ) ) { $callback = get_class( $frame['object'] ) . '->' . $frame['function'] . '()'; - } else if ( isset( $frame['class'] ) && method_exists( $frame['class'], $frame['function'] ) ) { + } elseif ( isset( $frame['class'] ) && method_exists( $frame['class'], $frame['function'] ) ) { $callback = $frame['class'] . '::' . $frame['function'] . '()'; - } else if ( ! empty( $frame['function'] ) && function_exists( $frame['function'] ) ) { + } elseif ( ! empty( $frame['function'] ) && function_exists( $frame['function'] ) ) { $callback = $frame['function'] . '()'; } elseif ( '__lambda_func' == $frame['function'] || '{closure}' == $frame['function'] ) { $callback = 'function(){}'; @@ -341,11 +354,11 @@ class Profiler { } } - $this->tick_callback = $callback; - $this->tick_location = $location; - $this->tick_start_time = microtime( true ); - $this->tick_query_offset = ! empty( $wpdb->queries ) ? count( $wpdb->queries ) : 0; - $this->tick_cache_hit_offset = ! empty( $wp_object_cache->cache_hits ) ? $wp_object_cache->cache_hits : 0; + $this->tick_callback = $callback; + $this->tick_location = $location; + $this->tick_start_time = microtime( true ); + $this->tick_query_offset = ! empty( $wpdb->queries ) ? count( $wpdb->queries ) : 0; + $this->tick_cache_hit_offset = ! empty( $wp_object_cache->cache_hits ) ? $wp_object_cache->cache_hits : 0; $this->tick_cache_miss_offset = ! empty( $wp_object_cache->cache_misses ) ? $wp_object_cache->cache_misses : 0; } @@ -353,7 +366,7 @@ class Profiler { * Profiling request time for any active Loggers */ public function wp_request_begin( $filter_value = null ) { - foreach( Logger::$active_loggers as $logger ) { + foreach ( Logger::$active_loggers as $logger ) { $logger->start_request_timer(); } return $filter_value; @@ -363,7 +376,7 @@ class Profiler { * Profiling request time for any active Loggers */ public function wp_request_end( $filter_value = null ) { - foreach( Logger::$active_loggers as $logger ) { + foreach ( Logger::$active_loggers as $logger ) { $logger->stop_request_timer(); } return $filter_value; @@ -381,7 +394,7 @@ class Profiler { if ( 'stage' === $this->type && true === $this->focus ) { $hooks = array(); - foreach( $this->stage_hooks as $stage_hook ) { + foreach ( $this->stage_hooks as $stage_hook ) { $hooks = array_merge( $hooks, $stage_hook ); } $this->set_stage_hooks( $hooks ); @@ -390,7 +403,7 @@ class Profiler { if ( 'stage' === $this->type ) { if ( 'bootstrap' === $this->focus ) { $this->set_stage_hooks( $this->stage_hooks['bootstrap'] ); - } else if ( ! $this->focus ) { + } elseif ( ! $this->focus ) { $logger = new Logger( array( 'stage' => 'bootstrap' ) ); $logger->start(); } @@ -412,7 +425,7 @@ class Profiler { if ( 'stage' === $this->type ) { if ( 'main_query' === $this->focus ) { $this->set_stage_hooks( $this->stage_hooks['main_query'] ); - } else if ( ! $this->focus ) { + } elseif ( ! $this->focus ) { $logger = new Logger( array( 'stage' => 'main_query' ) ); $logger->start(); } @@ -433,15 +446,15 @@ class Profiler { define( 'WP_USE_THEMES', true ); // Template is normally loaded in global scope, so we need to replicate - foreach( $GLOBALS as $key => $value ) { - global $$key; + foreach ( $GLOBALS as $key => $value ) { + global ${$key}; // phpcs:ignore PHPCompatibility.PHP.ForbiddenGlobalVariableVariable.NonBareVariableFound -- Syntax is updated to compatible with php 5 and 7. } // Load the theme template. if ( 'stage' === $this->type ) { if ( 'template' === $this->focus ) { $this->set_stage_hooks( $this->stage_hooks['template'] ); - } else if ( ! $this->focus ) { + } elseif ( ! $this->focus ) { $logger = new Logger( array( 'stage' => 'template' ) ); $logger->start(); } @@ -467,20 +480,20 @@ class Profiler { * Get a human-readable name from a callback */ private static function get_name_location_from_callback( $callback ) { - $name = $location = ''; + $name = $location = ''; $reflection = false; if ( is_array( $callback ) && is_object( $callback[0] ) ) { $reflection = new \ReflectionMethod( $callback[0], $callback[1] ); - $name = get_class( $callback[0] ) . '->' . $callback[1] . '()'; + $name = get_class( $callback[0] ) . '->' . $callback[1] . '()'; } elseif ( is_array( $callback ) && method_exists( $callback[0], $callback[1] ) ) { $reflection = new \ReflectionMethod( $callback[0], $callback[1] ); - $name = $callback[0] . '::' . $callback[1] . '()'; + $name = $callback[0] . '::' . $callback[1] . '()'; } elseif ( is_object( $callback ) && is_a( $callback, 'Closure' ) ) { $reflection = new \ReflectionFunction( $callback ); - $name = 'function(){}'; - } else if ( is_string( $callback ) && function_exists( $callback ) ) { + $name = 'function(){}'; + } elseif ( is_string( $callback ) && function_exists( $callback ) ) { $reflection = new \ReflectionFunction( $callback ); - $name = $callback . '()'; + $name = $callback . '()'; } if ( $reflection ) { $location = $reflection->getFileName() . ':' . $reflection->getStartLine(); @@ -498,13 +511,13 @@ class Profiler { $abspath = rtrim( realpath( ABSPATH ), '/' ) . '/'; if ( defined( 'WP_PLUGIN_DIR' ) && 0 === stripos( $location, WP_PLUGIN_DIR ) ) { $location = str_replace( trailingslashit( WP_PLUGIN_DIR ), '', $location ); - } else if ( defined( 'WPMU_PLUGIN_DIR' ) && 0 === stripos( $location, WPMU_PLUGIN_DIR ) ) { + } elseif ( defined( 'WPMU_PLUGIN_DIR' ) && 0 === stripos( $location, WPMU_PLUGIN_DIR ) ) { $location = str_replace( trailingslashit( dirname( WPMU_PLUGIN_DIR ) ), '', $location ); - } else if ( function_exists( 'get_theme_root' ) && 0 === stripos( $location, get_theme_root() ) ) { + } elseif ( function_exists( 'get_theme_root' ) && 0 === stripos( $location, get_theme_root() ) ) { $location = str_replace( trailingslashit( get_theme_root() ), '', $location ); - } else if ( 0 === stripos( $location, $abspath . 'wp-admin/' ) ) { + } elseif ( 0 === stripos( $location, $abspath . 'wp-admin/' ) ) { $location = str_replace( $abspath, '', $location ); - } else if ( 0 === stripos( $location, $abspath . 'wp-includes/' ) ) { + } elseif ( 0 === stripos( $location, $abspath . 'wp-includes/' ) ) { $location = str_replace( $abspath, '', $location ); } return $location; @@ -514,8 +527,8 @@ class Profiler { * Set the hooks for the current stage */ private function set_stage_hooks( $hooks ) { - $this->current_stage_hooks = $hooks; - $pseudo_hook = "{$hooks[0]}:before"; + $this->current_stage_hooks = $hooks; + $pseudo_hook = "{$hooks[0]}:before"; $this->loggers[ $pseudo_hook ] = new Logger( array( 'hook' => $pseudo_hook ) ); $this->loggers[ $pseudo_hook ]->start(); } @@ -563,5 +576,5 @@ class Profiler { $wp_filter[ $filter ] = $callbacks; } } - + } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..4252e09 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,61 @@ + + + Custom ruleset for WP-CLI + + + + + + . + + */.git/* + */ci/* + */features/* + */packages/* + */tests/* + */utils/* + */vendor/* + + + + + + + + + + + + + + + + + + + + + */php/commands/src/CLI_Command.php + + + + + + + + + + + + + + + + + +