diff --git a/src/mantle/framework/events/class-discover-events.php b/src/mantle/framework/events/class-discover-events.php index 07cdd8073..7dafadfeb 100644 --- a/src/mantle/framework/events/class-discover-events.php +++ b/src/mantle/framework/events/class-discover-events.php @@ -7,6 +7,7 @@ namespace Mantle\Framework\Events; +use Mantle\Support\Attributes\Action; use Mantle\Support\Reflector; use Mantle\Support\Str; use ReflectionClass; @@ -79,8 +80,26 @@ protected static function get_listener_events( $listeners, string $base_path ): } foreach ( $listener->getMethods( ReflectionMethod::IS_PUBLIC ) as $method ) { + // Check for attribute support with PHP 8. + if ( version_compare( phpversion(), '8.0.0', '>=' ) ) { + // Check if the method has an attribute action. + $action_attributes = $method->getAttributes( Action::class ); + + if ( ! empty( $action_attributes ) ) { + foreach ( $action_attributes as $attribute ) { + $instance = $attribute->newInstance(); + + $listener_events[ $listener->name . '@' . $method->name ] = [ + [ $instance->action ], + $instance->priority, + ]; + } + + continue; + } + } + // Handle WordPress hooks being registered with a listener. - // todo: move to use attributes with PHP 8. if ( Str::starts_with( $method->name, 'on_' ) ) { $hook = Str::after( $method->name, 'on_' ); $priority = 10; diff --git a/tests/framework/events/fixtures/listeners/class-example-listener.php b/tests/framework/events/fixtures/listeners/class-example-listener.php index f48a5336f..39e41e402 100644 --- a/tests/framework/events/fixtures/listeners/class-example-listener.php +++ b/tests/framework/events/fixtures/listeners/class-example-listener.php @@ -1,6 +1,7 @@ assertEquals( [ + $is_php_8 = version_compare( PHP_VERSION, '8.0.0', '>=' ); + + $expected = [ // Type hinted events. Event_One::class => [ [ Example_Listener::class . '@handle', 10 ], [ Example_Listener::class . '@handle_event_one', 10 ], + [ Example_Listener::class . '@handle_attribute_event_one', 10 ], ], Event_Two::class => [ [ Example_Listener::class . '@handle_event_two', 10 ], @@ -50,6 +55,19 @@ public function test_events_can_be_discovered() { 'pre_get_posts' => [ [ Example_Listener::class . '@on_pre_get_posts_at_20', 20 ], ], - ], $events ); + 'attribute-event' => $is_php_8 ? [ + [ Example_Listener::class . '@handle_attribute_string_callback', 10 ], + [ Example_Listener::class . '@handle_attribute_string_callback_priority', 20 ], + ] : null, + ]; + + // Filter out expected events for PHP 7.4. + if ( ! $is_php_8 ) { + $expected = collect( $expected ) + ->filter( fn ( $events ) => null !== $events ) + ->to_array(); + } + + $this->assertEquals( $expected, $events ); } }