diff --git a/includes/abilities-api/class-wp-ability.php b/includes/abilities-api/class-wp-ability.php index b9d686e..280b7fc 100644 --- a/includes/abilities-api/class-wp-ability.php +++ b/includes/abilities-api/class-wp-ability.php @@ -381,6 +381,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( callable $callback, $input = null ) { + $args = array(); + if ( ! empty( $this->get_input_schema() ) ) { + $args[] = $input; + } + + return $callback( ...$args ); + } + /** * Checks whether the ability has the necessary permissions. * @@ -397,11 +415,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 ); } /** @@ -439,11 +453,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 8e439ff..7c86152 100644 --- a/tests/unit/abilities-api/wpAbility.php +++ b/tests/unit/abilities-api/wpAbility.php @@ -349,6 +349,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 ); + } + + /** + * 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. + */ + 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. */