From 53233b4635ca2de02322a6364e4a944dd9f44db5 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 26 Sep 2025 14:32:34 +0200 Subject: [PATCH 1/3] Introduce `invoke_callback` helper method in `WP_Ability` class --- includes/abilities-api/class-wp-ability.php | 30 ++++++--- tests/unit/abilities-api/wpAbility.php | 68 +++++++++++++++++++++ 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/includes/abilities-api/class-wp-ability.php b/includes/abilities-api/class-wp-ability.php index fc422f0..e0d8521 100644 --- a/includes/abilities-api/class-wp-ability.php +++ b/includes/abilities-api/class-wp-ability.php @@ -399,6 +399,24 @@ protected function validate_input( $input = null ) { return true; } + /** + * Invokes a callable, ensuring the input is passed through only if the input schema is defined. + * + * @since n.e.x.t + * + * @param callable $callback The callable to invoke. + * @param mixed $input Optional. The input data for the ability. Default `null`. + * @return mixed The result of the callable execution. + */ + protected function invoke_callback( $callback, $input = null ) { + $args = array(); + if ( ! empty( $this->get_input_schema() ) ) { + $args[] = $input; + } + + return $callback( ...$args ); + } + /** * Checks whether the ability has the necessary permissions. * @@ -415,11 +433,7 @@ public function check_permissions( $input = null ) { return $is_valid; } - if ( empty( $this->get_input_schema() ) ) { - return call_user_func( $this->permission_callback ); - } - - return call_user_func( $this->permission_callback, $input ); + return $this->invoke_callback( $this->permission_callback, $input ); } /** @@ -457,11 +471,7 @@ protected function do_execute( $input = null ) { ); } - if ( empty( $this->get_input_schema() ) ) { - return call_user_func( $this->execute_callback ); - } - - return call_user_func( $this->execute_callback, $input ); + return $this->invoke_callback( $this->execute_callback, $input ); } /** diff --git a/tests/unit/abilities-api/wpAbility.php b/tests/unit/abilities-api/wpAbility.php index 6b57157..49fa9e2 100644 --- a/tests/unit/abilities-api/wpAbility.php +++ b/tests/unit/abilities-api/wpAbility.php @@ -343,6 +343,74 @@ public function test_execute_input( $input_schema, $execute_callback, $input, $r $this->assertSame( $result, $ability->execute( $input ) ); } + /** + * A static method to be used as a callback in tests. + * + * @param string $input An input string. + * @return int The length of the input string. + */ + public static function my_static_execute_callback( string $input ): int { + return strlen( $input ); + } + + /** + * A instance method to be used as a callback in tests. + * + * @param string $input An input string. + * @return int The length of the input string. + */ + public function my_instance_execute_callback( string $input ): int { + return strlen( $input ); + } + + /** + * Data provider for testing different types of execute callbacks. + */ + public function data_execute_callback() { + return array( + 'function name string' => array( + 'strlen', + ), + 'closure' => array( + static function ( string $input ): int { + return strlen( $input ); + }, + ), + 'static class method string' => array( + 'Tests_Abilities_API_WpAbility::my_static_execute_callback', + ), + 'static class method array' => array( + array( 'Tests_Abilities_API_WpAbility', 'my_static_execute_callback' ), + ), + 'object method' => array( + array( $this, 'my_instance_execute_callback' ), + ), + ); + } + + /** + * Tests the execution of the ability with different types of callbacks. + * + * @dataProvider data_execute_callback + */ + public function test_execute_with_different_callbacks( $execute_callback) { + $args = array_merge( + self::$test_ability_properties, + array( + 'input_schema' => array( + 'type' => 'string', + 'description' => 'Test input string.', + 'required' => true, + ), + 'execute_callback' => $execute_callback, + ) + ); + + $ability = new WP_Ability( self::$test_ability_name, $args ); + + $this->assertSame( 6, $ability->execute( 'hello!' ) ); + } + /** * Tests the execution of the ability with no input. */ From 3b7f4cc51e7bc01e7af33370aa410545ecb94165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=B3=C5=82kowski?= Date: Fri, 10 Oct 2025 11:52:29 +0200 Subject: [PATCH 2/3] Update tests/unit/abilities-api/wpAbility.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- tests/unit/abilities-api/wpAbility.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/abilities-api/wpAbility.php b/tests/unit/abilities-api/wpAbility.php index 49fa9e2..4dc5941 100644 --- a/tests/unit/abilities-api/wpAbility.php +++ b/tests/unit/abilities-api/wpAbility.php @@ -354,7 +354,7 @@ public static function my_static_execute_callback( string $input ): int { } /** - * A instance method to be used as a callback in tests. + * An instance method to be used as a callback in tests. * * @param string $input An input string. * @return int The length of the input string. From 2014a43a0e55e828c99e17ad7ad361e4534ce878 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 10 Oct 2025 12:00:26 +0200 Subject: [PATCH 3/3] Add callable type hint --- includes/abilities-api/class-wp-ability.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/abilities-api/class-wp-ability.php b/includes/abilities-api/class-wp-ability.php index e0d8521..abc17ac 100644 --- a/includes/abilities-api/class-wp-ability.php +++ b/includes/abilities-api/class-wp-ability.php @@ -408,7 +408,7 @@ protected function validate_input( $input = null ) { * @param mixed $input Optional. The input data for the ability. Default `null`. * @return mixed The result of the callable execution. */ - protected function invoke_callback( $callback, $input = null ) { + protected function invoke_callback( callable $callback, $input = null ) { $args = array(); if ( ! empty( $this->get_input_schema() ) ) { $args[] = $input;