diff --git a/src/wp-includes/class-wp-customize-manager.php b/src/wp-includes/class-wp-customize-manager.php index 60b07a83f1..761e3216ee 100644 --- a/src/wp-includes/class-wp-customize-manager.php +++ b/src/wp-includes/class-wp-customize-manager.php @@ -670,14 +670,15 @@ final class WP_Customize_Manager { if ( ! array_key_exists( $setting->id, $post_values ) ) { return $default; } - $value = $setting->sanitize( $post_values[ $setting->id ] ); - if ( is_null( $value ) || is_wp_error( $value ) ) { - return $default; - } + $value = $post_values[ $setting->id ]; $valid = $setting->validate( $value ); if ( is_wp_error( $valid ) ) { return $default; } + $value = $setting->sanitize( $value ); + if ( is_null( $value ) || is_wp_error( $value ) ) { + return $default; + } return $value; } @@ -1007,8 +1008,16 @@ final class WP_Customize_Manager { if ( ! $setting || is_null( $unsanitized_value ) ) { continue; } - $validity = $setting->validate( $setting->sanitize( $unsanitized_value ) ); - if ( false === $validity || null === $validity ) { + $validity = $setting->validate( $unsanitized_value ); + if ( ! is_wp_error( $validity ) ) { + $value = $setting->sanitize( $unsanitized_value ); + if ( is_null( $value ) ) { + $validity = false; + } elseif ( is_wp_error( $value ) ) { + $validity = $value; + } + } + if ( false === $validity ) { $validity = new WP_Error( 'invalid_value', __( 'Invalid value.' ) ); } $validities[ $setting_id ] = $validity; diff --git a/tests/phpunit/tests/customize/manager.php b/tests/phpunit/tests/customize/manager.php index 437f4101fc..011bd8de2d 100644 --- a/tests/phpunit/tests/customize/manager.php +++ b/tests/phpunit/tests/customize/manager.php @@ -190,6 +190,50 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { return $validity; } + /** + * Test the WP_Customize_Manager::post_value() method to make sure that the validation and sanitization are done in the right order. + * + * @ticket 37247 + */ + function test_post_value_validation_sanitization_order() { + $default_value = '0'; + $setting = $this->manager->add_setting( 'numeric', array( + 'validate_callback' => array( $this, 'filter_customize_validate_numeric' ), + 'sanitize_callback' => array( $this, 'filter_customize_sanitize_numeric' ), + ) ); + $this->assertEquals( $default_value, $this->manager->post_value( $setting, $default_value ) ); + $this->assertEquals( $default_value, $setting->post_value( $default_value ) ); + + $post_value = '42'; + $this->manager->set_post_value( 'numeric', $post_value ); + $this->assertEquals( $post_value, $this->manager->post_value( $setting, $default_value ) ); + $this->assertEquals( $post_value, $setting->post_value( $default_value ) ); + } + + /** + * Filter customize_validate callback for a numeric value. + * + * @param mixed $value Value. + * @return string|WP_Error + */ + function filter_customize_sanitize_numeric( $value ) { + return absint( $value ); + } + + /** + * Filter customize_validate callback for a numeric value. + * + * @param WP_Error $validity Validity. + * @param mixed $value Value. + * @return WP_Error + */ + function filter_customize_validate_numeric( $validity, $value ) { + if ( ! is_string( $value ) || ! is_numeric( $value ) ) { + $validity->add( 'invalid_value_in_validate', __( 'Invalid value.' ), array( 'source' => 'filter_customize_validate_numeric' ) ); + } + return $validity; + } + /** * Test WP_Customize_Manager::validate_setting_values(). * @@ -234,6 +278,23 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { $this->assertEquals( array( 'source' => 'filter_customize_validate_foo' ), $error->get_error_data() ); } + /** + * Test the WP_Customize_Manager::validate_setting_values() method to make sure that the validation and sanitization are done in the right order. + * + * @ticket 37247 + */ + function test_validate_setting_values_validation_sanitization_order() { + $setting = $this->manager->add_setting( 'numeric', array( + 'validate_callback' => array( $this, 'filter_customize_validate_numeric' ), + 'sanitize_callback' => array( $this, 'filter_customize_sanitize_numeric' ), + ) ); + $post_value = '42'; + $this->manager->set_post_value( 'numeric', $post_value ); + $validities = $this->manager->validate_setting_values( $this->manager->unsanitized_post_values() ); + $this->assertCount( 1, $validities ); + $this->assertEquals( array( 'numeric' => true ), $validities ); + } + /** * Test WP_Customize_Manager::prepare_setting_validity_for_js(). *