| | 52 | 'permission_callback' => array( $this, 'get_items_permissions_check' ), |
| | 53 | ), |
| | 54 | 'schema' => array( $this, 'get_public_item_schema' ), |
| | 55 | ) |
| | 56 | ); |
| | 57 | |
| | 58 | register_rest_route( |
| | 59 | $this->namespace, |
| | 60 | '/' . $this->rest_base . '/(?P<option>.+)', |
| | 61 | array( |
| | 62 | 'args' => array( |
| | 63 | 'id' => array( |
| | 64 | 'description' => __( 'The option to fetch.' ), |
| | 65 | 'type' => 'string', |
| | 66 | ), |
| | 67 | ), |
| | 68 | array( |
| | 69 | 'methods' => WP_REST_Server::READABLE, |
| | 70 | 'callback' => array( $this, 'get_item' ), |
| | 126 | * Filters the value of a setting recognized by the REST API. |
| | 127 | * |
| | 128 | * Allow hijacking the setting value and overriding the built-in behavior by returning a |
| | 129 | * non-null value. The returned value will be presented as the setting value instead. |
| | 130 | * |
| | 131 | * @since 4.7.0 |
| | 132 | * |
| | 133 | * @param mixed $result Value to use for the requested setting. Can be a scalar |
| | 134 | * matching the registered schema for the setting, or null to |
| | 135 | * follow the default get_option() behavior. |
| | 136 | * @param string $name Setting name (as shown in REST API responses). |
| | 137 | * @param array $args Arguments passed to register_setting() for this setting. |
| | 138 | */ |
| | 139 | private function get_filtered_setting( $name, $args ) { |
| | 140 | $response = apply_filters( 'rest_pre_get_setting', null, $name, $args ); |
| | 141 | |
| | 142 | if ( is_null( $response) ) { |
| | 143 | // Default to a null value as "null" in the response means "not set". |
| | 144 | $response = get_option( $args['option_name'], $args['schema']['default'] ); |
| | 145 | } |
| | 146 | |
| | 147 | /* |
| | 148 | * Because get_option() is lossy, we have to |
| | 149 | * cast values to the type they are registered with. |
| | 150 | */ |
| | 151 | return $this->prepare_value( $response, $args['schema'] ); |
| | 152 | } |
| | 153 | |
| | 154 | /** |
| 85 | | /** |
| 86 | | * Filters the value of a setting recognized by the REST API. |
| 87 | | * |
| 88 | | * Allow hijacking the setting value and overriding the built-in behavior by returning a |
| 89 | | * non-null value. The returned value will be presented as the setting value instead. |
| 90 | | * |
| 91 | | * @since 4.7.0 |
| 92 | | * |
| 93 | | * @param mixed $result Value to use for the requested setting. Can be a scalar |
| 94 | | * matching the registered schema for the setting, or null to |
| 95 | | * follow the default get_option() behavior. |
| 96 | | * @param string $name Setting name (as shown in REST API responses). |
| 97 | | * @param array $args Arguments passed to register_setting() for this setting. |
| 98 | | */ |
| 99 | | $response[ $name ] = apply_filters( 'rest_pre_get_setting', null, $name, $args ); |
| 100 | | |
| 101 | | if ( is_null( $response[ $name ] ) ) { |
| 102 | | // Default to a null value as "null" in the response means "not set". |
| 103 | | $response[ $name ] = get_option( $args['option_name'], $args['schema']['default'] ); |
| 104 | | } |
| 105 | | |
| 106 | | /* |
| 107 | | * Because get_option() is lossy, we have to |
| 108 | | * cast values to the type they are registered with. |
| 109 | | */ |
| 110 | | $response[ $name ] = $this->prepare_value( $response[ $name ], $args['schema'] ); |
| | 167 | $response[ $name ] = $this->get_filtered_setting( $name, $args ); |
| | 195 | * Filters whether to preempt a setting value update. |
| | 196 | * |
| | 197 | * Allows hijacking the setting update logic and overriding the built-in behavior by |
| | 198 | * returning true. |
| | 199 | * |
| | 200 | * @since 4.7.0 |
| | 201 | * |
| | 202 | * @param bool $result Whether to override the default behavior for updating the |
| | 203 | * value of a setting. |
| | 204 | * @param string $name Setting name (as shown in REST API responses). |
| | 205 | * @param mixed $value Updated setting value. |
| | 206 | * @param array $args Arguments passed to register_setting() for this setting. |
| | 207 | */ |
| | 208 | private function filtered_update_option( $name, $value, $args ) { |
| | 209 | $updated = apply_filters( 'rest_pre_update_setting', false, $name, $value, $args ); |
| | 210 | |
| | 211 | if ( $updated ) { |
| | 212 | return; |
| | 213 | } |
| | 214 | |
| | 215 | /* |
| | 216 | * A null value for an option would have the same effect as |
| | 217 | * deleting the option from the database, and relying on the |
| | 218 | * default value. |
| | 219 | */ |
| | 220 | if ( is_null( $value ) ) { |
| | 221 | /* |
| | 222 | * A null value is returned in the response for any option |
| | 223 | * that has a non-scalar value. |
| | 224 | * |
| | 225 | * To protect clients from accidentally including the null |
| | 226 | * values from a response object in a request, we do not allow |
| | 227 | * options with values that don't pass validation to be updated to null. |
| | 228 | * Without this added protection a client could mistakenly |
| | 229 | * delete all options that have invalid values from the |
| | 230 | * database. |
| | 231 | */ |
| | 232 | if ( is_wp_error( rest_validate_value_from_schema( get_option( $args['option_name'], false ), $args['schema'] ) ) ) { |
| | 233 | return new WP_Error( |
| | 234 | 'rest_invalid_stored_value', |
| | 235 | /* translators: %s: Property name. */ |
| | 236 | sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), |
| | 237 | array( 'status' => 500 ) |
| | 238 | ); |
| | 239 | } |
| | 240 | |
| | 241 | delete_option( $args['option_name'] ); |
| | 242 | } else { |
| | 243 | update_option( $args['option_name'], $value ); |
| | 244 | } |
| | 245 | } |
| | 246 | |
| | 247 | /** |
| 155 | | /** |
| 156 | | * Filters whether to preempt a setting value update. |
| 157 | | * |
| 158 | | * Allows hijacking the setting update logic and overriding the built-in behavior by |
| 159 | | * returning true. |
| 160 | | * |
| 161 | | * @since 4.7.0 |
| 162 | | * |
| 163 | | * @param bool $result Whether to override the default behavior for updating the |
| 164 | | * value of a setting. |
| 165 | | * @param string $name Setting name (as shown in REST API responses). |
| 166 | | * @param mixed $value Updated setting value. |
| 167 | | * @param array $args Arguments passed to register_setting() for this setting. |
| 168 | | */ |
| 169 | | $updated = apply_filters( 'rest_pre_update_setting', false, $name, $request[ $name ], $args ); |
| 170 | | |
| 171 | | if ( $updated ) { |
| 172 | | continue; |
| 173 | | } |
| 174 | | |
| 175 | | /* |
| 176 | | * A null value for an option would have the same effect as |
| 177 | | * deleting the option from the database, and relying on the |
| 178 | | * default value. |
| 179 | | */ |
| 180 | | if ( is_null( $request[ $name ] ) ) { |
| 181 | | /* |
| 182 | | * A null value is returned in the response for any option |
| 183 | | * that has a non-scalar value. |
| 184 | | * |
| 185 | | * To protect clients from accidentally including the null |
| 186 | | * values from a response object in a request, we do not allow |
| 187 | | * options with values that don't pass validation to be updated to null. |
| 188 | | * Without this added protection a client could mistakenly |
| 189 | | * delete all options that have invalid values from the |
| 190 | | * database. |
| 191 | | */ |
| 192 | | if ( is_wp_error( rest_validate_value_from_schema( get_option( $args['option_name'], false ), $args['schema'] ) ) ) { |
| 193 | | return new WP_Error( |
| 194 | | 'rest_invalid_stored_value', |
| 195 | | /* translators: %s: Property name. */ |
| 196 | | sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), |
| 197 | | array( 'status' => 500 ) |
| 198 | | ); |
| 199 | | } |
| 200 | | |
| 201 | | delete_option( $args['option_name'] ); |
| 202 | | } else { |
| 203 | | update_option( $args['option_name'], $request[ $name ] ); |
| 204 | | } |
| | 265 | $this->filtered_update_option( $name, $request[ $name ], $args ); |
| | 409 | |
| | 410 | /** |
| | 411 | * Retrieves a single option |
| | 412 | * |
| | 413 | * @since ? |
| | 414 | * |
| | 415 | * @param WP_REST_Request $request Full details about the request. |
| | 416 | * @return array|WP_Error Array on success, or WP_Error object on failure. |
| | 417 | */ |
| | 418 | public function get_item( $request ) { |
| | 419 | $name = $request['option']; |
| | 420 | $options = $this->get_registered_options(); |
| | 421 | if ( ! isset( $options[ $name ] ) ) { |
| | 422 | return new WP_Error( |
| | 423 | 'rest_invalid_setting', |
| | 424 | /* translators: %s: Settings name. */ |
| | 425 | sprintf( __( '%s is not a registered setting.' ), $name ), |
| | 426 | array( 'status' => 500 ) |
| | 427 | ); |
| | 428 | } |
| | 429 | |
| | 430 | $response = array(); |
| | 431 | $response[ $name ] = $this->get_filtered_setting( $name, $options[ $name ] ); |
| | 432 | return $response; |
| | 433 | } |
| | 434 | |
| | 435 | /** |
| | 436 | * Updates a given setting |
| | 437 | * |
| | 438 | * @since 4.7.0 |
| | 439 | * |
| | 440 | * @param WP_REST_Request $request Full details about the request. |
| | 441 | * @return array|WP_Error Array on success, or error object on failure. |
| | 442 | */ |
| | 443 | public function update_item( $request ) { |
| | 444 | $name = $request['option']; |
| | 445 | $options = $this->get_registered_options(); |
| | 446 | |
| | 447 | $params = $request->get_params(); |
| | 448 | |
| | 449 | if ( ! array_key_exists( $name, $params ) ) { |
| | 450 | return new WP_Error( |
| | 451 | 'rest_invalid_setting', |
| | 452 | /* translators: %s: Settings name. */ |
| | 453 | sprintf( __( '%s is not a registered setting.' ), $name ), |
| | 454 | array( 'status' => 500 ) |
| | 455 | ); |
| | 456 | } |
| | 457 | |
| | 458 | $this->filtered_update_option( $name, $request[ $name ], $args ); |
| | 459 | |
| | 460 | return $this->get_items( $request ); |
| | 461 | } |