run:R W Run
895 By
2026-03-11 16:18:52
R W Run
18.08 KB
2026-03-11 16:18:52
R W Run
1.21 KB
2026-03-11 16:18:52
R W Run
1.21 KB
2026-03-11 16:18:52
R W Run
856 By
2026-03-11 16:18:52
R W Run
error_log
📄class-wp-rest-meta-fields.php
1<?php
2/**
3 * REST API: WP_REST_Meta_Fields class
4 *
5 * @package WordPress
6 * @subpackage REST_API
7 * @since 4.7.0
8 */
9
10/**
11 * Core class to manage meta values for an object via the REST API.
12 *
13 * @since 4.7.0
14 */
15#[AllowDynamicProperties]
16abstract class WP_REST_Meta_Fields {
17
18 /**
19 * Retrieves the object meta type.
20 *
21 * @since 4.7.0
22 *
23 * @return string One of 'post', 'comment', 'term', 'user', or anything
24 * else supported by `_get_meta_table()`.
25 */
26 abstract protected function get_meta_type();
27
28 /**
29 * Retrieves the object meta subtype.
30 *
31 * @since 4.9.8
32 *
33 * @return string Subtype for the meta type, or empty string if no specific subtype.
34 */
35 protected function get_meta_subtype() {
36 return '';
37 }
38
39 /**
40 * Retrieves the object type for register_rest_field().
41 *
42 * @since 4.7.0
43 *
44 * @return string The REST field type, such as post type name, taxonomy name, 'comment', or `user`.
45 */
46 abstract protected function get_rest_field_type();
47
48 /**
49 * Registers the meta field.
50 *
51 * @since 4.7.0
52 * @deprecated 5.6.0
53 *
54 * @see register_rest_field()
55 */
56 public function register_field() {
57 _deprecated_function( __METHOD__, '5.6.0' );
58
59 register_rest_field(
60 $this->get_rest_field_type(),
61 'meta',
62 array(
63 'get_callback' => array( $this, 'get_value' ),
64 'update_callback' => array( $this, 'update_value' ),
65 'schema' => $this->get_field_schema(),
66 )
67 );
68 }
69
70 /**
71 * Retrieves the meta field value.
72 *
73 * @since 4.7.0
74 *
75 * @param int $object_id Object ID to fetch meta for.
76 * @param WP_REST_Request $request Full details about the request.
77 * @return array Array containing the meta values keyed by name.
78 */
79 public function get_value( $object_id, $request ) {
80 $fields = $this->get_registered_fields();
81 $response = array();
82
83 foreach ( $fields as $meta_key => $args ) {
84 $name = $args['name'];
85 $all_values = get_metadata( $this->get_meta_type(), $object_id, $meta_key, false );
86
87 if ( $args['single'] ) {
88 if ( empty( $all_values ) ) {
89 $value = $args['schema']['default'];
90 } else {
91 $value = $all_values[0];
92 }
93
94 $value = $this->prepare_value_for_response( $value, $request, $args );
95 } else {
96 $value = array();
97
98 if ( is_array( $all_values ) ) {
99 foreach ( $all_values as $row ) {
100 $value[] = $this->prepare_value_for_response( $row, $request, $args );
101 }
102 }
103 }
104
105 $response[ $name ] = $value;
106 }
107
108 return $response;
109 }
110
111 /**
112 * Prepares a meta value for a response.
113 *
114 * This is required because some native types cannot be stored correctly
115 * in the database, such as booleans. We need to cast back to the relevant
116 * type before passing back to JSON.
117 *
118 * @since 4.7.0
119 *
120 * @param mixed $value Meta value to prepare.
121 * @param WP_REST_Request $request Current request object.
122 * @param array $args Options for the field.
123 * @return mixed Prepared value.
124 */
125 protected function prepare_value_for_response( $value, $request, $args ) {
126 if ( ! empty( $args['prepare_callback'] ) ) {
127 $value = call_user_func( $args['prepare_callback'], $value, $request, $args );
128 }
129
130 return $value;
131 }
132
133 /**
134 * Updates meta values.
135 *
136 * @since 4.7.0
137 *
138 * @param array $meta Array of meta parsed from the request.
139 * @param int $object_id Object ID to fetch meta for.
140 * @return null|WP_Error Null on success, WP_Error object on failure.
141 */
142 public function update_value( $meta, $object_id ) {
143 $fields = $this->get_registered_fields();
144 $error = new WP_Error();
145
146 foreach ( $fields as $meta_key => $args ) {
147 $name = $args['name'];
148 if ( ! array_key_exists( $name, $meta ) ) {
149 continue;
150 }
151
152 $value = $meta[ $name ];
153
154 /*
155 * A null value means reset the field, which is essentially deleting it
156 * from the database and then relying on the default value.
157 *
158 * Non-single meta can also be removed by passing an empty array.
159 */
160 if ( is_null( $value ) || ( array() === $value && ! $args['single'] ) ) {
161 $args = $this->get_registered_fields()[ $meta_key ];
162
163 if ( $args['single'] ) {
164 $current = get_metadata( $this->get_meta_type(), $object_id, $meta_key, true );
165
166 if ( is_wp_error( rest_validate_value_from_schema( $current, $args['schema'] ) ) ) {
167 $error->add(
168 'rest_invalid_stored_value',
169 /* translators: %s: Custom field key. */
170 sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ),
171 array( 'status' => 500 )
172 );
173 continue;
174 }
175 }
176
177 $result = $this->delete_meta_value( $object_id, $meta_key, $name );
178 if ( is_wp_error( $result ) ) {
179 $error->merge_from( $result );
180 }
181 continue;
182 }
183
184 if ( ! $args['single'] && is_array( $value ) && count( array_filter( $value, 'is_null' ) ) ) {
185 $error->add(
186 'rest_invalid_stored_value',
187 /* translators: %s: Custom field key. */
188 sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ),
189 array( 'status' => 500 )
190 );
191 continue;
192 }
193
194 $is_valid = rest_validate_value_from_schema( $value, $args['schema'], 'meta.' . $name );
195 if ( is_wp_error( $is_valid ) ) {
196 $is_valid->add_data( array( 'status' => 400 ) );
197 $error->merge_from( $is_valid );
198 continue;
199 }
200
201 $value = rest_sanitize_value_from_schema( $value, $args['schema'] );
202
203 if ( $args['single'] ) {
204 $result = $this->update_meta_value( $object_id, $meta_key, $name, $value );
205 } else {
206 $result = $this->update_multi_meta_value( $object_id, $meta_key, $name, $value );
207 }
208
209 if ( is_wp_error( $result ) ) {
210 $error->merge_from( $result );
211 continue;
212 }
213 }
214
215 if ( $error->has_errors() ) {
216 return $error;
217 }
218
219 return null;
220 }
221
222 /**
223 * Deletes a meta value for an object.
224 *
225 * @since 4.7.0
226 *
227 * @param int $object_id Object ID the field belongs to.
228 * @param string $meta_key Key for the field.
229 * @param string $name Name for the field that is exposed in the REST API.
230 * @return true|WP_Error True if meta field is deleted, WP_Error otherwise.
231 */
232 protected function delete_meta_value( $object_id, $meta_key, $name ) {
233 $meta_type = $this->get_meta_type();
234
235 if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) {
236 return new WP_Error(
237 'rest_cannot_delete',
238 /* translators: %s: Custom field key. */
239 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ),
240 array(
241 'key' => $name,
242 'status' => rest_authorization_required_code(),
243 )
244 );
245 }
246
247 if ( null === get_metadata_raw( $meta_type, $object_id, wp_slash( $meta_key ) ) ) {
248 return true;
249 }
250
251 if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) {
252 return new WP_Error(
253 'rest_meta_database_error',
254 __( 'Could not delete meta value from database.' ),
255 array(
256 'key' => $name,
257 'status' => WP_Http::INTERNAL_SERVER_ERROR,
258 )
259 );
260 }
261
262 return true;
263 }
264
265 /**
266 * Updates multiple meta values for an object.
267 *
268 * Alters the list of values in the database to match the list of provided values.
269 *
270 * @since 4.7.0
271 * @since 6.7.0 Stores values into DB even if provided registered default value.
272 *
273 * @param int $object_id Object ID to update.
274 * @param string $meta_key Key for the custom field.
275 * @param string $name Name for the field that is exposed in the REST API.
276 * @param array $values List of values to update to.
277 * @return true|WP_Error True if meta fields are updated, WP_Error otherwise.
278 */
279 protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) {
280 $meta_type = $this->get_meta_type();
281
282 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) {
283 return new WP_Error(
284 'rest_cannot_update',
285 /* translators: %s: Custom field key. */
286 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ),
287 array(
288 'key' => $name,
289 'status' => rest_authorization_required_code(),
290 )
291 );
292 }
293
294 $current_values = get_metadata_raw( $meta_type, $object_id, $meta_key, false );
295 $subtype = get_object_subtype( $meta_type, $object_id );
296
297 if ( ! is_array( $current_values ) ) {
298 $current_values = array();
299 }
300
301 $to_remove = $current_values;
302 $to_add = $values;
303
304 foreach ( $to_add as $add_key => $value ) {
305 $remove_keys = array_keys(
306 array_filter(
307 $current_values,
308 function ( $stored_value ) use ( $meta_key, $subtype, $value ) {
309 return $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $stored_value, $value );
310 }
311 )
312 );
313
314 if ( empty( $remove_keys ) ) {
315 continue;
316 }
317
318 if ( count( $remove_keys ) > 1 ) {
319 // To remove, we need to remove first, then add, so don't touch.
320 continue;
321 }
322
323 $remove_key = $remove_keys[0];
324
325 unset( $to_remove[ $remove_key ] );
326 unset( $to_add[ $add_key ] );
327 }
328
329 /*
330 * `delete_metadata` removes _all_ instances of the value, so only call once. Otherwise,
331 * `delete_metadata` will return false for subsequent calls of the same value.
332 * Use serialization to produce a predictable string that can be used by array_unique.
333 */
334 $to_remove = array_map( 'maybe_unserialize', array_unique( array_map( 'maybe_serialize', $to_remove ) ) );
335
336 foreach ( $to_remove as $value ) {
337 if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) {
338 return new WP_Error(
339 'rest_meta_database_error',
340 /* translators: %s: Custom field key. */
341 sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ),
342 array(
343 'key' => $name,
344 'status' => WP_Http::INTERNAL_SERVER_ERROR,
345 )
346 );
347 }
348 }
349
350 foreach ( $to_add as $value ) {
351 if ( ! add_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) {
352 return new WP_Error(
353 'rest_meta_database_error',
354 /* translators: %s: Custom field key. */
355 sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ),
356 array(
357 'key' => $name,
358 'status' => WP_Http::INTERNAL_SERVER_ERROR,
359 )
360 );
361 }
362 }
363
364 return true;
365 }
366
367 /**
368 * Updates a meta value for an object.
369 *
370 * @since 4.7.0
371 * @since 6.7.0 Stores values into DB even if provided registered default value.
372 *
373 * @param int $object_id Object ID to update.
374 * @param string $meta_key Key for the custom field.
375 * @param string $name Name for the field that is exposed in the REST API.
376 * @param mixed $value Updated value.
377 * @return true|WP_Error True if the meta field was updated, WP_Error otherwise.
378 */
379 protected function update_meta_value( $object_id, $meta_key, $name, $value ) {
380 $meta_type = $this->get_meta_type();
381
382 // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false.
383 $old_value = get_metadata_raw( $meta_type, $object_id, $meta_key );
384 $subtype = get_object_subtype( $meta_type, $object_id );
385
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 ) {
389 return true;
390 }
391
392 if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) {
393 return new WP_Error(
394 'rest_cannot_update',
395 /* translators: %s: Custom field key. */
396 sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ),
397 array(
398 'key' => $name,
399 'status' => rest_authorization_required_code(),
400 )
401 );
402 }
403
404 if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) {
405 return new WP_Error(
406 'rest_meta_database_error',
407 /* translators: %s: Custom field key. */
408 sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ),
409 array(
410 'key' => $name,
411 'status' => WP_Http::INTERNAL_SERVER_ERROR,
412 )
413 );
414 }
415
416 return true;
417 }
418
419 /**
420 * Checks if the user provided value is equivalent to a stored value for the given meta key.
421 *
422 * @since 5.5.0
423 *
424 * @param string $meta_key The meta key being checked.
425 * @param string $subtype The object subtype.
426 * @param mixed $stored_value The currently stored value retrieved from get_metadata().
427 * @param mixed $user_value The value provided by the user.
428 * @return bool
429 */
430 protected function is_meta_value_same_as_stored_value( $meta_key, $subtype, $stored_value, $user_value ) {
431 $args = $this->get_registered_fields()[ $meta_key ];
432 $sanitized = sanitize_meta( $meta_key, $user_value, $this->get_meta_type(), $subtype );
433
434 if ( in_array( $args['type'], array( 'string', 'number', 'integer', 'boolean' ), true ) ) {
435 // The return value of get_metadata will always be a string for scalar types.
436 $sanitized = (string) $sanitized;
437 }
438
439 return $sanitized === $stored_value;
440 }
441
442 /**
443 * Retrieves all the registered meta fields.
444 *
445 * @since 4.7.0
446 *
447 * @return array Registered fields.
448 */
449 protected function get_registered_fields() {
450 $registered = array();
451
452 $meta_type = $this->get_meta_type();
453 $meta_subtype = $this->get_meta_subtype();
454
455 $meta_keys = get_registered_meta_keys( $meta_type );
456 if ( ! empty( $meta_subtype ) ) {
457 $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( $meta_type, $meta_subtype ) );
458 }
459
460 foreach ( $meta_keys as $name => $args ) {
461 if ( empty( $args['show_in_rest'] ) ) {
462 continue;
463 }
464
465 $rest_args = array();
466
467 if ( is_array( $args['show_in_rest'] ) ) {
468 $rest_args = $args['show_in_rest'];
469 }
470
471 $default_args = array(
472 'name' => $name,
473 'single' => $args['single'],
474 'type' => ! empty( $args['type'] ) ? $args['type'] : null,
475 'schema' => array(),
476 'prepare_callback' => array( $this, 'prepare_value' ),
477 );
478
479 $default_schema = array(
480 'type' => $default_args['type'],
481 'title' => empty( $args['label'] ) ? '' : $args['label'],
482 'description' => empty( $args['description'] ) ? '' : $args['description'],
483 'default' => isset( $args['default'] ) ? $args['default'] : null,
484 );
485
486 $rest_args = array_merge( $default_args, $rest_args );
487 $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] );
488
489 $type = ! empty( $rest_args['type'] ) ? $rest_args['type'] : null;
490 $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type;
491
492 if ( null === $rest_args['schema']['default'] ) {
493 $rest_args['schema']['default'] = static::get_empty_value_for_type( $type );
494 }
495
496 $rest_args['schema'] = rest_default_additional_properties_to_false( $rest_args['schema'] );
497
498 if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) {
499 continue;
500 }
501
502 if ( empty( $rest_args['single'] ) ) {
503 $rest_args['schema'] = array(
504 'type' => 'array',
505 'items' => $rest_args['schema'],
506 );
507 }
508
509 $registered[ $name ] = $rest_args;
510 }
511
512 return $registered;
513 }
514
515 /**
516 * Retrieves the object's meta schema, conforming to JSON Schema.
517 *
518 * @since 4.7.0
519 *
520 * @return array Field schema data.
521 */
522 public function get_field_schema() {
523 $fields = $this->get_registered_fields();
524
525 $schema = array(
526 'description' => __( 'Meta fields.' ),
527 'type' => 'object',
528 'context' => array( 'view', 'edit' ),
529 'properties' => array(),
530 'arg_options' => array(
531 'sanitize_callback' => null,
532 'validate_callback' => array( $this, 'check_meta_is_array' ),
533 ),
534 );
535
536 foreach ( $fields as $args ) {
537 $schema['properties'][ $args['name'] ] = $args['schema'];
538 }
539
540 return $schema;
541 }
542
543 /**
544 * Prepares a meta value for output.
545 *
546 * Default preparation for meta fields. Override by passing the
547 * `prepare_callback` in your `show_in_rest` options.
548 *
549 * @since 4.7.0
550 *
551 * @param mixed $value Meta value from the database.
552 * @param WP_REST_Request $request Request object.
553 * @param array $args REST-specific options for the meta key.
554 * @return mixed Value prepared for output. If a non-JsonSerializable object, null.
555 */
556 public static function prepare_value( $value, $request, $args ) {
557 if ( $args['single'] ) {
558 $schema = $args['schema'];
559 } else {
560 $schema = $args['schema']['items'];
561 }
562
563 if ( '' === $value && in_array( $schema['type'], array( 'boolean', 'integer', 'number' ), true ) ) {
564 $value = static::get_empty_value_for_type( $schema['type'] );
565 }
566
567 if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) {
568 return null;
569 }
570
571 return rest_sanitize_value_from_schema( $value, $schema );
572 }
573
574 /**
575 * Check the 'meta' value of a request is an associative array.
576 *
577 * @since 4.7.0
578 *
579 * @param mixed $value The meta value submitted in the request.
580 * @param WP_REST_Request $request Full details about the request.
581 * @param string $param The parameter name.
582 * @return array|false The meta array, if valid, false otherwise.
583 */
584 public function check_meta_is_array( $value, $request, $param ) {
585 if ( ! is_array( $value ) ) {
586 return false;
587 }
588
589 return $value;
590 }
591
592 /**
593 * Recursively add additionalProperties = false to all objects in a schema if no additionalProperties setting
594 * is specified.
595 *
596 * This is needed to restrict properties of objects in meta values to only
597 * registered items, as the REST API will allow additional properties by
598 * default.
599 *
600 * @since 5.3.0
601 * @deprecated 5.6.0 Use rest_default_additional_properties_to_false() instead.
602 *
603 * @param array $schema The schema array.
604 * @return array
605 */
606 protected function default_additional_properties_to_false( $schema ) {
607 _deprecated_function( __METHOD__, '5.6.0', 'rest_default_additional_properties_to_false()' );
608
609 return rest_default_additional_properties_to_false( $schema );
610 }
611
612 /**
613 * Gets the empty value for a schema type.
614 *
615 * @since 5.3.0
616 *
617 * @param string $type The schema type.
618 * @return mixed
619 */
620 protected static function get_empty_value_for_type( $type ) {
621 switch ( $type ) {
622 case 'string':
623 return '';
624 case 'boolean':
625 return false;
626 case 'integer':
627 return 0;
628 case 'number':
629 return 0.0;
630 case 'array':
631 case 'object':
632 return array();
633 default:
634 return null;
635 }
636 }
637}
638
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1