diff --git src/wp-admin/options.php src/wp-admin/options.php
index 9705134174..d040f376f9 100644
|
|
if ( 'update' == $action ) { |
220 | 220 | } |
221 | 221 | $value = wp_unslash( $value ); |
222 | 222 | } |
223 | | update_option( $option, $value ); |
| 223 | |
| 224 | $validity = validate_option( $option, $value ); |
| 225 | |
| 226 | if ( is_wp_error( $validity ) ) { |
| 227 | foreach ( $validity->errors as $code => $messages ) { |
| 228 | foreach ( $messages as $message ) { |
| 229 | add_settings_error( $option, $code, $message ); |
| 230 | } |
| 231 | } |
| 232 | } else { |
| 233 | update_option( $option, $value ); |
| 234 | } |
224 | 235 | } |
225 | 236 | |
226 | 237 | /* |
diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php
index 6d793d15db..3d6eb225d7 100644
|
|
final class WP_Customize_Manager { |
2300 | 2300 | $validity = $setting->validate( $unsanitized_value ); |
2301 | 2301 | } |
2302 | 2302 | if ( ! is_wp_error( $validity ) ) { |
| 2303 | // Use the regular option validation if the Customize setting is an option. |
| 2304 | $validity = new WP_Error(); |
| 2305 | |
| 2306 | if ( 'option' === $setting->type ) { |
| 2307 | $option_validity = validate_option( $setting->id, $value ); |
| 2308 | if ( is_wp_error( $option_validity ) ) { |
| 2309 | $validity = $option_validity; |
| 2310 | } |
| 2311 | } |
| 2312 | |
2303 | 2313 | /** This filter is documented in wp-includes/class-wp-customize-setting.php */ |
2304 | | $late_validity = apply_filters( "customize_validate_{$setting->id}", new WP_Error(), $unsanitized_value, $setting ); |
| 2314 | $late_validity = apply_filters( "customize_validate_{$setting->id}", $validity, $unsanitized_value, $setting ); |
2305 | 2315 | if ( ! empty( $late_validity->errors ) ) { |
2306 | 2316 | $validity = $late_validity; |
2307 | 2317 | } |
diff --git src/wp-includes/class-wp-customize-setting.php src/wp-includes/class-wp-customize-setting.php
index ae768fece7..2dc023f168 100644
|
|
class WP_Customize_Setting { |
580 | 580 | |
581 | 581 | $validity = new WP_Error(); |
582 | 582 | |
| 583 | // Use the regular option validation if the Customize setting is an option. |
| 584 | if ( 'option' === $this->type ) { |
| 585 | $option_validity = validate_option( $this->id, $value ); |
| 586 | if ( is_wp_error( $option_validity ) ) { |
| 587 | $validity = $option_validity; |
| 588 | } |
| 589 | } |
| 590 | |
583 | 591 | /** |
584 | 592 | * Validates a Customize setting value. |
585 | 593 | * |
diff --git src/wp-includes/formatting.php src/wp-includes/formatting.php
index 8648287f81..f599b53a5b 100644
|
|
function wp_make_link_relative( $link ) { |
4313 | 4313 | return preg_replace( '|^(https?:)?//[^/]+(/?.*)|i', '$2', $link ); |
4314 | 4314 | } |
4315 | 4315 | |
| 4316 | /** |
| 4317 | * Validates an option value based on the nature of the option. |
| 4318 | * |
| 4319 | * The {@see 'validate_option_$option'} filter should be used to add errors |
| 4320 | * to the `WP_Error` object passed-through. |
| 4321 | * |
| 4322 | * @since 5.0.0 |
| 4323 | * |
| 4324 | * @param string $option The name of the option. |
| 4325 | * @param string $value The unsanitized value. |
| 4326 | * @return true|WP_Error True if the input was validated, otherwise WP_Error. |
| 4327 | */ |
| 4328 | function validate_option( $option, $value ) { |
| 4329 | $validity = new WP_Error(); |
| 4330 | |
| 4331 | /** |
| 4332 | * Validates an option value. |
| 4333 | * |
| 4334 | * Plugins should amend the `$validity` object via its `WP_Error::add()` method. |
| 4335 | * |
| 4336 | * The dynamic portion of the hook name, `$option`, refers to the option name. |
| 4337 | * |
| 4338 | * @since 5.0.0 |
| 4339 | * |
| 4340 | * @param WP_Error $validity Filtered from `true` to `WP_Error` when invalid. |
| 4341 | * @param mixed $value The option value. |
| 4342 | */ |
| 4343 | $validity = apply_filters( "validate_option_{$option}", $validity, $value ); |
| 4344 | |
| 4345 | if ( is_wp_error( $validity ) && empty( $validity->errors ) ) { |
| 4346 | $validity = true; |
| 4347 | } |
| 4348 | |
| 4349 | return $validity; |
| 4350 | } |
| 4351 | |
4316 | 4352 | /** |
4317 | 4353 | * Sanitises various option values based on the nature of the option. |
4318 | 4354 | * |
diff --git src/wp-includes/option.php src/wp-includes/option.php
index f52b7efee7..21c18150e2 100644
|
|
function register_initial_settings() { |
2032 | 2032 | * |
2033 | 2033 | * @since 2.7.0 |
2034 | 2034 | * @since 4.7.0 `$args` can be passed to set flags on the setting, similar to `register_meta()`. |
| 2035 | * @since 5.0.0 Introduced the `$validate_callback` argument. |
2035 | 2036 | * |
2036 | 2037 | * @global array $new_whitelist_options |
2037 | 2038 | * @global array $wp_registered_settings |
… |
… |
function register_initial_settings() { |
2045 | 2046 | * @type string $type The type of data associated with this setting. |
2046 | 2047 | * Valid values are 'string', 'boolean', 'integer', and 'number'. |
2047 | 2048 | * @type string $description A description of the data attached to this setting. |
| 2049 | * @type callable $validate_callback A callback that checks validity of the option's value. |
2048 | 2050 | * @type callable $sanitize_callback A callback function that sanitizes the option's value. |
2049 | 2051 | * @type bool $show_in_rest Whether data associated with this setting should be included in the REST API. |
2050 | 2052 | * @type mixed $default Default value when calling `get_option()`. |
… |
… |
function register_setting( $option_group, $option_name, $args = array() ) { |
2057 | 2059 | 'type' => 'string', |
2058 | 2060 | 'group' => $option_group, |
2059 | 2061 | 'description' => '', |
| 2062 | 'validate_callback' => null, |
2060 | 2063 | 'sanitize_callback' => null, |
2061 | 2064 | 'show_in_rest' => false, |
2062 | 2065 | ); |
… |
… |
function register_setting( $option_group, $option_name, $args = array() ) { |
2110 | 2113 | } |
2111 | 2114 | |
2112 | 2115 | $new_whitelist_options[ $option_group ][] = $option_name; |
| 2116 | if ( ! empty( $args['validate_callback'] ) ) { |
| 2117 | add_filter( "validate_option_{$option_name}", $args['validate_callback'], 10, 3 ); |
| 2118 | } |
2113 | 2119 | if ( ! empty( $args['sanitize_callback'] ) ) { |
2114 | 2120 | add_filter( "sanitize_option_{$option_name}", $args['sanitize_callback'] ); |
2115 | 2121 | } |
… |
… |
function unregister_setting( $option_group, $option_name, $deprecated = '' ) { |
2177 | 2183 | } |
2178 | 2184 | |
2179 | 2185 | if ( isset( $wp_registered_settings[ $option_name ] ) ) { |
| 2186 | // Remove the validate callback if one was set during registration. |
| 2187 | if ( ! empty( $wp_registered_settings[ $option_name ]['validate_callback'] ) ) { |
| 2188 | remove_filter( "validate_option_{$option_name}", $wp_registered_settings[ $option_name ]['validate_callback'], 10 ); |
| 2189 | } |
| 2190 | |
2180 | 2191 | // Remove the sanitize callback if one was set during registration. |
2181 | 2192 | if ( ! empty( $wp_registered_settings[ $option_name ]['sanitize_callback'] ) ) { |
2182 | 2193 | remove_filter( "sanitize_option_{$option_name}", $wp_registered_settings[ $option_name ]['sanitize_callback'] ); |
diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php
index 1a38261a08..4c3a6d8bfd 100644
|
|
class WP_REST_Settings_Controller extends WP_REST_Controller { |
193 | 193 | |
194 | 194 | delete_option( $args['option_name'] ); |
195 | 195 | } else { |
| 196 | $validity = validate_option( $args['option_name'], $request[ $name ] ); |
| 197 | if ( is_wp_error( $validity ) ) { |
| 198 | foreach ( $validity->errors as $code => $messages ) { |
| 199 | $validity->add_data( array( 'status' => 400 ), $code ); |
| 200 | } |
| 201 | |
| 202 | return $validity; |
| 203 | } |
| 204 | |
196 | 205 | update_option( $args['option_name'], $request[ $name ] ); |
197 | 206 | } |
198 | 207 | } |