From d84b7167423e937e13a84ab0e5092f8345b4cca5 Mon Sep 17 00:00:00 2001
From: Sagar Tamang <mi5t4n@gmail.com>
Date: Tue, 7 Mar 2023 12:55:20 +0545
Subject: [PATCH] fix - allow user-defined validate and sanitize callbacks in
 rest json schema.

---
 src/wp-includes/rest-api.php                  |  8 ++++++
 .../tests/rest-api/rest-controller.php        | 16 +++++++++++
 .../tests/rest-api/rest-test-controller.php   | 28 ++++++++++---------
 3 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
index 33fcdd5b8a..41a290f11d 100644
--- a/src/wp-includes/rest-api.php
+++ b/src/wp-includes/rest-api.php
@@ -3272,6 +3272,14 @@ function rest_get_endpoint_args_for_schema( $schema, $method = WP_REST_Server::C
 			'sanitize_callback' => 'rest_sanitize_request_arg',
 		);
 
+		if ( isset( $params['validate_callback'] ) && is_callable( $params['validate_callback'] ) ) {
+			$endpoint_args[ $field_id ]['validate_callback'] = $params['validate_callback'];
+		}
+
+		if ( isset( $params['sanitize_callback'] ) && is_callable( $params['sanitize_callback'] ) ) {
+			$endpoint_args[ $field_id ]['sanitize_callback'] = $params['sanitize_callback'];
+		}
+
 		if ( WP_REST_Server::CREATABLE === $method && isset( $params['default'] ) ) {
 			$endpoint_args[ $field_id ]['default'] = $params['default'];
 		}
diff --git a/tests/phpunit/tests/rest-api/rest-controller.php b/tests/phpunit/tests/rest-api/rest-controller.php
index f7da75327a..912f7a7255 100644
--- a/tests/phpunit/tests/rest-api/rest-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-controller.php
@@ -300,6 +300,22 @@ class WP_Test_REST_Controller extends WP_Test_REST_TestCase {
 		$this->assertArrayHasKey( 'someobject', $args );
 	}
 
+	public function test_get_endpoint_args_for_item_schema_validate_callback() {
+		$controller = new WP_REST_Test_Controller();
+		$args       = rest_get_endpoint_args_for_schema( $controller->get_item_schema() );
+
+		$this->assertSame( $args['somestring']['validate_callback'], '__return_true' );
+		$this->assertSame( $args['sometextfield']['validate_callback'], 'rest_validate_request_arg' );
+	}
+
+	public function test_get_endpoint_args_for_item_schema_sanitize_callback() {
+		$controller = new WP_REST_Test_Controller();
+		$args       = rest_get_endpoint_args_for_schema( $controller->get_item_schema() );
+
+		$this->assertSame( $args['someinteger']['sanitize_callback'], 'absint' );
+		$this->assertSame( $args['sometextfield']['sanitize_callback'], 'rest_sanitize_request_arg' );
+	}
+
 	public function test_get_endpoint_args_for_item_schema_description() {
 		$controller = new WP_REST_Test_Controller();
 		$args       = rest_get_endpoint_args_for_schema( $controller->get_item_schema() );
diff --git a/tests/phpunit/tests/rest-api/rest-test-controller.php b/tests/phpunit/tests/rest-api/rest-test-controller.php
index 042f37cf8b..8c47eed942 100644
--- a/tests/phpunit/tests/rest-api/rest-test-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-test-controller.php
@@ -35,21 +35,23 @@ class WP_REST_Test_Controller extends WP_REST_Controller {
 			'type'       => 'object',
 			'properties' => array(
 				'somestring'        => array(
-					'type'        => 'string',
-					'description' => 'A pretty string.',
-					'minLength'   => 3,
-					'maxLength'   => 3,
-					'pattern'     => '[a-zA-Z]+',
-					'context'     => array( 'view' ),
+					'type'              => 'string',
+					'description'       => 'A pretty string.',
+					'minLength'         => 3,
+					'maxLength'         => 3,
+					'pattern'           => '[a-zA-Z]+',
+					'context'           => array( 'view' ),
+					'validate_callback' => '__return_true',
 				),
 				'someinteger'       => array(
-					'type'             => 'integer',
-					'multipleOf'       => 10,
-					'minimum'          => 100,
-					'maximum'          => 200,
-					'exclusiveMinimum' => true,
-					'exclusiveMaximum' => true,
-					'context'          => array( 'view' ),
+					'type'              => 'integer',
+					'multipleOf'        => 10,
+					'minimum'           => 100,
+					'maximum'           => 200,
+					'exclusiveMinimum'  => true,
+					'exclusiveMaximum'  => true,
+					'sanitize_callback' => 'absint',
+					'context'           => array( 'view' ),
 				),
 				'someboolean'       => array(
 					'type'    => 'boolean',
-- 
2.34.1

