diff --git a/CHANGELOG.md b/CHANGELOG.md index 18a635e..3e56802 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - call backtraces to SQL records and HTTP calls - new format of hook events - sidebar tracking +- list of callbacks to hook events ### Changed - required PHP version to 7.1 diff --git a/src/Event/Core_Events.php b/src/Event/Core_Events.php index 5895ff2..9e5938c 100644 --- a/src/Event/Core_Events.php +++ b/src/Event/Core_Events.php @@ -27,7 +27,7 @@ class Core_Events implements Hook_Event_Config_Interface { [ 'Main Loop', 'theme', 'loop_start', 'loop_end' ], [ 'Sidebar', 'theme', 'dynamic_sidebar_before', 'dynamic_sidebar_after' ], [ 'Toolbar', 'core', 'admin_bar_menu', '' ], - [ 'Footer Hook', 'theme', 'wp_footer', '' ], + [ 'Footer Hook', 'theme', 'wp_footer' ], ]; } } diff --git a/src/Formatter/Hook_Formatter.php b/src/Formatter/Hook_Formatter.php new file mode 100644 index 0000000..b75cdef --- /dev/null +++ b/src/Formatter/Hook_Formatter.php @@ -0,0 +1,61 @@ +callbacks; + } + ksort( $hook ); + + foreach ( $hook as $priority => $functions ) { + foreach ( $functions as $function ) { + $callback = $function['function']; + + if ( is_string( $callback ) ) { + + } elseif ( is_a( $callback, 'Closure' ) ) { + $closure = new \ReflectionFunction( $callback ); + $callback = 'closure from ' . $closure->getFileName() . '::' . $closure->getStartLine(); + + if ( false !== strpos( $callback, 'Hook_Record_Collector' ) ) { + continue; + } + } elseif ( is_object( $callback ) ) { + $class = new \ReflectionClass( $callback ); + $name = $class->getName(); + if ( 0 === strpos( $name, 'class@anonymous' ) ) { + $callback = 'anonymous class from ' . $class->getFileName() . '::' . $class->getStartLine(); + } else { + $callback = $name; + } + } elseif ( is_string( $callback[0] ) ) { // Static method call. + $callback = $callback[0] . '::' . $callback[1]; + } elseif ( is_object( $callback[0] ) ) { + $callback = get_class( $callback[0] ) . '->' . $callback[1]; + } + + $callback .= ( 1 === (int) $function['accepted_args'] ) ? '' : "({$function['accepted_args']})"; + + $callbacks[] = $callback; + } + } + + return $callbacks; + } +} + diff --git a/src/Record/Hook_Record_Collector.php b/src/Record/Hook_Record_Collector.php index 3ce20a4..a81c65f 100644 --- a/src/Record/Hook_Record_Collector.php +++ b/src/Record/Hook_Record_Collector.php @@ -4,7 +4,9 @@ declare( strict_types=1 ); namespace Rarst\Laps\Record; use Rarst\Laps\Event\Hook_Event_Config_Interface; +use Rarst\Laps\Formatter\Hook_Formatter; use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\Stopwatch\StopwatchEvent; /** * Processes events based on hooked starts and stops. @@ -17,6 +19,12 @@ class Hook_Record_Collector extends Stopwatch_Record_Collector { /** @var array $events */ protected $events = []; + /** @var array */ + protected $callbacks = []; + + /** @var Hook_Formatter */ + protected $formatter; + /** * @param Stopwatch $stopwatch Stopwatch instance. * @param Hook_Event_Config_Interface[] $event_configs Starts and stops configuration. @@ -31,6 +39,8 @@ class Hook_Record_Collector extends Stopwatch_Record_Collector { $this->event_configs = $event_configs; add_action( 'after_setup_theme', [ $this, 'after_setup_theme' ], 15 ); + + $this->formatter = new Hook_Formatter(); } /** @@ -84,12 +94,17 @@ class Hook_Record_Collector extends Stopwatch_Record_Collector { } if ( '' !== $start ) { - add_action( $start, function ( $input = null ) use ( $event, $category ) { + add_action( $start, function ( $input = null ) use ( $event, $category, $start, $stop ) { if ( 'Sidebar' === $event ) { $event = $input; } + if ( $start === $stop ) { + global $wp_filter; + $this->callbacks[ $event ] = $wp_filter[ $start ]; + } + $this->start( $event, $category ); return $input; @@ -173,4 +188,21 @@ class Hook_Record_Collector extends Stopwatch_Record_Collector { return parent::get_records(); } + + /** + * @param string $name Event name. + * @param StopwatchEvent $event Stopwatch event instance. + * + * @return Stopwatch_Record + */ + protected function transform( string $name, StopwatchEvent $event ): Stopwatch_Record { + + $description = ''; + + if ( isset( $this->callbacks[ $name ] ) ) { + $description = implode( '
', $this->formatter->format( $this->callbacks[ $name ] ) ); + } + + return new Stopwatch_Record( $name, $event, $description ); + } }