diff --git a/CHANGELOG.md b/CHANGELOG.md index 883ccaf..c3efb30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Added +- call backtraces to SQL records +- new format of hook events + +### Changed +- required PHP version to 7.1 + +### Deprecated +- old format of hook events + ## 2.0 - 2018-02-26 ### Added diff --git a/config/psalm.xml b/config/psalm.xml index 5991740..497d40c 100644 --- a/config/psalm.xml +++ b/config/psalm.xml @@ -26,7 +26,18 @@ + + + + + + + + + + + diff --git a/src/Event/Core_Events.php b/src/Event/Core_Events.php index 9830b86..e4fa390 100644 --- a/src/Event/Core_Events.php +++ b/src/Event/Core_Events.php @@ -13,96 +13,16 @@ class Core_Events implements Hook_Event_Config_Interface { */ public function get_events(): array { - $stops = []; - - $stops['plugins_loaded'][-2] = [ - 'action' => 'stop', - 'event' => 'Plugins Load', - 'category' => 'plugin', + return [ + [ 'Plugins Load', 'plugin', null, 'plugins_loaded', - 1, - 2 ], + [ 'Plugins Loaded Hook', 'plugin', 'plugins_loaded' ], + [ 'Themes Load', 'theme', 'setup_theme', 'after_setup_theme' ], + [ 'Core Init', 'core', 'init', 'wp_loaded' ], + [ 'Admin Init', 'core', 'admin_init' ], + [ 'Admin Menu', 'core', '_admin_menu', 'admin_menu' ], + [ 'Toolbar', 'core', 'admin_bar_menu', null ], + [ 'Main Loop', 'theme', 'loop_start', 'loop_end' ], + [ 'Admin Print Scripts', 'core', 'admin_enqueue_scripts', 'admin_print_scripts' ], ]; - - $stops['plugins_loaded'][-1] = [ - 'event' => 'Plugins Loaded Hook', - 'category' => 'plugin', - ]; - - $stops['plugins_loaded'][20] = [ - 'action' => 'stop', - 'event' => 'Plugins Loaded Hook', - 'category' => 'plugin', - ]; - - $stops['setup_theme'][0] = [ - 'event' => 'Themes Load', - 'category' => 'theme', - ]; - - $stops['after_setup_theme'][20] = [ - 'action' => 'stop', - 'event' => 'Themes Load', - 'category' => 'theme', - ]; - - $stops['init'][-1] = [ - 'event' => 'Core Init', - 'category' => 'core', - ]; - - $stops['wp_loaded'][20] = [ - 'action' => 'stop', - 'event' => 'Core Init', - 'category' => 'core', - ]; - - $stops['admin_init'][-1] = [ - 'event' => 'Core Admin Init', - 'category' => 'core', - ]; - - $stops['admin_init'][ PHP_INT_MAX - 1 ] = [ - 'action' => 'stop', - 'event' => 'Core Admin Init', - 'category' => 'core', - ]; - - $stops['_admin_menu'][-1] = [ - 'event' => 'Admin Menu', - 'category' => 'core', - ]; - - $stops['admin_menu'][ PHP_INT_MAX - 1 ] = [ - 'action' => 'stop', - 'event' => 'Admin Menu', - 'category' => 'core', - ]; - - $stops['admin_bar_menu'][-1] = [ - 'event' => 'Toolbar', - 'category' => 'core', - ]; - - $stops['loop_start'][10] = [ - 'event' => 'Main Loop', - 'category' => 'theme', - ]; - - $stops['loop_end'][10] = [ - 'action' => 'stop', - 'event' => 'Main Loop', - 'category' => 'theme', - ]; - - $stops['admin_enqueue_scripts'][10] = [ - 'event' => 'Admin Print Scripts', - 'category' => 'core', - ]; - - $stops['admin_print_scripts'][10] = [ - 'action' => 'stop', - 'event' => 'Admin Print Scripts', - 'category' => 'core', - ]; - - return $stops; } } diff --git a/src/Event/Genesis_Events.php b/src/Event/Genesis_Events.php index a48f94b..5aa3ae6 100644 --- a/src/Event/Genesis_Events.php +++ b/src/Event/Genesis_Events.php @@ -15,45 +15,15 @@ class Genesis_Events implements Hook_Event_Config_Interface { */ public function get_events(): array { - $events = []; - - if ( ! \function_exists( 'genesis' ) ) { - return $events; - } - - $events['genesis_before_header'][10] = [ - 'event' => 'Header', - 'category' => 'theme', - ]; - - $events['genesis_after_header'][10] = [ - 'action' => 'stop', - 'event' => 'Header', - 'category' => 'theme', - ]; - - $events['genesis_before_sidebar_widget_area'][10] = [ - 'event' => 'Sidebar', - 'category' => 'theme', - ]; - - $events['genesis_after_sidebar_widget_area'][10] = [ - 'action' => 'stop', - 'event' => 'Sidebar', - 'category' => 'theme', - ]; - - $events['genesis_before_sidebar_alt_widget_area'][10] = [ - 'event' => 'Sidebar (alternate)', - 'category' => 'theme', - ]; - - $events['genesis_after_sidebar_alt_widget_area'][10] = [ - 'action' => 'stop', - 'event' => 'Sidebar (alternate)', - 'category' => 'theme', - ]; - - return $events; + return \function_exists( 'genesis' ) ? [ + [ 'Header', 'theme', 'genesis_before_header', 'genesis_after_header' ], + [ 'Sidebar', 'theme', 'genesis_before_sidebar_widget_area', 'genesis_after_sidebar_widget_area' ], + [ + 'Sidebar (alternate)', + 'theme', + 'genesis_before_sidebar_alt_widget_area', + 'genesis_after_sidebar_alt_widget_area', + ], + ] : []; } } diff --git a/src/Event/Hook_Event_Config_Interface.php b/src/Event/Hook_Event_Config_Interface.php index 1516b83..b0c8fd3 100644 --- a/src/Event/Hook_Event_Config_Interface.php +++ b/src/Event/Hook_Event_Config_Interface.php @@ -9,7 +9,9 @@ namespace Rarst\Laps\Event; interface Hook_Event_Config_Interface { /** - * @return array + * @see Hook_Record_Collector::add_event() + * + * @return array[] */ public function get_events(): array; } diff --git a/src/Event/Hybrid_Events.php b/src/Event/Hybrid_Events.php index 60f051c..e3fa779 100644 --- a/src/Event/Hybrid_Events.php +++ b/src/Event/Hybrid_Events.php @@ -24,15 +24,8 @@ class Hybrid_Events implements Hook_Event_Config_Interface { /** @var string $prefix */ $prefix = hybrid_get_prefix(); - $events["{$prefix}_before_header"][10] = [ - 'event' => 'Header', - 'category' => 'theme', - ]; - - $events["{$prefix}_after_header"][10] = [ - 'action' => 'stop', - 'event' => 'Header', - 'category' => 'theme', + $events = [ + [ 'Header', 'theme', "{$prefix}_before_header", "{$prefix}_after_header" ], ]; /** @var array $sidebars */ @@ -41,16 +34,11 @@ class Hybrid_Events implements Hook_Event_Config_Interface { if ( ! empty( $sidebars[0] ) ) { /** @var string $sidebar */ foreach ( $sidebars[0] as $sidebar ) { - - $events["{$prefix}_before_{$sidebar}"][10] = [ - 'event' => "Sidebar ({$sidebar})", - 'category' => 'theme', - ]; - - $events["{$prefix}_after_{$sidebar}"][10] = [ - 'action' => 'stop', - 'event' => "Sidebar ({$sidebar})", - 'category' => 'theme', + $events[] = [ + "Sidebar ({$sidebar})", + 'theme', + "{$prefix}_before_{$sidebar}", + "{$prefix}_after_{$sidebar}", ]; } } diff --git a/src/Event/THA_Events.php b/src/Event/THA_Events.php index 8f7975f..04bbfde 100644 --- a/src/Event/THA_Events.php +++ b/src/Event/THA_Events.php @@ -15,34 +15,9 @@ class THA_Events implements Hook_Event_Config_Interface { */ public function get_events(): array { - $events = []; - - if ( ! \defined( 'THA_HOOKS_VERSION' ) ) { - return $events; - } - - $events['tha_header_before'][10] = [ - 'event' => 'Header', - 'category' => 'theme', - ]; - - $events['tha_header_after'][10] = [ - 'action' => 'stop', - 'event' => 'Header', - 'category' => 'theme', - ]; - - $events['tha_sidebars_before'][10] = [ - 'event' => 'Sidebars', - 'category' => 'theme', - ]; - - $events['tha_sidebars_after'][10] = [ - 'action' => 'stop', - 'event' => 'Sidebars', - 'category' => 'theme', - ]; - - return $events; + return \defined( 'THA_HOOKS_VERSION' ) ? [ + [ 'Header', 'theme', 'tha_header_before', 'tha_header_after' ], + [ 'Sidebars', 'theme', 'tha_sidebars_before', 'tha_sidebars_after' ], + ] : []; } } diff --git a/src/Event/Yoast_Events.php b/src/Event/Yoast_Events.php index e8628d5..0b94c8f 100644 --- a/src/Event/Yoast_Events.php +++ b/src/Event/Yoast_Events.php @@ -13,23 +13,8 @@ class Yoast_Events implements Hook_Event_Config_Interface { */ public function get_events(): array { - $stops = []; - - if ( ! class_exists( 'WPSEO_Frontend' ) ) { - return $stops; - } - - $stops['wpseo_head'][1] = [ - 'event' => 'WP SEO head hook', - 'category' => 'plugin', - ]; - - $stops['wpseo_head'][100] = [ - 'action' => 'stop', - 'event' => 'WP SEO head hook', - 'category' => 'plugin', - ]; - - return $stops; + return class_exists( 'WPSEO_Frontend' ) ? [ + [ 'WP SEO head hook', 'plugin', 'wpseo_head' ], + ] : []; } } diff --git a/src/Record/Hook_Record_Collector.php b/src/Record/Hook_Record_Collector.php index 2cd7373..564a8f4 100644 --- a/src/Record/Hook_Record_Collector.php +++ b/src/Record/Hook_Record_Collector.php @@ -43,17 +43,65 @@ class Hook_Record_Collector extends Stopwatch_Record_Collector { $this->events = array_merge( $this->events, $stops ); /** - * @var string $hook_name - * @var array $data + * @var int|string $key + * @var array $data */ - foreach ( $stops as $hook_name => $data ) { + foreach ( $stops as $key => $data ) { + + if ( is_int( $key ) ) { + /** @var array{0:string} $data */ + $this->add_event( ...$data ); + continue; + } + /** @var int $priority */ foreach ( array_keys( $data ) as $priority ) { - add_action( $hook_name, [ $this, 'tick' ], $priority ); + add_action( $key, [ $this, 'tick' ], $priority ); } } } + /** + * Add a start/stop pair of hook event. + * + * @param string $event Hook event name. + * @param string $category Hook event category. + * @param string|null $start Start hook name. Pass null to ignore. + * @param string|null $stop Stop hook name (defaults to start name). + * @param int $start_priority Start hook priority (defaults to -1). + * @param int $stop_priority Stop hook priority (defaults to max int). + */ + private function add_event( + string $event, + string $category, + ?string $start = null, + ?string $stop = null, + int $start_priority = - 1, + int $stop_priority = PHP_INT_MAX + ): void { + if ( null === $stop ) { + $stop = $start; + } + + $collector = $this; + + if ( null !== $start ) { + add_action( $start, function ( $input = null ) use ( $collector, $event, $category ) { + $collector->start( $event, $category ); + + return $input; + }, $start_priority ); + } + + if ( null !== $stop ) { + add_action( $stop, function ( $input = null ) use ( $collector, $event ) { + $collector->stop( $event ); + + return $input; + }, $stop_priority ); + } + } + /** * When theme is done possibly add vendor-specific events. */ @@ -67,6 +115,9 @@ class Hook_Record_Collector extends Stopwatch_Record_Collector { /** * Mark action for the event on Stopwatch. * + * @deprecated 3.0:4.0 Deprecated in favor of the new format. + * @codeCoverageIgnore + * * @param mixed $input Pass through if added to filter. * * @return mixed @@ -109,7 +160,7 @@ class Hook_Record_Collector extends Stopwatch_Record_Collector { */ public function get_records(): array { - $this->stopwatch->stop( 'Toolbar' ); + $this->stop( 'Toolbar' ); return parent::get_records(); } diff --git a/tests/Record/HookTest.php b/tests/Record/HookTest.php index 0fa8d67..3c0b76b 100644 --- a/tests/Record/HookTest.php +++ b/tests/Record/HookTest.php @@ -1,8 +1,8 @@ assertTrue( $stopwatch->isStarted( 'Plugins Load' ) ); $this->assertTrue( has_action( 'after_setup_theme', [ $collector, 'after_setup_theme' ] ) ); + $this->assertTrue( has_action( 'plugins_loaded', 'function ($input)' ) ); + $collector->after_setup_theme(); - - Functions\expect( 'current_filter' )->once()->andReturn( 'plugins_loaded' ); - Functions\expect( 'wp_parse_args' )->once()->andReturnFirstArg(); - - global $wp_filter; - - $wp_hook = $this->getMockBuilder( 'WP_Hook' ) - ->allowMockingUnknownTypes() - ->setMethods( [ 'current_priority' ] ) - ->getMock(); - - $wp_hook->method( 'current_priority' )->willReturn( - 2 ); - - $wp_filter['plugins_loaded'] = $wp_hook; - - $collector->tick(); - - $this->assertFalse( $stopwatch->isStarted( 'Plugins Load' ) ); - $stopwatch->start( 'Toolbar' ); $collector->get_records();