50 * @since 4.7.0 |
50 * @since 4.7.0 |
51 * |
51 * |
52 * @see register_rest_field() |
52 * @see register_rest_field() |
53 */ |
53 */ |
54 public function register_field() { |
54 public function register_field() { |
55 register_rest_field( $this->get_rest_field_type(), 'meta', array( |
55 register_rest_field( |
56 'get_callback' => array( $this, 'get_value' ), |
56 $this->get_rest_field_type(), |
57 'update_callback' => array( $this, 'update_value' ), |
57 'meta', |
58 'schema' => $this->get_field_schema(), |
58 array( |
59 )); |
59 'get_callback' => array( $this, 'get_value' ), |
|
60 'update_callback' => array( $this, 'update_value' ), |
|
61 'schema' => $this->get_field_schema(), |
|
62 ) |
|
63 ); |
60 } |
64 } |
61 |
65 |
62 /** |
66 /** |
63 * Retrieves the meta field value. |
67 * Retrieves the meta field value. |
64 * |
68 * |
71 public function get_value( $object_id, $request ) { |
75 public function get_value( $object_id, $request ) { |
72 $fields = $this->get_registered_fields(); |
76 $fields = $this->get_registered_fields(); |
73 $response = array(); |
77 $response = array(); |
74 |
78 |
75 foreach ( $fields as $meta_key => $args ) { |
79 foreach ( $fields as $meta_key => $args ) { |
76 $name = $args['name']; |
80 $name = $args['name']; |
77 $all_values = get_metadata( $this->get_meta_type(), $object_id, $meta_key, false ); |
81 $all_values = get_metadata( $this->get_meta_type(), $object_id, $meta_key, false ); |
78 if ( $args['single'] ) { |
82 if ( $args['single'] ) { |
79 if ( empty( $all_values ) ) { |
83 if ( empty( $all_values ) ) { |
80 $value = $args['schema']['default']; |
84 $value = $args['schema']['default']; |
81 } else { |
85 } else { |
183 if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) { |
187 if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) { |
184 return new WP_Error( |
188 return new WP_Error( |
185 'rest_cannot_delete', |
189 'rest_cannot_delete', |
186 /* translators: %s: custom field key */ |
190 /* translators: %s: custom field key */ |
187 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), |
191 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), |
188 array( 'key' => $name, 'status' => rest_authorization_required_code() ) |
192 array( |
|
193 'key' => $name, |
|
194 'status' => rest_authorization_required_code(), |
|
195 ) |
189 ); |
196 ); |
190 } |
197 } |
191 |
198 |
192 if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { |
199 if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { |
193 return new WP_Error( |
200 return new WP_Error( |
194 'rest_meta_database_error', |
201 'rest_meta_database_error', |
195 __( 'Could not delete meta value from database.' ), |
202 __( 'Could not delete meta value from database.' ), |
196 array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR ) |
203 array( |
|
204 'key' => $name, |
|
205 'status' => WP_Http::INTERNAL_SERVER_ERROR, |
|
206 ) |
197 ); |
207 ); |
198 } |
208 } |
199 |
209 |
200 return true; |
210 return true; |
201 } |
211 } |
218 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { |
228 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { |
219 return new WP_Error( |
229 return new WP_Error( |
220 'rest_cannot_update', |
230 'rest_cannot_update', |
221 /* translators: %s: custom field key */ |
231 /* translators: %s: custom field key */ |
222 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), |
232 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), |
223 array( 'key' => $name, 'status' => rest_authorization_required_code() ) |
233 array( |
|
234 'key' => $name, |
|
235 'status' => rest_authorization_required_code(), |
|
236 ) |
224 ); |
237 ); |
225 } |
238 } |
226 |
239 |
227 $current = get_metadata( $meta_type, $object_id, $meta_key, false ); |
240 $current = get_metadata( $meta_type, $object_id, $meta_key, false ); |
228 |
241 |
253 foreach ( $to_remove as $value ) { |
266 foreach ( $to_remove as $value ) { |
254 if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { |
267 if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { |
255 return new WP_Error( |
268 return new WP_Error( |
256 'rest_meta_database_error', |
269 'rest_meta_database_error', |
257 __( 'Could not update meta value in database.' ), |
270 __( 'Could not update meta value in database.' ), |
258 array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR ) |
271 array( |
|
272 'key' => $name, |
|
273 'status' => WP_Http::INTERNAL_SERVER_ERROR, |
|
274 ) |
259 ); |
275 ); |
260 } |
276 } |
261 } |
277 } |
262 |
278 |
263 foreach ( $to_add as $value ) { |
279 foreach ( $to_add as $value ) { |
264 if ( ! add_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { |
280 if ( ! add_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { |
265 return new WP_Error( |
281 return new WP_Error( |
266 'rest_meta_database_error', |
282 'rest_meta_database_error', |
267 __( 'Could not update meta value in database.' ), |
283 __( 'Could not update meta value in database.' ), |
268 array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR ) |
284 array( |
|
285 'key' => $name, |
|
286 'status' => WP_Http::INTERNAL_SERVER_ERROR, |
|
287 ) |
269 ); |
288 ); |
270 } |
289 } |
271 } |
290 } |
272 |
291 |
273 return true; |
292 return true; |
284 * @param mixed $value Updated value. |
303 * @param mixed $value Updated value. |
285 * @return bool|WP_Error True if the meta field was updated, WP_Error otherwise. |
304 * @return bool|WP_Error True if the meta field was updated, WP_Error otherwise. |
286 */ |
305 */ |
287 protected function update_meta_value( $object_id, $meta_key, $name, $value ) { |
306 protected function update_meta_value( $object_id, $meta_key, $name, $value ) { |
288 $meta_type = $this->get_meta_type(); |
307 $meta_type = $this->get_meta_type(); |
289 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { |
308 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { |
290 return new WP_Error( |
309 return new WP_Error( |
291 'rest_cannot_update', |
310 'rest_cannot_update', |
292 /* translators: %s: custom field key */ |
311 /* translators: %s: custom field key */ |
293 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), |
312 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), |
294 array( 'key' => $name, 'status' => rest_authorization_required_code() ) |
313 array( |
295 ); |
314 'key' => $name, |
296 } |
315 'status' => rest_authorization_required_code(), |
297 |
316 ) |
298 $meta_key = wp_slash( $meta_key ); |
317 ); |
299 $meta_value = wp_slash( $value ); |
318 } |
300 |
319 |
301 // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false. |
320 // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false. |
302 $old_value = get_metadata( $meta_type, $object_id, $meta_key ); |
321 $old_value = get_metadata( $meta_type, $object_id, $meta_key ); |
|
322 $subtype = get_object_subtype( $meta_type, $object_id ); |
303 |
323 |
304 if ( 1 === count( $old_value ) ) { |
324 if ( 1 === count( $old_value ) ) { |
305 if ( $old_value[0] === $meta_value ) { |
325 if ( (string) sanitize_meta( $meta_key, $value, $meta_type, $subtype ) === $old_value[0] ) { |
306 return true; |
326 return true; |
307 } |
327 } |
308 } |
328 } |
309 |
329 |
310 if ( ! update_metadata( $meta_type, $object_id, $meta_key, $meta_value ) ) { |
330 if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { |
311 return new WP_Error( |
331 return new WP_Error( |
312 'rest_meta_database_error', |
332 'rest_meta_database_error', |
313 __( 'Could not update meta value in database.' ), |
333 __( 'Could not update meta value in database.' ), |
314 array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR ) |
334 array( |
|
335 'key' => $name, |
|
336 'status' => WP_Http::INTERNAL_SERVER_ERROR, |
|
337 ) |
315 ); |
338 ); |
316 } |
339 } |
317 |
340 |
318 return true; |
341 return true; |
319 } |
342 } |
359 'type' => $default_args['type'], |
382 'type' => $default_args['type'], |
360 'description' => empty( $args['description'] ) ? '' : $args['description'], |
383 'description' => empty( $args['description'] ) ? '' : $args['description'], |
361 'default' => isset( $args['default'] ) ? $args['default'] : null, |
384 'default' => isset( $args['default'] ) ? $args['default'] : null, |
362 ); |
385 ); |
363 |
386 |
364 $rest_args = array_merge( $default_args, $rest_args ); |
387 $rest_args = array_merge( $default_args, $rest_args ); |
365 $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] ); |
388 $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] ); |
366 |
389 |
367 $type = ! empty( $rest_args['type'] ) ? $rest_args['type'] : null; |
390 $type = ! empty( $rest_args['type'] ) ? $rest_args['type'] : null; |
368 $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type; |
391 $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type; |
369 |
392 |