diff --git a/src/Dispatchers/WordpressDispatcher.php b/src/Dispatchers/WordpressDispatcher.php index 008062b..fc86d23 100644 --- a/src/Dispatchers/WordpressDispatcher.php +++ b/src/Dispatchers/WordpressDispatcher.php @@ -215,20 +215,38 @@ public function dispatch( $event, ...$payload ) { if ( ! $this->hasListeners( $event ) ) { - if ( is_callable( [ $payload, 'default' ] ) ) { - return $payload->default(); - } - - return is_object( $payload ) ? $payload : $payload[0]; + return $this->determineDefault($payload); } - - return $this->hook_api->applyFilter( $event, $payload ); + + + + $filtered = $this->hook_api->applyFilter( $event, $payload ); + + if ( $filtered === $payload ) { + + return $this->determineDefault($payload); + + } + + return $filtered; } - + + private function determineDefault( $payload) { + + if ( is_callable( [ $payload, 'default' ] ) ) { + + return $payload->default(); + + } + + return is_object( $payload ) ? $payload : $payload[0]; + + } + /** * Parse the given event and payload and prepare them for dispatching. * If the event that got dispatched is an object we will use the classname as the event and @@ -252,8 +270,7 @@ private function parseEventAndPayload( $event, $payload ): array { } - - + /** * * Searches the first registered listener that implements @@ -400,8 +417,7 @@ private function resolveAlias( $event, $callable ) { return $this->aliases[ $event ][ $key ] ?? classNameIfClassExists( $callable ); } - - + /** * Uses the alias of the listener to find and return * the object hash of the listener callable @@ -471,8 +487,7 @@ public function forgetOne( string $event, $listener ) { } } - - + /** * * Checks if a registered closure is marked as unremovable diff --git a/tests/Unit/WordpressDispatcherTest.php b/tests/Unit/WordpressDispatcherTest.php index 3ce0b01..9764b90 100644 --- a/tests/Unit/WordpressDispatcherTest.php +++ b/tests/Unit/WordpressDispatcherTest.php @@ -803,8 +803,7 @@ public function a_listener_can_handle_an_event_conditionally_based_on_runtime_de } - - + /** @test */ public function the_payload_is_not_changed_when_a_listener_does_not_listen_at_runtime() { @@ -1043,7 +1042,38 @@ public function if_no_return_value_can_be_created_from_the_dispatched_object_the } - + + /** @test */ + public function if_listeners_are_present_but_none_of_them_handles_the_event_conditionally_the_default_value_is_returned_for_object_events() + { + + // Class Listener + $_SERVER['should_handle'] = FALSE; + + $this->dispatcher->listen( FilterableEvent::class, ConditionalListener::class . '@foobar' ); + + $result = $this->dispatcher->dispatch( new FilterableEvent( 'foobar' ) ); + + $this->assertSame( 'foobar', $result ); + + + } + + /** @test */ + public function if_listeners_are_present_but_none_of_them_handles_the_event_conditionally_the_default_value_is_returned_for_non_object_events() + { + + // Class Listener + $_SERVER['should_handle'] = FALSE; + + $this->dispatcher->listen( 'event', ConditionalListener::class . '@foobar' ); + + $value1 = $this->dispatcher->dispatch( 'event', 'foo', 'bar', 'baz' ); + + $this->assertEquals( 'foo', $value1 ); + + + } private function reset(): void {