46 |
46 |
47 /** |
47 /** |
48 * Registers the meta field. |
48 * Registers the meta field. |
49 * |
49 * |
50 * @since 4.7.0 |
50 * @since 4.7.0 |
|
51 * @deprecated 5.6.0 |
51 * |
52 * |
52 * @see register_rest_field() |
53 * @see register_rest_field() |
53 */ |
54 */ |
54 public function register_field() { |
55 public function register_field() { |
|
56 _deprecated_function( __METHOD__, '5.6.0' ); |
|
57 |
55 register_rest_field( |
58 register_rest_field( |
56 $this->get_rest_field_type(), |
59 $this->get_rest_field_type(), |
57 'meta', |
60 'meta', |
58 array( |
61 array( |
59 'get_callback' => array( $this, 'get_value' ), |
62 'get_callback' => array( $this, 'get_value' ), |
89 |
92 |
90 $value = $this->prepare_value_for_response( $value, $request, $args ); |
93 $value = $this->prepare_value_for_response( $value, $request, $args ); |
91 } else { |
94 } else { |
92 $value = array(); |
95 $value = array(); |
93 |
96 |
94 foreach ( $all_values as $row ) { |
97 if ( is_array( $all_values ) ) { |
95 $value[] = $this->prepare_value_for_response( $row, $request, $args ); |
98 foreach ( $all_values as $row ) { |
|
99 $value[] = $this->prepare_value_for_response( $row, $request, $args ); |
|
100 } |
96 } |
101 } |
97 } |
102 } |
98 |
103 |
99 $response[ $name ] = $value; |
104 $response[ $name ] = $value; |
100 } |
105 } |
140 $name = $args['name']; |
145 $name = $args['name']; |
141 if ( ! array_key_exists( $name, $meta ) ) { |
146 if ( ! array_key_exists( $name, $meta ) ) { |
142 continue; |
147 continue; |
143 } |
148 } |
144 |
149 |
|
150 $value = $meta[ $name ]; |
|
151 |
145 /* |
152 /* |
146 * A null value means reset the field, which is essentially deleting it |
153 * A null value means reset the field, which is essentially deleting it |
147 * from the database and then relying on the default value. |
154 * from the database and then relying on the default value. |
|
155 * |
|
156 * Non-single meta can also be removed by passing an empty array. |
148 */ |
157 */ |
149 if ( is_null( $meta[ $name ] ) ) { |
158 if ( is_null( $value ) || ( array() === $value && ! $args['single'] ) ) { |
150 $args = $this->get_registered_fields()[ $meta_key ]; |
159 $args = $this->get_registered_fields()[ $meta_key ]; |
151 |
160 |
152 if ( $args['single'] ) { |
161 if ( $args['single'] ) { |
153 $current = get_metadata( $this->get_meta_type(), $object_id, $meta_key, true ); |
162 $current = get_metadata( $this->get_meta_type(), $object_id, $meta_key, true ); |
154 |
163 |
167 return $result; |
176 return $result; |
168 } |
177 } |
169 continue; |
178 continue; |
170 } |
179 } |
171 |
180 |
172 $value = $meta[ $name ]; |
|
173 |
|
174 if ( ! $args['single'] && is_array( $value ) && count( array_filter( $value, 'is_null' ) ) ) { |
181 if ( ! $args['single'] && is_array( $value ) && count( array_filter( $value, 'is_null' ) ) ) { |
175 return new WP_Error( |
182 return new WP_Error( |
176 'rest_invalid_stored_value', |
183 'rest_invalid_stored_value', |
177 /* translators: %s: Custom field key. */ |
184 /* translators: %s: Custom field key. */ |
178 sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), |
185 sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), |
208 * @since 4.7.0 |
215 * @since 4.7.0 |
209 * |
216 * |
210 * @param int $object_id Object ID the field belongs to. |
217 * @param int $object_id Object ID the field belongs to. |
211 * @param string $meta_key Key for the field. |
218 * @param string $meta_key Key for the field. |
212 * @param string $name Name for the field that is exposed in the REST API. |
219 * @param string $name Name for the field that is exposed in the REST API. |
213 * @return bool|WP_Error True if meta field is deleted, WP_Error otherwise. |
220 * @return true|WP_Error True if meta field is deleted, WP_Error otherwise. |
214 */ |
221 */ |
215 protected function delete_meta_value( $object_id, $meta_key, $name ) { |
222 protected function delete_meta_value( $object_id, $meta_key, $name ) { |
216 $meta_type = $this->get_meta_type(); |
223 $meta_type = $this->get_meta_type(); |
217 |
224 |
218 if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) { |
225 if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) { |
225 'status' => rest_authorization_required_code(), |
232 'status' => rest_authorization_required_code(), |
226 ) |
233 ) |
227 ); |
234 ); |
228 } |
235 } |
229 |
236 |
|
237 if ( null === get_metadata_raw( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { |
|
238 return true; |
|
239 } |
|
240 |
230 if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { |
241 if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { |
231 return new WP_Error( |
242 return new WP_Error( |
232 'rest_meta_database_error', |
243 'rest_meta_database_error', |
233 __( 'Could not delete meta value from database.' ), |
244 __( 'Could not delete meta value from database.' ), |
234 array( |
245 array( |
250 * |
261 * |
251 * @param int $object_id Object ID to update. |
262 * @param int $object_id Object ID to update. |
252 * @param string $meta_key Key for the custom field. |
263 * @param string $meta_key Key for the custom field. |
253 * @param string $name Name for the field that is exposed in the REST API. |
264 * @param string $name Name for the field that is exposed in the REST API. |
254 * @param array $values List of values to update to. |
265 * @param array $values List of values to update to. |
255 * @return bool|WP_Error True if meta fields are updated, WP_Error otherwise. |
266 * @return true|WP_Error True if meta fields are updated, WP_Error otherwise. |
256 */ |
267 */ |
257 protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) { |
268 protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) { |
258 $meta_type = $this->get_meta_type(); |
269 $meta_type = $this->get_meta_type(); |
259 |
270 |
260 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { |
271 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { |
269 ); |
280 ); |
270 } |
281 } |
271 |
282 |
272 $current_values = get_metadata( $meta_type, $object_id, $meta_key, false ); |
283 $current_values = get_metadata( $meta_type, $object_id, $meta_key, false ); |
273 $subtype = get_object_subtype( $meta_type, $object_id ); |
284 $subtype = get_object_subtype( $meta_type, $object_id ); |
|
285 |
|
286 if ( ! is_array( $current_values ) ) { |
|
287 $current_values = array(); |
|
288 } |
274 |
289 |
275 $to_remove = $current_values; |
290 $to_remove = $current_values; |
276 $to_add = $values; |
291 $to_add = $values; |
277 |
292 |
278 foreach ( $to_add as $add_key => $value ) { |
293 foreach ( $to_add as $add_key => $value ) { |
345 * |
360 * |
346 * @param int $object_id Object ID to update. |
361 * @param int $object_id Object ID to update. |
347 * @param string $meta_key Key for the custom field. |
362 * @param string $meta_key Key for the custom field. |
348 * @param string $name Name for the field that is exposed in the REST API. |
363 * @param string $name Name for the field that is exposed in the REST API. |
349 * @param mixed $value Updated value. |
364 * @param mixed $value Updated value. |
350 * @return bool|WP_Error True if the meta field was updated, WP_Error otherwise. |
365 * @return true|WP_Error True if the meta field was updated, WP_Error otherwise. |
351 */ |
366 */ |
352 protected function update_meta_value( $object_id, $meta_key, $name, $value ) { |
367 protected function update_meta_value( $object_id, $meta_key, $name, $value ) { |
353 $meta_type = $this->get_meta_type(); |
368 $meta_type = $this->get_meta_type(); |
354 |
369 |
355 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { |
370 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { |
366 |
381 |
367 // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false. |
382 // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false. |
368 $old_value = get_metadata( $meta_type, $object_id, $meta_key ); |
383 $old_value = get_metadata( $meta_type, $object_id, $meta_key ); |
369 $subtype = get_object_subtype( $meta_type, $object_id ); |
384 $subtype = get_object_subtype( $meta_type, $object_id ); |
370 |
385 |
371 if ( 1 === count( $old_value ) && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) ) { |
386 if ( is_array( $old_value ) && 1 === count( $old_value ) |
|
387 && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) |
|
388 ) { |
372 return true; |
389 return true; |
373 } |
390 } |
374 |
391 |
375 if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash_strings_only( $value ) ) ) { |
392 if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { |
376 return new WP_Error( |
393 return new WP_Error( |
377 'rest_meta_database_error', |
394 'rest_meta_database_error', |
378 /* translators: %s: Custom field key. */ |
395 /* translators: %s: Custom field key. */ |
379 sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), |
396 sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), |
380 array( |
397 array( |
461 |
478 |
462 if ( null === $rest_args['schema']['default'] ) { |
479 if ( null === $rest_args['schema']['default'] ) { |
463 $rest_args['schema']['default'] = static::get_empty_value_for_type( $type ); |
480 $rest_args['schema']['default'] = static::get_empty_value_for_type( $type ); |
464 } |
481 } |
465 |
482 |
466 $rest_args['schema'] = $this->default_additional_properties_to_false( $rest_args['schema'] ); |
483 $rest_args['schema'] = rest_default_additional_properties_to_false( $rest_args['schema'] ); |
467 |
484 |
468 if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { |
485 if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { |
469 continue; |
486 continue; |
470 } |
487 } |
471 |
488 |
566 * This is needed to restrict properties of objects in meta values to only |
583 * This is needed to restrict properties of objects in meta values to only |
567 * registered items, as the REST API will allow additional properties by |
584 * registered items, as the REST API will allow additional properties by |
568 * default. |
585 * default. |
569 * |
586 * |
570 * @since 5.3.0 |
587 * @since 5.3.0 |
|
588 * @deprecated 5.6.0 Use rest_default_additional_properties_to_false() instead. |
571 * |
589 * |
572 * @param array $schema The schema array. |
590 * @param array $schema The schema array. |
573 * @return array |
591 * @return array |
574 */ |
592 */ |
575 protected function default_additional_properties_to_false( $schema ) { |
593 protected function default_additional_properties_to_false( $schema ) { |
576 switch ( $schema['type'] ) { |
594 _deprecated_function( __METHOD__, '5.6.0', 'rest_default_additional_properties_to_false()' ); |
577 case 'object': |
595 |
578 foreach ( $schema['properties'] as $key => $child_schema ) { |
596 return rest_default_additional_properties_to_false( $schema ); |
579 $schema['properties'][ $key ] = $this->default_additional_properties_to_false( $child_schema ); |
|
580 } |
|
581 |
|
582 if ( ! isset( $schema['additionalProperties'] ) ) { |
|
583 $schema['additionalProperties'] = false; |
|
584 } |
|
585 break; |
|
586 case 'array': |
|
587 $schema['items'] = $this->default_additional_properties_to_false( $schema['items'] ); |
|
588 break; |
|
589 } |
|
590 |
|
591 return $schema; |
|
592 } |
597 } |
593 |
598 |
594 /** |
599 /** |
595 * Gets the empty value for a schema type. |
600 * Gets the empty value for a schema type. |
596 * |
601 * |