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();