[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> meta.php (source)

   1  <?php
   2  /**
   3   * Core Metadata API
   4   *
   5   * Functions for retrieving and manipulating metadata of various WordPress object types. Metadata
   6   * for an object is a represented by a simple key-value pair. Objects may contain multiple
   7   * metadata entries that share the same key and differ only in their value.
   8   *
   9   * @package WordPress
  10   * @subpackage Meta
  11   */
  12  
  13  require  ABSPATH . WPINC . '/class-wp-metadata-lazyloader.php';
  14  
  15  /**
  16   * Adds metadata for the specified object.
  17   *
  18   * @since 2.9.0
  19   *
  20   * @global wpdb $wpdb WordPress database abstraction object.
  21   *
  22   * @param string $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
  23   *                           or any other object type with an associated meta table.
  24   * @param int    $object_id  ID of the object metadata is for.
  25   * @param string $meta_key   Metadata key.
  26   * @param mixed  $meta_value Metadata value. Arrays and objects are stored as serialized data and
  27   *                           will be returned as the same type when retrieved. Other data types will
  28   *                           be stored as strings in the database:
  29   *                           - false is stored and retrieved as an empty string ('')
  30   *                           - true is stored and retrieved as '1'
  31   *                           - numbers (both integer and float) are stored and retrieved as strings
  32   *                           Must be serializable if non-scalar.
  33   * @param bool   $unique     Optional. Whether the specified metadata key should be unique for the object.
  34   *                           If true, and the object already has a value for the specified metadata key,
  35   *                           no change will be made. Default false.
  36   * @return int|false The meta ID on success, false on failure.
  37   */
  38  function add_metadata( $meta_type, $object_id, $meta_key, $meta_value, $unique = false ) {
  39      global $wpdb;
  40  
  41      if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
  42          return false;
  43      }
  44  
  45      $object_id = absint( $object_id );
  46      if ( ! $object_id ) {
  47          return false;
  48      }
  49  
  50      $table = _get_meta_table( $meta_type );
  51      if ( ! $table ) {
  52          return false;
  53      }
  54  
  55      $meta_subtype = get_object_subtype( $meta_type, $object_id );
  56  
  57      $column = sanitize_key( $meta_type . '_id' );
  58  
  59      // expected_slashed ($meta_key)
  60      $meta_key   = wp_unslash( $meta_key );
  61      $meta_value = wp_unslash( $meta_value );
  62      $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
  63  
  64      /**
  65       * Short-circuits adding metadata of a specific type.
  66       *
  67       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
  68       * (post, comment, term, user, or any other type with an associated meta table).
  69       * Returning a non-null value will effectively short-circuit the function.
  70       *
  71       * Possible hook names include:
  72       *
  73       *  - `add_post_metadata`
  74       *  - `add_comment_metadata`
  75       *  - `add_term_metadata`
  76       *  - `add_user_metadata`
  77       *
  78       * @since 3.1.0
  79       *
  80       * @param null|bool $check      Whether to allow adding metadata for the given type.
  81       * @param int       $object_id  ID of the object metadata is for.
  82       * @param string    $meta_key   Metadata key.
  83       * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
  84       * @param bool      $unique     Whether the specified meta key should be unique for the object.
  85       */
  86      $check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique );
  87      if ( null !== $check ) {
  88          return $check;
  89      }
  90  
  91      if ( $unique && $wpdb->get_var(
  92          $wpdb->prepare(
  93              "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d",
  94              $meta_key,
  95              $object_id
  96          )
  97      ) ) {
  98          return false;
  99      }
 100  
 101      $_meta_value = $meta_value;
 102      $meta_value  = maybe_serialize( $meta_value );
 103  
 104      /**
 105       * Fires immediately before meta of a specific type is added.
 106       *
 107       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 108       * (post, comment, term, user, or any other type with an associated meta table).
 109       *
 110       * Possible hook names include:
 111       *
 112       *  - `add_post_meta`
 113       *  - `add_comment_meta`
 114       *  - `add_term_meta`
 115       *  - `add_user_meta`
 116       *
 117       * @since 3.1.0
 118       *
 119       * @param int    $object_id   ID of the object metadata is for.
 120       * @param string $meta_key    Metadata key.
 121       * @param mixed  $_meta_value Metadata value.
 122       */
 123      do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value );
 124  
 125      $result = $wpdb->insert(
 126          $table,
 127          array(
 128              $column      => $object_id,
 129              'meta_key'   => $meta_key,
 130              'meta_value' => $meta_value,
 131          )
 132      );
 133  
 134      if ( ! $result ) {
 135          return false;
 136      }
 137  
 138      $mid = (int) $wpdb->insert_id;
 139  
 140      wp_cache_delete( $object_id, $meta_type . '_meta' );
 141  
 142      /**
 143       * Fires immediately after meta of a specific type is added.
 144       *
 145       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 146       * (post, comment, term, user, or any other type with an associated meta table).
 147       *
 148       * Possible hook names include:
 149       *
 150       *  - `added_post_meta`
 151       *  - `added_comment_meta`
 152       *  - `added_term_meta`
 153       *  - `added_user_meta`
 154       *
 155       * @since 2.9.0
 156       *
 157       * @param int    $mid         The meta ID after successful update.
 158       * @param int    $object_id   ID of the object metadata is for.
 159       * @param string $meta_key    Metadata key.
 160       * @param mixed  $_meta_value Metadata value.
 161       */
 162      do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value );
 163  
 164      return $mid;
 165  }
 166  
 167  /**
 168   * Updates metadata for the specified object. If no value already exists for the specified object
 169   * ID and metadata key, the metadata will be added.
 170   *
 171   * @since 2.9.0
 172   *
 173   * @global wpdb $wpdb WordPress database abstraction object.
 174   *
 175   * @param string $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 176   *                           or any other object type with an associated meta table.
 177   * @param int    $object_id  ID of the object metadata is for.
 178   * @param string $meta_key   Metadata key.
 179   * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
 180   * @param mixed  $prev_value Optional. Previous value to check before updating.
 181   *                           If specified, only update existing metadata entries with
 182   *                           this value. Otherwise, update all entries. Default empty string.
 183   * @return int|bool The new meta field ID if a field with the given key didn't exist
 184   *                  and was therefore added, true on successful update,
 185   *                  false on failure or if the value passed to the function
 186   *                  is the same as the one that is already in the database.
 187   */
 188  function update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_value = '' ) {
 189      global $wpdb;
 190  
 191      if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
 192          return false;
 193      }
 194  
 195      $object_id = absint( $object_id );
 196      if ( ! $object_id ) {
 197          return false;
 198      }
 199  
 200      $table = _get_meta_table( $meta_type );
 201      if ( ! $table ) {
 202          return false;
 203      }
 204  
 205      $meta_subtype = get_object_subtype( $meta_type, $object_id );
 206  
 207      $column    = sanitize_key( $meta_type . '_id' );
 208      $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
 209  
 210      // expected_slashed ($meta_key)
 211      $raw_meta_key = $meta_key;
 212      $meta_key     = wp_unslash( $meta_key );
 213      $passed_value = $meta_value;
 214      $meta_value   = wp_unslash( $meta_value );
 215      $meta_value   = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
 216  
 217      /**
 218       * Short-circuits updating metadata of a specific type.
 219       *
 220       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 221       * (post, comment, term, user, or any other type with an associated meta table).
 222       * Returning a non-null value will effectively short-circuit the function.
 223       *
 224       * Possible hook names include:
 225       *
 226       *  - `update_post_metadata`
 227       *  - `update_comment_metadata`
 228       *  - `update_term_metadata`
 229       *  - `update_user_metadata`
 230       *
 231       * @since 3.1.0
 232       *
 233       * @param null|bool $check      Whether to allow updating metadata for the given type.
 234       * @param int       $object_id  ID of the object metadata is for.
 235       * @param string    $meta_key   Metadata key.
 236       * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
 237       * @param mixed     $prev_value Optional. Previous value to check before updating.
 238       *                              If specified, only update existing metadata entries with
 239       *                              this value. Otherwise, update all entries.
 240       */
 241      $check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value );
 242      if ( null !== $check ) {
 243          return (bool) $check;
 244      }
 245  
 246      // Compare existing value to new value if no prev value given and the key exists only once.
 247      if ( empty( $prev_value ) ) {
 248          $old_value = get_metadata_raw( $meta_type, $object_id, $meta_key );
 249          if ( is_countable( $old_value ) && count( $old_value ) === 1 ) {
 250              if ( $old_value[0] === $meta_value ) {
 251                  return false;
 252              }
 253          }
 254      }
 255  
 256      $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) );
 257      if ( empty( $meta_ids ) ) {
 258          return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value );
 259      }
 260  
 261      $_meta_value = $meta_value;
 262      $meta_value  = maybe_serialize( $meta_value );
 263  
 264      $data  = compact( 'meta_value' );
 265      $where = array(
 266          $column    => $object_id,
 267          'meta_key' => $meta_key,
 268      );
 269  
 270      if ( ! empty( $prev_value ) ) {
 271          $prev_value          = maybe_serialize( $prev_value );
 272          $where['meta_value'] = $prev_value;
 273      }
 274  
 275      foreach ( $meta_ids as $meta_id ) {
 276          /**
 277           * Fires immediately before updating metadata of a specific type.
 278           *
 279           * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 280           * (post, comment, term, user, or any other type with an associated meta table).
 281           *
 282           * Possible hook names include:
 283           *
 284           *  - `update_post_meta`
 285           *  - `update_comment_meta`
 286           *  - `update_term_meta`
 287           *  - `update_user_meta`
 288           *
 289           * @since 2.9.0
 290           *
 291           * @param int    $meta_id     ID of the metadata entry to update.
 292           * @param int    $object_id   ID of the object metadata is for.
 293           * @param string $meta_key    Metadata key.
 294           * @param mixed  $_meta_value Metadata value.
 295           */
 296          do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
 297  
 298          if ( 'post' === $meta_type ) {
 299              /**
 300               * Fires immediately before updating a post's metadata.
 301               *
 302               * @since 2.9.0
 303               *
 304               * @param int    $meta_id    ID of metadata entry to update.
 305               * @param int    $object_id  Post ID.
 306               * @param string $meta_key   Metadata key.
 307               * @param mixed  $meta_value Metadata value. This will be a PHP-serialized string representation of the value
 308               *                           if the value is an array, an object, or itself a PHP-serialized string.
 309               */
 310              do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
 311          }
 312      }
 313  
 314      $result = $wpdb->update( $table, $data, $where );
 315      if ( ! $result ) {
 316          return false;
 317      }
 318  
 319      wp_cache_delete( $object_id, $meta_type . '_meta' );
 320  
 321      foreach ( $meta_ids as $meta_id ) {
 322          /**
 323           * Fires immediately after updating metadata of a specific type.
 324           *
 325           * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 326           * (post, comment, term, user, or any other type with an associated meta table).
 327           *
 328           * Possible hook names include:
 329           *
 330           *  - `updated_post_meta`
 331           *  - `updated_comment_meta`
 332           *  - `updated_term_meta`
 333           *  - `updated_user_meta`
 334           *
 335           * @since 2.9.0
 336           *
 337           * @param int    $meta_id     ID of updated metadata entry.
 338           * @param int    $object_id   ID of the object metadata is for.
 339           * @param string $meta_key    Metadata key.
 340           * @param mixed  $_meta_value Metadata value.
 341           */
 342          do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
 343  
 344          if ( 'post' === $meta_type ) {
 345              /**
 346               * Fires immediately after updating a post's metadata.
 347               *
 348               * @since 2.9.0
 349               *
 350               * @param int    $meta_id    ID of updated metadata entry.
 351               * @param int    $object_id  Post ID.
 352               * @param string $meta_key   Metadata key.
 353               * @param mixed  $meta_value Metadata value. This will be a PHP-serialized string representation of the value
 354               *                           if the value is an array, an object, or itself a PHP-serialized string.
 355               */
 356              do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
 357          }
 358      }
 359  
 360      return true;
 361  }
 362  
 363  /**
 364   * Deletes metadata for the specified object.
 365   *
 366   * @since 2.9.0
 367   *
 368   * @global wpdb $wpdb WordPress database abstraction object.
 369   *
 370   * @param string $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 371   *                           or any other object type with an associated meta table.
 372   * @param int    $object_id  ID of the object metadata is for.
 373   * @param string $meta_key   Metadata key.
 374   * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar.
 375   *                           If specified, only delete metadata entries with this value.
 376   *                           Otherwise, delete all entries with the specified meta_key.
 377   *                           Pass `null`, `false`, or an empty string to skip this check.
 378   *                           (For backward compatibility, it is not possible to pass an empty string
 379   *                           to delete those entries with an empty string for a value.)
 380   *                           Default empty string.
 381   * @param bool   $delete_all Optional. If true, delete matching metadata entries for all objects,
 382   *                           ignoring the specified object_id. Otherwise, only delete
 383   *                           matching metadata entries for the specified object_id. Default false.
 384   * @return bool True on successful delete, false on failure.
 385   */
 386  function delete_metadata( $meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
 387      global $wpdb;
 388  
 389      if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) {
 390          return false;
 391      }
 392  
 393      $object_id = absint( $object_id );
 394      if ( ! $object_id && ! $delete_all ) {
 395          return false;
 396      }
 397  
 398      $table = _get_meta_table( $meta_type );
 399      if ( ! $table ) {
 400          return false;
 401      }
 402  
 403      $type_column = sanitize_key( $meta_type . '_id' );
 404      $id_column   = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
 405  
 406      // expected_slashed ($meta_key)
 407      $meta_key   = wp_unslash( $meta_key );
 408      $meta_value = wp_unslash( $meta_value );
 409  
 410      /**
 411       * Short-circuits deleting metadata of a specific type.
 412       *
 413       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 414       * (post, comment, term, user, or any other type with an associated meta table).
 415       * Returning a non-null value will effectively short-circuit the function.
 416       *
 417       * Possible hook names include:
 418       *
 419       *  - `delete_post_metadata`
 420       *  - `delete_comment_metadata`
 421       *  - `delete_term_metadata`
 422       *  - `delete_user_metadata`
 423       *
 424       * @since 3.1.0
 425       *
 426       * @param null|bool $delete     Whether to allow metadata deletion of the given type.
 427       * @param int       $object_id  ID of the object metadata is for.
 428       * @param string    $meta_key   Metadata key.
 429       * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
 430       * @param bool      $delete_all Whether to delete the matching metadata entries
 431       *                              for all objects, ignoring the specified $object_id.
 432       *                              Default false.
 433       */
 434      $check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all );
 435      if ( null !== $check ) {
 436          return (bool) $check;
 437      }
 438  
 439      $_meta_value = $meta_value;
 440      $meta_value  = maybe_serialize( $meta_value );
 441  
 442      $query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key );
 443  
 444      if ( ! $delete_all ) {
 445          $query .= $wpdb->prepare( " AND $type_column = %d", $object_id );
 446      }
 447  
 448      if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
 449          $query .= $wpdb->prepare( ' AND meta_value = %s', $meta_value );
 450      }
 451  
 452      $meta_ids = $wpdb->get_col( $query );
 453      if ( ! count( $meta_ids ) ) {
 454          return false;
 455      }
 456  
 457      if ( $delete_all ) {
 458          if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
 459              $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value ) );
 460          } else {
 461              $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s", $meta_key ) );
 462          }
 463      }
 464  
 465      /**
 466       * Fires immediately before deleting metadata of a specific type.
 467       *
 468       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 469       * (post, comment, term, user, or any other type with an associated meta table).
 470       *
 471       * Possible hook names include:
 472       *
 473       *  - `delete_post_meta`
 474       *  - `delete_comment_meta`
 475       *  - `delete_term_meta`
 476       *  - `delete_user_meta`
 477       *
 478       * @since 3.1.0
 479       *
 480       * @param string[] $meta_ids    An array of metadata entry IDs to delete.
 481       * @param int      $object_id   ID of the object metadata is for.
 482       * @param string   $meta_key    Metadata key.
 483       * @param mixed    $_meta_value Metadata value.
 484       */
 485      do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
 486  
 487      // Old-style action.
 488      if ( 'post' === $meta_type ) {
 489          /**
 490           * Fires immediately before deleting metadata for a post.
 491           *
 492           * @since 2.9.0
 493           *
 494           * @param string[] $meta_ids An array of metadata entry IDs to delete.
 495           */
 496          do_action( 'delete_postmeta', $meta_ids );
 497      }
 498  
 499      $query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . ' )';
 500  
 501      $count = $wpdb->query( $query );
 502  
 503      if ( ! $count ) {
 504          return false;
 505      }
 506  
 507      if ( $delete_all ) {
 508          $data = (array) $object_ids;
 509      } else {
 510          $data = array( $object_id );
 511      }
 512      wp_cache_delete_multiple( $data, $meta_type . '_meta' );
 513  
 514      /**
 515       * Fires immediately after deleting metadata of a specific type.
 516       *
 517       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 518       * (post, comment, term, user, or any other type with an associated meta table).
 519       *
 520       * Possible hook names include:
 521       *
 522       *  - `deleted_post_meta`
 523       *  - `deleted_comment_meta`
 524       *  - `deleted_term_meta`
 525       *  - `deleted_user_meta`
 526       *
 527       * @since 2.9.0
 528       *
 529       * @param string[] $meta_ids    An array of metadata entry IDs to delete.
 530       * @param int      $object_id   ID of the object metadata is for.
 531       * @param string   $meta_key    Metadata key.
 532       * @param mixed    $_meta_value Metadata value.
 533       */
 534      do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
 535  
 536      // Old-style action.
 537      if ( 'post' === $meta_type ) {
 538          /**
 539           * Fires immediately after deleting metadata for a post.
 540           *
 541           * @since 2.9.0
 542           *
 543           * @param string[] $meta_ids An array of metadata entry IDs to delete.
 544           */
 545          do_action( 'deleted_postmeta', $meta_ids );
 546      }
 547  
 548      return true;
 549  }
 550  
 551  /**
 552   * Retrieves the value of a metadata field for the specified object type and ID.
 553   *
 554   * If the meta field exists, a single value is returned if `$single` is true,
 555   * or an array of values if it's false.
 556   *
 557   * If the meta field does not exist, the result depends on get_metadata_default().
 558   * By default, an empty string is returned if `$single` is true, or an empty array
 559   * if it's false.
 560   *
 561   * @since 2.9.0
 562   *
 563   * @see get_metadata_raw()
 564   * @see get_metadata_default()
 565   *
 566   * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 567   *                          or any other object type with an associated meta table.
 568   * @param int    $object_id ID of the object metadata is for.
 569   * @param string $meta_key  Optional. Metadata key. If not specified, retrieve all metadata for
 570   *                          the specified object. Default empty string.
 571   * @param bool   $single    Optional. If true, return only the first value of the specified `$meta_key`.
 572   *                          This parameter has no effect if `$meta_key` is not specified. Default false.
 573   * @return mixed An array of values if `$single` is false.
 574   *               The value of the meta field if `$single` is true.
 575   *               False for an invalid `$object_id` (non-numeric, zero, or negative value),
 576   *               or if `$meta_type` is not specified.
 577   *               An empty array if a valid but non-existing object ID is passed and `$single` is false.
 578   *               An empty string if a valid but non-existing object ID is passed and `$single` is true.
 579   *               Note: Non-serialized values are returned as strings:
 580   *               - false values are returned as empty strings ('')
 581   *               - true values are returned as '1'
 582   *               - numbers (both integer and float) are returned as strings
 583   *               Arrays and objects retain their original type.
 584   */
 585  function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false ) {
 586      $value = get_metadata_raw( $meta_type, $object_id, $meta_key, $single );
 587      if ( ! is_null( $value ) ) {
 588          return $value;
 589      }
 590  
 591      return get_metadata_default( $meta_type, $object_id, $meta_key, $single );
 592  }
 593  
 594  /**
 595   * Retrieves raw metadata value for the specified object.
 596   *
 597   * @since 5.5.0
 598   *
 599   * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 600   *                          or any other object type with an associated meta table.
 601   * @param int    $object_id ID of the object metadata is for.
 602   * @param string $meta_key  Optional. Metadata key. If not specified, retrieve all metadata for
 603   *                          the specified object. Default empty string.
 604   * @param bool   $single    Optional. If true, return only the first value of the specified `$meta_key`.
 605   *                          This parameter has no effect if `$meta_key` is not specified. Default false.
 606   * @return mixed An array of values if `$single` is false.
 607   *               The value of the meta field if `$single` is true.
 608   *               False for an invalid `$object_id` (non-numeric, zero, or negative value),
 609   *               or if `$meta_type` is not specified.
 610   *               Null if the value does not exist.
 611   */
 612  function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = false ) {
 613      if ( ! $meta_type || ! is_numeric( $object_id ) ) {
 614          return false;
 615      }
 616  
 617      $object_id = absint( $object_id );
 618      if ( ! $object_id ) {
 619          return false;
 620      }
 621  
 622      /**
 623       * Short-circuits the return value of a meta field.
 624       *
 625       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 626       * (post, comment, term, user, or any other type with an associated meta table).
 627       * Returning a non-null value will effectively short-circuit the function.
 628       *
 629       * Possible filter names include:
 630       *
 631       *  - `get_post_metadata`
 632       *  - `get_comment_metadata`
 633       *  - `get_term_metadata`
 634       *  - `get_user_metadata`
 635       *
 636       * @since 3.1.0
 637       * @since 5.5.0 Added the `$meta_type` parameter.
 638       *
 639       * @param mixed  $value     The value to return, either a single metadata value or an array
 640       *                          of values depending on the value of `$single`. Default null.
 641       * @param int    $object_id ID of the object metadata is for.
 642       * @param string $meta_key  Metadata key.
 643       * @param bool   $single    Whether to return only the first value of the specified `$meta_key`.
 644       * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 645       *                          or any other object type with an associated meta table.
 646       */
 647      $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single, $meta_type );
 648      if ( null !== $check ) {
 649          if ( $single && is_array( $check ) ) {
 650              return $check[0];
 651          } else {
 652              return $check;
 653          }
 654      }
 655  
 656      $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
 657  
 658      if ( ! $meta_cache ) {
 659          $meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
 660          if ( isset( $meta_cache[ $object_id ] ) ) {
 661              $meta_cache = $meta_cache[ $object_id ];
 662          } else {
 663              $meta_cache = null;
 664          }
 665      }
 666  
 667      if ( ! $meta_key ) {
 668          return $meta_cache;
 669      }
 670  
 671      if ( isset( $meta_cache[ $meta_key ] ) ) {
 672          if ( $single ) {
 673              return maybe_unserialize( $meta_cache[ $meta_key ][0] );
 674          } else {
 675              return array_map( 'maybe_unserialize', $meta_cache[ $meta_key ] );
 676          }
 677      }
 678  
 679      return null;
 680  }
 681  
 682  /**
 683   * Retrieves default metadata value for the specified meta key and object.
 684   *
 685   * By default, an empty string is returned if `$single` is true, or an empty array
 686   * if it's false.
 687   *
 688   * @since 5.5.0
 689   *
 690   * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 691   *                          or any other object type with an associated meta table.
 692   * @param int    $object_id ID of the object metadata is for.
 693   * @param string $meta_key  Metadata key.
 694   * @param bool   $single    Optional. If true, return only the first value of the specified `$meta_key`.
 695   *                          This parameter has no effect if `$meta_key` is not specified. Default false.
 696   * @return mixed An array of default values if `$single` is false.
 697   *               The default value of the meta field if `$single` is true.
 698   */
 699  function get_metadata_default( $meta_type, $object_id, $meta_key, $single = false ) {
 700      if ( $single ) {
 701          $value = '';
 702      } else {
 703          $value = array();
 704      }
 705  
 706      /**
 707       * Filters the default metadata value for a specified meta key and object.
 708       *
 709       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 710       * (post, comment, term, user, or any other type with an associated meta table).
 711       *
 712       * Possible filter names include:
 713       *
 714       *  - `default_post_metadata`
 715       *  - `default_comment_metadata`
 716       *  - `default_term_metadata`
 717       *  - `default_user_metadata`
 718       *
 719       * @since 5.5.0
 720       *
 721       * @param mixed  $value     The value to return, either a single metadata value or an array
 722       *                          of values depending on the value of `$single`.
 723       * @param int    $object_id ID of the object metadata is for.
 724       * @param string $meta_key  Metadata key.
 725       * @param bool   $single    Whether to return only the first value of the specified `$meta_key`.
 726       * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 727       *                          or any other object type with an associated meta table.
 728       */
 729      $value = apply_filters( "default_{$meta_type}_metadata", $value, $object_id, $meta_key, $single, $meta_type );
 730  
 731      if ( ! $single && ! wp_is_numeric_array( $value ) ) {
 732          $value = array( $value );
 733      }
 734  
 735      return $value;
 736  }
 737  
 738  /**
 739   * Determines if a meta field with the given key exists for the given object ID.
 740   *
 741   * @since 3.3.0
 742   *
 743   * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 744   *                          or any other object type with an associated meta table.
 745   * @param int    $object_id ID of the object metadata is for.
 746   * @param string $meta_key  Metadata key.
 747   * @return bool Whether a meta field with the given key exists.
 748   */
 749  function metadata_exists( $meta_type, $object_id, $meta_key ) {
 750      if ( ! $meta_type || ! is_numeric( $object_id ) ) {
 751          return false;
 752      }
 753  
 754      $object_id = absint( $object_id );
 755      if ( ! $object_id ) {
 756          return false;
 757      }
 758  
 759      /** This filter is documented in wp-includes/meta.php */
 760      $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true, $meta_type );
 761      if ( null !== $check ) {
 762          return (bool) $check;
 763      }
 764  
 765      $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
 766  
 767      if ( ! $meta_cache ) {
 768          $meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
 769          $meta_cache = $meta_cache[ $object_id ];
 770      }
 771  
 772      if ( isset( $meta_cache[ $meta_key ] ) ) {
 773          return true;
 774      }
 775  
 776      return false;
 777  }
 778  
 779  /**
 780   * Retrieves metadata by meta ID.
 781   *
 782   * @since 3.3.0
 783   *
 784   * @global wpdb $wpdb WordPress database abstraction object.
 785   *
 786   * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 787   *                          or any other object type with an associated meta table.
 788   * @param int    $meta_id   ID for a specific meta row.
 789   * @return stdClass|false {
 790   *     Metadata object, or boolean `false` if the metadata doesn't exist.
 791   *
 792   *     @type string $meta_key   The meta key.
 793   *     @type mixed  $meta_value The unserialized meta value.
 794   *     @type string $meta_id    Optional. The meta ID when the meta type is any value except 'user'.
 795   *     @type string $umeta_id   Optional. The meta ID when the meta type is 'user'.
 796   *     @type string $post_id    Optional. The object ID when the meta type is 'post'.
 797   *     @type string $comment_id Optional. The object ID when the meta type is 'comment'.
 798   *     @type string $term_id    Optional. The object ID when the meta type is 'term'.
 799   *     @type string $user_id    Optional. The object ID when the meta type is 'user'.
 800   * }
 801   */
 802  function get_metadata_by_mid( $meta_type, $meta_id ) {
 803      global $wpdb;
 804  
 805      if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) {
 806          return false;
 807      }
 808  
 809      $meta_id = (int) $meta_id;
 810      if ( $meta_id <= 0 ) {
 811          return false;
 812      }
 813  
 814      $table = _get_meta_table( $meta_type );
 815      if ( ! $table ) {
 816          return false;
 817      }
 818  
 819      /**
 820       * Short-circuits the return value when fetching a meta field by meta ID.
 821       *
 822       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 823       * (post, comment, term, user, or any other type with an associated meta table).
 824       * Returning a non-null value will effectively short-circuit the function.
 825       *
 826       * Possible hook names include:
 827       *
 828       *  - `get_post_metadata_by_mid`
 829       *  - `get_comment_metadata_by_mid`
 830       *  - `get_term_metadata_by_mid`
 831       *  - `get_user_metadata_by_mid`
 832       *
 833       * @since 5.0.0
 834       *
 835       * @param stdClass|null $value   The value to return.
 836       * @param int           $meta_id Meta ID.
 837       */
 838      $check = apply_filters( "get_{$meta_type}_metadata_by_mid", null, $meta_id );
 839      if ( null !== $check ) {
 840          return $check;
 841      }
 842  
 843      $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
 844  
 845      $meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) );
 846  
 847      if ( empty( $meta ) ) {
 848          return false;
 849      }
 850  
 851      if ( isset( $meta->meta_value ) ) {
 852          $meta->meta_value = maybe_unserialize( $meta->meta_value );
 853      }
 854  
 855      return $meta;
 856  }
 857  
 858  /**
 859   * Updates metadata by meta ID.
 860   *
 861   * @since 3.3.0
 862   *
 863   * @global wpdb $wpdb WordPress database abstraction object.
 864   *
 865   * @param string       $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 866   *                                 or any other object type with an associated meta table.
 867   * @param int          $meta_id    ID for a specific meta row.
 868   * @param string       $meta_value Metadata value. Must be serializable if non-scalar.
 869   * @param string|false $meta_key   Optional. You can provide a meta key to update it. Default false.
 870   * @return bool True on successful update, false on failure.
 871   */
 872  function update_metadata_by_mid( $meta_type, $meta_id, $meta_value, $meta_key = false ) {
 873      global $wpdb;
 874  
 875      // Make sure everything is valid.
 876      if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) {
 877          return false;
 878      }
 879  
 880      $meta_id = (int) $meta_id;
 881      if ( $meta_id <= 0 ) {
 882          return false;
 883      }
 884  
 885      $table = _get_meta_table( $meta_type );
 886      if ( ! $table ) {
 887          return false;
 888      }
 889  
 890      $column    = sanitize_key( $meta_type . '_id' );
 891      $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
 892  
 893      /**
 894       * Short-circuits updating metadata of a specific type by meta ID.
 895       *
 896       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
 897       * (post, comment, term, user, or any other type with an associated meta table).
 898       * Returning a non-null value will effectively short-circuit the function.
 899       *
 900       * Possible hook names include:
 901       *
 902       *  - `update_post_metadata_by_mid`
 903       *  - `update_comment_metadata_by_mid`
 904       *  - `update_term_metadata_by_mid`
 905       *  - `update_user_metadata_by_mid`
 906       *
 907       * @since 5.0.0
 908       *
 909       * @param null|bool    $check      Whether to allow updating metadata for the given type.
 910       * @param int          $meta_id    Meta ID.
 911       * @param mixed        $meta_value Meta value. Must be serializable if non-scalar.
 912       * @param string|false $meta_key   Meta key, if provided.
 913       */
 914      $check = apply_filters( "update_{$meta_type}_metadata_by_mid", null, $meta_id, $meta_value, $meta_key );
 915      if ( null !== $check ) {
 916          return (bool) $check;
 917      }
 918  
 919      // Fetch the meta and go on if it's found.
 920      $meta = get_metadata_by_mid( $meta_type, $meta_id );
 921      if ( $meta ) {
 922          $original_key = $meta->meta_key;
 923          $object_id    = $meta->{$column};
 924  
 925          /*
 926           * If a new meta_key (last parameter) was specified, change the meta key,
 927           * otherwise use the original key in the update statement.
 928           */
 929          if ( false === $meta_key ) {
 930              $meta_key = $original_key;
 931          } elseif ( ! is_string( $meta_key ) ) {
 932              return false;
 933          }
 934  
 935          $meta_subtype = get_object_subtype( $meta_type, $object_id );
 936  
 937          // Sanitize the meta.
 938          $_meta_value = $meta_value;
 939          $meta_value  = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
 940          $meta_value  = maybe_serialize( $meta_value );
 941  
 942          // Format the data query arguments.
 943          $data = array(
 944              'meta_key'   => $meta_key,
 945              'meta_value' => $meta_value,
 946          );
 947  
 948          // Format the where query arguments.
 949          $where               = array();
 950          $where[ $id_column ] = $meta_id;
 951  
 952          /** This action is documented in wp-includes/meta.php */
 953          do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
 954  
 955          if ( 'post' === $meta_type ) {
 956              /** This action is documented in wp-includes/meta.php */
 957              do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
 958          }
 959  
 960          // Run the update query, all fields in $data are %s, $where is a %d.
 961          $result = $wpdb->update( $table, $data, $where, '%s', '%d' );
 962          if ( ! $result ) {
 963              return false;
 964          }
 965  
 966          // Clear the caches.
 967          wp_cache_delete( $object_id, $meta_type . '_meta' );
 968  
 969          /** This action is documented in wp-includes/meta.php */
 970          do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
 971  
 972          if ( 'post' === $meta_type ) {
 973              /** This action is documented in wp-includes/meta.php */
 974              do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
 975          }
 976  
 977          return true;
 978      }
 979  
 980      // And if the meta was not found.
 981      return false;
 982  }
 983  
 984  /**
 985   * Deletes metadata by meta ID.
 986   *
 987   * @since 3.3.0
 988   *
 989   * @global wpdb $wpdb WordPress database abstraction object.
 990   *
 991   * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 992   *                          or any other object type with an associated meta table.
 993   * @param int    $meta_id   ID for a specific meta row.
 994   * @return bool True on successful delete, false on failure.
 995   */
 996  function delete_metadata_by_mid( $meta_type, $meta_id ) {
 997      global $wpdb;
 998  
 999      // Make sure everything is valid.
1000      if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) {
1001          return false;
1002      }
1003  
1004      $meta_id = (int) $meta_id;
1005      if ( $meta_id <= 0 ) {
1006          return false;
1007      }
1008  
1009      $table = _get_meta_table( $meta_type );
1010      if ( ! $table ) {
1011          return false;
1012      }
1013  
1014      // Object and ID columns.
1015      $column    = sanitize_key( $meta_type . '_id' );
1016      $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
1017  
1018      /**
1019       * Short-circuits deleting metadata of a specific type by meta ID.
1020       *
1021       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
1022       * (post, comment, term, user, or any other type with an associated meta table).
1023       * Returning a non-null value will effectively short-circuit the function.
1024       *
1025       * Possible hook names include:
1026       *
1027       *  - `delete_post_metadata_by_mid`
1028       *  - `delete_comment_metadata_by_mid`
1029       *  - `delete_term_metadata_by_mid`
1030       *  - `delete_user_metadata_by_mid`
1031       *
1032       * @since 5.0.0
1033       *
1034       * @param null|bool $delete  Whether to allow metadata deletion of the given type.
1035       * @param int       $meta_id Meta ID.
1036       */
1037      $check = apply_filters( "delete_{$meta_type}_metadata_by_mid", null, $meta_id );
1038      if ( null !== $check ) {
1039          return (bool) $check;
1040      }
1041  
1042      // Fetch the meta and go on if it's found.
1043      $meta = get_metadata_by_mid( $meta_type, $meta_id );
1044      if ( $meta ) {
1045          $object_id = (int) $meta->{$column};
1046  
1047          /** This action is documented in wp-includes/meta.php */
1048          do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
1049  
1050          // Old-style action.
1051          if ( 'post' === $meta_type || 'comment' === $meta_type ) {
1052              /**
1053               * Fires immediately before deleting post or comment metadata of a specific type.
1054               *
1055               * The dynamic portion of the hook name, `$meta_type`, refers to the meta
1056               * object type (post or comment).
1057               *
1058               * Possible hook names include:
1059               *
1060               *  - `delete_postmeta`
1061               *  - `delete_commentmeta`
1062               *  - `delete_termmeta`
1063               *  - `delete_usermeta`
1064               *
1065               * @since 3.4.0
1066               *
1067               * @param int $meta_id ID of the metadata entry to delete.
1068               */
1069              do_action( "delete_{$meta_type}meta", $meta_id );
1070          }
1071  
1072          // Run the query, will return true if deleted, false otherwise.
1073          $result = (bool) $wpdb->delete( $table, array( $id_column => $meta_id ) );
1074  
1075          // Clear the caches.
1076          wp_cache_delete( $object_id, $meta_type . '_meta' );
1077  
1078          /** This action is documented in wp-includes/meta.php */
1079          do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
1080  
1081          // Old-style action.
1082          if ( 'post' === $meta_type || 'comment' === $meta_type ) {
1083              /**
1084               * Fires immediately after deleting post or comment metadata of a specific type.
1085               *
1086               * The dynamic portion of the hook name, `$meta_type`, refers to the meta
1087               * object type (post or comment).
1088               *
1089               * Possible hook names include:
1090               *
1091               *  - `deleted_postmeta`
1092               *  - `deleted_commentmeta`
1093               *  - `deleted_termmeta`
1094               *  - `deleted_usermeta`
1095               *
1096               * @since 3.4.0
1097               *
1098               * @param int $meta_id Deleted metadata entry ID.
1099               */
1100              do_action( "deleted_{$meta_type}meta", $meta_id );
1101          }
1102  
1103          return $result;
1104  
1105      }
1106  
1107      // Meta ID was not found.
1108      return false;
1109  }
1110  
1111  /**
1112   * Updates the metadata cache for the specified objects.
1113   *
1114   * @since 2.9.0
1115   *
1116   * @global wpdb $wpdb WordPress database abstraction object.
1117   *
1118   * @param string       $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1119   *                                 or any other object type with an associated meta table.
1120   * @param string|int[] $object_ids Array or comma delimited list of object IDs to update cache for.
1121   * @return array|false Metadata cache for the specified objects, or false on failure.
1122   */
1123  function update_meta_cache( $meta_type, $object_ids ) {
1124      global $wpdb;
1125  
1126      if ( ! $meta_type || ! $object_ids ) {
1127          return false;
1128      }
1129  
1130      $table = _get_meta_table( $meta_type );
1131      if ( ! $table ) {
1132          return false;
1133      }
1134  
1135      $column = sanitize_key( $meta_type . '_id' );
1136  
1137      if ( ! is_array( $object_ids ) ) {
1138          $object_ids = preg_replace( '|[^0-9,]|', '', $object_ids );
1139          $object_ids = explode( ',', $object_ids );
1140      }
1141  
1142      $object_ids = array_map( 'intval', $object_ids );
1143  
1144      /**
1145       * Short-circuits updating the metadata cache of a specific type.
1146       *
1147       * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
1148       * (post, comment, term, user, or any other type with an associated meta table).
1149       * Returning a non-null value will effectively short-circuit the function.
1150       *
1151       * Possible hook names include:
1152       *
1153       *  - `update_post_metadata_cache`
1154       *  - `update_comment_metadata_cache`
1155       *  - `update_term_metadata_cache`
1156       *  - `update_user_metadata_cache`
1157       *
1158       * @since 5.0.0
1159       *
1160       * @param mixed $check      Whether to allow updating the meta cache of the given type.
1161       * @param int[] $object_ids Array of object IDs to update the meta cache for.
1162       */
1163      $check = apply_filters( "update_{$meta_type}_metadata_cache", null, $object_ids );
1164      if ( null !== $check ) {
1165          return (bool) $check;
1166      }
1167  
1168      $cache_key      = $meta_type . '_meta';
1169      $non_cached_ids = array();
1170      $cache          = array();
1171      $cache_values   = wp_cache_get_multiple( $object_ids, $cache_key );
1172  
1173      foreach ( $cache_values as $id => $cached_object ) {
1174          if ( false === $cached_object ) {
1175              $non_cached_ids[] = $id;
1176          } else {
1177              $cache[ $id ] = $cached_object;
1178          }
1179      }
1180  
1181      if ( empty( $non_cached_ids ) ) {
1182          return $cache;
1183      }
1184  
1185      // Get meta info.
1186      $id_list   = implode( ',', $non_cached_ids );
1187      $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
1188  
1189      $meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A );
1190  
1191      if ( ! empty( $meta_list ) ) {
1192          foreach ( $meta_list as $metarow ) {
1193              $mpid = (int) $metarow[ $column ];
1194              $mkey = $metarow['meta_key'];
1195              $mval = $metarow['meta_value'];
1196  
1197              // Force subkeys to be array type.
1198              if ( ! isset( $cache[ $mpid ] ) || ! is_array( $cache[ $mpid ] ) ) {
1199                  $cache[ $mpid ] = array();
1200              }
1201              if ( ! isset( $cache[ $mpid ][ $mkey ] ) || ! is_array( $cache[ $mpid ][ $mkey ] ) ) {
1202                  $cache[ $mpid ][ $mkey ] = array();
1203              }
1204  
1205              // Add a value to the current pid/key.
1206              $cache[ $mpid ][ $mkey ][] = $mval;
1207          }
1208      }
1209  
1210      $data = array();
1211      foreach ( $non_cached_ids as $id ) {
1212          if ( ! isset( $cache[ $id ] ) ) {
1213              $cache[ $id ] = array();
1214          }
1215          $data[ $id ] = $cache[ $id ];
1216      }
1217      wp_cache_add_multiple( $data, $cache_key );
1218  
1219      return $cache;
1220  }
1221  
1222  /**
1223   * Retrieves the queue for lazy-loading metadata.
1224   *
1225   * @since 4.5.0
1226   *
1227   * @return WP_Metadata_Lazyloader Metadata lazyloader queue.
1228   */
1229  function wp_metadata_lazyloader() {
1230      static $wp_metadata_lazyloader;
1231  
1232      if ( null === $wp_metadata_lazyloader ) {
1233          $wp_metadata_lazyloader = new WP_Metadata_Lazyloader();
1234      }
1235  
1236      return $wp_metadata_lazyloader;
1237  }
1238  
1239  /**
1240   * Given a meta query, generates SQL clauses to be appended to a main query.
1241   *
1242   * @since 3.2.0
1243   *
1244   * @see WP_Meta_Query
1245   *
1246   * @param array  $meta_query        A meta query.
1247   * @param string $type              Type of meta.
1248   * @param string $primary_table     Primary database table name.
1249   * @param string $primary_id_column Primary ID column name.
1250   * @param object $context           Optional. The main query object. Default null.
1251   * @return string[]|false {
1252   *     Array containing JOIN and WHERE SQL clauses to append to the main query,
1253   *     or false if no table exists for the requested meta type.
1254   *
1255   *     @type string $join  SQL fragment to append to the main JOIN clause.
1256   *     @type string $where SQL fragment to append to the main WHERE clause.
1257   * }
1258   */
1259  function get_meta_sql( $meta_query, $type, $primary_table, $primary_id_column, $context = null ) {
1260      $meta_query_obj = new WP_Meta_Query( $meta_query );
1261      return $meta_query_obj->get_sql( $type, $primary_table, $primary_id_column, $context );
1262  }
1263  
1264  /**
1265   * Retrieves the name of the metadata table for the specified object type.
1266   *
1267   * @since 2.9.0
1268   *
1269   * @global wpdb $wpdb WordPress database abstraction object.
1270   *
1271   * @param string $type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1272   *                     or any other object type with an associated meta table.
1273   * @return string|false Metadata table name, or false if no metadata table exists
1274   */
1275  function _get_meta_table( $type ) {
1276      global $wpdb;
1277  
1278      $table_name = $type . 'meta';
1279  
1280      if ( empty( $wpdb->$table_name ) ) {
1281          return false;
1282      }
1283  
1284      return $wpdb->$table_name;
1285  }
1286  
1287  /**
1288   * Determines whether a meta key is considered protected.
1289   *
1290   * @since 3.1.3
1291   *
1292   * @param string $meta_key  Metadata key.
1293   * @param string $meta_type Optional. Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1294   *                          or any other object type with an associated meta table. Default empty string.
1295   * @return bool Whether the meta key is considered protected.
1296   */
1297  function is_protected_meta( $meta_key, $meta_type = '' ) {
1298      $sanitized_key = preg_replace( "/[^\x20-\x7E\p{L}]/", '', $meta_key );
1299      $protected     = strlen( $sanitized_key ) > 0 && ( '_' === $sanitized_key[0] );
1300  
1301      /**
1302       * Filters whether a meta key is considered protected.
1303       *
1304       * @since 3.2.0
1305       *
1306       * @param bool   $protected Whether the key is considered protected.
1307       * @param string $meta_key  Metadata key.
1308       * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1309       *                          or any other object type with an associated meta table.
1310       */
1311      return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type );
1312  }
1313  
1314  /**
1315   * Sanitizes meta value.
1316   *
1317   * @since 3.1.3
1318   * @since 4.9.8 The `$object_subtype` parameter was added.
1319   *
1320   * @param string $meta_key       Metadata key.
1321   * @param mixed  $meta_value     Metadata value to sanitize.
1322   * @param string $object_type    Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1323   *                               or any other object type with an associated meta table.
1324   * @param string $object_subtype Optional. The subtype of the object type. Default empty string.
1325   * @return mixed Sanitized $meta_value.
1326   */
1327  function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) {
1328      if ( ! empty( $object_subtype ) && has_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) {
1329  
1330          /**
1331           * Filters the sanitization of a specific meta key of a specific meta type and subtype.
1332           *
1333           * The dynamic portions of the hook name, `$object_type`, `$meta_key`,
1334           * and `$object_subtype`, refer to the metadata object type (comment, post, term, or user),
1335           * the meta key value, and the object subtype respectively.
1336           *
1337           * @since 4.9.8
1338           *
1339           * @param mixed  $meta_value     Metadata value to sanitize.
1340           * @param string $meta_key       Metadata key.
1341           * @param string $object_type    Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1342           *                               or any other object type with an associated meta table.
1343           * @param string $object_subtype Object subtype.
1344           */
1345          return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $meta_value, $meta_key, $object_type, $object_subtype );
1346      }
1347  
1348      /**
1349       * Filters the sanitization of a specific meta key of a specific meta type.
1350       *
1351       * The dynamic portions of the hook name, `$meta_type`, and `$meta_key`,
1352       * refer to the metadata object type (comment, post, term, or user) and the meta
1353       * key value, respectively.
1354       *
1355       * @since 3.3.0
1356       *
1357       * @param mixed  $meta_value  Metadata value to sanitize.
1358       * @param string $meta_key    Metadata key.
1359       * @param string $object_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1360       *                            or any other object type with an associated meta table.
1361       */
1362      return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}", $meta_value, $meta_key, $object_type );
1363  }
1364  
1365  /**
1366   * Registers a meta key.
1367   *
1368   * It is recommended to register meta keys for a specific combination of object type and object subtype. If passing
1369   * an object subtype is omitted, the meta key will be registered for the entire object type, however it can be partly
1370   * overridden in case a more specific meta key of the same name exists for the same object type and a subtype.
1371   *
1372   * If an object type does not support any subtypes, such as users or comments, you should commonly call this function
1373   * without passing a subtype.
1374   *
1375   * @since 3.3.0
1376   * @since 4.6.0 {@link https://core.trac.wordpress.org/ticket/35658 Modified
1377   *              to support an array of data to attach to registered meta keys}. Previous arguments for
1378   *              `$sanitize_callback` and `$auth_callback` have been folded into this array.
1379   * @since 4.9.8 The `$object_subtype` argument was added to the arguments array.
1380   * @since 5.3.0 Valid meta types expanded to include "array" and "object".
1381   * @since 5.5.0 The `$default` argument was added to the arguments array.
1382   * @since 6.4.0 The `$revisions_enabled` argument was added to the arguments array.
1383   * @since 6.7.0 The `label` argument was added to the arguments array.
1384   *
1385   * @param string       $object_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1386   *                                  or any other object type with an associated meta table.
1387   * @param string       $meta_key    Meta key to register.
1388   * @param array        $args {
1389   *     Data used to describe the meta key when registered.
1390   *
1391   *     @type string     $object_subtype    A subtype; e.g. if the object type is "post", the post type. If left empty,
1392   *                                         the meta key will be registered on the entire object type. Default empty.
1393   *     @type string     $type              The type of data associated with this meta key.
1394   *                                         Valid values are 'string', 'boolean', 'integer', 'number', 'array', and 'object'.
1395   *     @type string     $label             A human-readable label of the data attached to this meta key.
1396   *     @type string     $description       A description of the data attached to this meta key.
1397   *     @type bool       $single            Whether the meta key has one value per object, or an array of values per object.
1398   *     @type mixed      $default           The default value returned from get_metadata() if no value has been set yet.
1399   *                                         When using a non-single meta key, the default value is for the first entry.
1400   *                                         In other words, when calling get_metadata() with `$single` set to `false`,
1401   *                                         the default value given here will be wrapped in an array.
1402   *     @type callable   $sanitize_callback A function or method to call when sanitizing `$meta_key` data.
1403   *     @type callable   $auth_callback     Optional. A function or method to call when performing edit_post_meta,
1404   *                                         add_post_meta, and delete_post_meta capability checks.
1405   *     @type bool|array $show_in_rest      Whether data associated with this meta key can be considered public and
1406   *                                         should be accessible via the REST API. A custom post type must also declare
1407   *                                         support for custom fields for registered meta to be accessible via REST.
1408   *                                         When registering complex meta values this argument may optionally be an
1409   *                                         array with 'schema' or 'prepare_callback' keys instead of a boolean.
1410   *     @type bool       $revisions_enabled Whether to enable revisions support for this meta_key. Can only be used when the
1411   *                                         object type is 'post'.
1412   * }
1413   * @param string|array $deprecated Deprecated. Use `$args` instead.
1414   * @return bool True if the meta key was successfully registered in the global array, false if not.
1415   *              Registering a meta key with distinct sanitize and auth callbacks will fire those callbacks,
1416   *              but will not add to the global registry.
1417   */
1418  function register_meta( $object_type, $meta_key, $args, $deprecated = null ) {
1419      global $wp_meta_keys;
1420  
1421      if ( ! is_array( $wp_meta_keys ) ) {
1422          $wp_meta_keys = array();
1423      }
1424  
1425      $defaults = array(
1426          'object_subtype'    => '',
1427          'type'              => 'string',
1428          'label'             => '',
1429          'description'       => '',
1430          'default'           => '',
1431          'single'            => false,
1432          'sanitize_callback' => null,
1433          'auth_callback'     => null,
1434          'show_in_rest'      => false,
1435          'revisions_enabled' => false,
1436      );
1437  
1438      // There used to be individual args for sanitize and auth callbacks.
1439      $has_old_sanitize_cb = false;
1440      $has_old_auth_cb     = false;
1441  
1442      if ( is_callable( $args ) ) {
1443          $args = array(
1444              'sanitize_callback' => $args,
1445          );
1446  
1447          $has_old_sanitize_cb = true;
1448      } else {
1449          $args = (array) $args;
1450      }
1451  
1452      if ( is_callable( $deprecated ) ) {
1453          $args['auth_callback'] = $deprecated;
1454          $has_old_auth_cb       = true;
1455      }
1456  
1457      /**
1458       * Filters the registration arguments when registering meta.
1459       *
1460       * @since 4.6.0
1461       *
1462       * @param array  $args        Array of meta registration arguments.
1463       * @param array  $defaults    Array of default arguments.
1464       * @param string $object_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1465       *                            or any other object type with an associated meta table.
1466       * @param string $meta_key    Meta key.
1467       */
1468      $args = apply_filters( 'register_meta_args', $args, $defaults, $object_type, $meta_key );
1469      unset( $defaults['default'] );
1470      $args = wp_parse_args( $args, $defaults );
1471  
1472      // Require an item schema when registering array meta.
1473      if ( false !== $args['show_in_rest'] && 'array' === $args['type'] ) {
1474          if ( ! is_array( $args['show_in_rest'] ) || ! isset( $args['show_in_rest']['schema']['items'] ) ) {
1475              _doing_it_wrong( __FUNCTION__, __( 'When registering an "array" meta type to show in the REST API, you must specify the schema for each array item in "show_in_rest.schema.items".' ), '5.3.0' );
1476  
1477              return false;
1478          }
1479      }
1480  
1481      $object_subtype = ! empty( $args['object_subtype'] ) ? $args['object_subtype'] : '';
1482      if ( $args['revisions_enabled'] ) {
1483          if ( 'post' !== $object_type ) {
1484              _doing_it_wrong( __FUNCTION__, __( 'Meta keys cannot enable revisions support unless the object type supports revisions.' ), '6.4.0' );
1485  
1486              return false;
1487          } elseif ( ! empty( $object_subtype ) && ! post_type_supports( $object_subtype, 'revisions' ) ) {
1488              _doing_it_wrong( __FUNCTION__, __( 'Meta keys cannot enable revisions support unless the object subtype supports revisions.' ), '6.4.0' );
1489  
1490              return false;
1491          }
1492      }
1493  
1494      // If `auth_callback` is not provided, fall back to `is_protected_meta()`.
1495      if ( empty( $args['auth_callback'] ) ) {
1496          if ( is_protected_meta( $meta_key, $object_type ) ) {
1497              $args['auth_callback'] = '__return_false';
1498          } else {
1499              $args['auth_callback'] = '__return_true';
1500          }
1501      }
1502  
1503      // Back-compat: old sanitize and auth callbacks are applied to all of an object type.
1504      if ( is_callable( $args['sanitize_callback'] ) ) {
1505          if ( ! empty( $object_subtype ) ) {
1506              add_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'], 10, 4 );
1507          } else {
1508              add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 3 );
1509          }
1510      }
1511  
1512      if ( is_callable( $args['auth_callback'] ) ) {
1513          if ( ! empty( $object_subtype ) ) {
1514              add_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'], 10, 6 );
1515          } else {
1516              add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
1517          }
1518      }
1519  
1520      if ( array_key_exists( 'default', $args ) ) {
1521          $schema = $args;
1522          if ( is_array( $args['show_in_rest'] ) && isset( $args['show_in_rest']['schema'] ) ) {
1523              $schema = array_merge( $schema, $args['show_in_rest']['schema'] );
1524          }
1525  
1526          $check = rest_validate_value_from_schema( $args['default'], $schema );
1527          if ( is_wp_error( $check ) ) {
1528              _doing_it_wrong( __FUNCTION__, __( 'When registering a default meta value the data must match the type provided.' ), '5.5.0' );
1529  
1530              return false;
1531          }
1532  
1533          if ( ! has_filter( "default_{$object_type}_metadata", 'filter_default_metadata' ) ) {
1534              add_filter( "default_{$object_type}_metadata", 'filter_default_metadata', 10, 5 );
1535          }
1536      }
1537  
1538      // Global registry only contains meta keys registered with the array of arguments added in 4.6.0.
1539      if ( ! $has_old_auth_cb && ! $has_old_sanitize_cb ) {
1540          unset( $args['object_subtype'] );
1541  
1542          $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] = $args;
1543  
1544          return true;
1545      }
1546  
1547      return false;
1548  }
1549  
1550  /**
1551   * Filters into default_{$object_type}_metadata and adds in default value.
1552   *
1553   * @since 5.5.0
1554   *
1555   * @param mixed  $value     Current value passed to filter.
1556   * @param int    $object_id ID of the object metadata is for.
1557   * @param string $meta_key  Metadata key.
1558   * @param bool   $single    If true, return only the first value of the specified `$meta_key`.
1559   *                          This parameter has no effect if `$meta_key` is not specified.
1560   * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1561   *                          or any other object type with an associated meta table.
1562   * @return mixed An array of default values if `$single` is false.
1563   *               The default value of the meta field if `$single` is true.
1564   */
1565  function filter_default_metadata( $value, $object_id, $meta_key, $single, $meta_type ) {
1566      global $wp_meta_keys;
1567  
1568      if ( wp_installing() ) {
1569          return $value;
1570      }
1571  
1572      if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $meta_type ] ) ) {
1573          return $value;
1574      }
1575  
1576      $defaults = array();
1577      foreach ( $wp_meta_keys[ $meta_type ] as $sub_type => $meta_data ) {
1578          foreach ( $meta_data as $_meta_key => $args ) {
1579              if ( $_meta_key === $meta_key && array_key_exists( 'default', $args ) ) {
1580                  $defaults[ $sub_type ] = $args;
1581              }
1582          }
1583      }
1584  
1585      if ( ! $defaults ) {
1586          return $value;
1587      }
1588  
1589      // If this meta type does not have subtypes, then the default is keyed as an empty string.
1590      if ( isset( $defaults[''] ) ) {
1591          $metadata = $defaults[''];
1592      } else {
1593          $sub_type = get_object_subtype( $meta_type, $object_id );
1594          if ( ! isset( $defaults[ $sub_type ] ) ) {
1595              return $value;
1596          }
1597          $metadata = $defaults[ $sub_type ];
1598      }
1599  
1600      if ( $single ) {
1601          $value = $metadata['default'];
1602      } else {
1603          $value = array( $metadata['default'] );
1604      }
1605  
1606      return $value;
1607  }
1608  
1609  /**
1610   * Checks if a meta key is registered.
1611   *
1612   * @since 4.6.0
1613   * @since 4.9.8 The `$object_subtype` parameter was added.
1614   *
1615   * @param string $object_type    Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1616   *                               or any other object type with an associated meta table.
1617   * @param string $meta_key       Metadata key.
1618   * @param string $object_subtype Optional. The subtype of the object type. Default empty string.
1619   * @return bool True if the meta key is registered to the object type and, if provided,
1620   *              the object subtype. False if not.
1621   */
1622  function registered_meta_key_exists( $object_type, $meta_key, $object_subtype = '' ) {
1623      $meta_keys = get_registered_meta_keys( $object_type, $object_subtype );
1624  
1625      return isset( $meta_keys[ $meta_key ] );
1626  }
1627  
1628  /**
1629   * Unregisters a meta key from the list of registered keys.
1630   *
1631   * @since 4.6.0
1632   * @since 4.9.8 The `$object_subtype` parameter was added.
1633   *
1634   * @param string $object_type    Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1635   *                               or any other object type with an associated meta table.
1636   * @param string $meta_key       Metadata key.
1637   * @param string $object_subtype Optional. The subtype of the object type. Default empty string.
1638   * @return bool True if successful. False if the meta key was not registered.
1639   */
1640  function unregister_meta_key( $object_type, $meta_key, $object_subtype = '' ) {
1641      global $wp_meta_keys;
1642  
1643      if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) {
1644          return false;
1645      }
1646  
1647      $args = $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ];
1648  
1649      if ( isset( $args['sanitize_callback'] ) && is_callable( $args['sanitize_callback'] ) ) {
1650          if ( ! empty( $object_subtype ) ) {
1651              remove_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'] );
1652          } else {
1653              remove_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'] );
1654          }
1655      }
1656  
1657      if ( isset( $args['auth_callback'] ) && is_callable( $args['auth_callback'] ) ) {
1658          if ( ! empty( $object_subtype ) ) {
1659              remove_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'] );
1660          } else {
1661              remove_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'] );
1662          }
1663      }
1664  
1665      unset( $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] );
1666  
1667      // Do some clean up.
1668      if ( empty( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) {
1669          unset( $wp_meta_keys[ $object_type ][ $object_subtype ] );
1670      }
1671      if ( empty( $wp_meta_keys[ $object_type ] ) ) {
1672          unset( $wp_meta_keys[ $object_type ] );
1673      }
1674  
1675      return true;
1676  }
1677  
1678  /**
1679   * Retrieves a list of registered metadata args for an object type, keyed by their meta keys.
1680   *
1681   * @since 4.6.0
1682   * @since 4.9.8 The `$object_subtype` parameter was added.
1683   *
1684   * @param string $object_type    Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1685   *                               or any other object type with an associated meta table.
1686   * @param string $object_subtype Optional. The subtype of the object type. Default empty string.
1687   * @return array[] List of registered metadata args, keyed by their meta keys.
1688   */
1689  function get_registered_meta_keys( $object_type, $object_subtype = '' ) {
1690      global $wp_meta_keys;
1691  
1692      if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $object_type ] ) || ! isset( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) {
1693          return array();
1694      }
1695  
1696      return $wp_meta_keys[ $object_type ][ $object_subtype ];
1697  }
1698  
1699  /**
1700   * Retrieves registered metadata for a specified object.
1701   *
1702   * The results include both meta that is registered specifically for the
1703   * object's subtype and meta that is registered for the entire object type.
1704   *
1705   * @since 4.6.0
1706   *
1707   * @param string $object_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1708   *                            or any other object type with an associated meta table.
1709   * @param int    $object_id   ID of the object the metadata is for.
1710   * @param string $meta_key    Optional. Registered metadata key. If not specified, retrieve all registered
1711   *                            metadata for the specified object.
1712   * @return mixed A single value or array of values for a key if specified. An array of all registered keys
1713   *               and values for an object ID if not. False if a given $meta_key is not registered.
1714   */
1715  function get_registered_metadata( $object_type, $object_id, $meta_key = '' ) {
1716      $object_subtype = get_object_subtype( $object_type, $object_id );
1717  
1718      if ( ! empty( $meta_key ) ) {
1719          if ( ! empty( $object_subtype ) && ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) {
1720              $object_subtype = '';
1721          }
1722  
1723          if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) {
1724              return false;
1725          }
1726  
1727          $meta_keys     = get_registered_meta_keys( $object_type, $object_subtype );
1728          $meta_key_data = $meta_keys[ $meta_key ];
1729  
1730          $data = get_metadata( $object_type, $object_id, $meta_key, $meta_key_data['single'] );
1731  
1732          return $data;
1733      }
1734  
1735      $data = get_metadata( $object_type, $object_id );
1736      if ( ! $data ) {
1737          return array();
1738      }
1739  
1740      $meta_keys = get_registered_meta_keys( $object_type );
1741      if ( ! empty( $object_subtype ) ) {
1742          $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( $object_type, $object_subtype ) );
1743      }
1744  
1745      return array_intersect_key( $data, $meta_keys );
1746  }
1747  
1748  /**
1749   * Filters out `register_meta()` args based on an allowed list.
1750   *
1751   * `register_meta()` args may change over time, so requiring the allowed list
1752   * to be explicitly turned off is a warranty seal of sorts.
1753   *
1754   * @access private
1755   * @since 5.5.0
1756   *
1757   * @param array $args         Arguments from `register_meta()`.
1758   * @param array $default_args Default arguments for `register_meta()`.
1759   * @return array Filtered arguments.
1760   */
1761  function _wp_register_meta_args_allowed_list( $args, $default_args ) {
1762      return array_intersect_key( $args, $default_args );
1763  }
1764  
1765  /**
1766   * Returns the object subtype for a given object ID of a specific type.
1767   *
1768   * @since 4.9.8
1769   *
1770   * @param string $object_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
1771   *                            or any other object type with an associated meta table.
1772   * @param int    $object_id   ID of the object to retrieve its subtype.
1773   * @return string The object subtype or an empty string if unspecified subtype.
1774   */
1775  function get_object_subtype( $object_type, $object_id ) {
1776      $object_id      = (int) $object_id;
1777      $object_subtype = '';
1778  
1779      switch ( $object_type ) {
1780          case 'post':
1781              $post_type = get_post_type( $object_id );
1782  
1783              if ( ! empty( $post_type ) ) {
1784                  $object_subtype = $post_type;
1785              }
1786              break;
1787  
1788          case 'term':
1789              $term = get_term( $object_id );
1790              if ( ! $term instanceof WP_Term ) {
1791                  break;
1792              }
1793  
1794              $object_subtype = $term->taxonomy;
1795              break;
1796  
1797          case 'comment':
1798              $comment = get_comment( $object_id );
1799              if ( ! $comment ) {
1800                  break;
1801              }
1802  
1803              $object_subtype = 'comment';
1804              break;
1805  
1806          case 'user':
1807              $user = get_user_by( 'id', $object_id );
1808              if ( ! $user ) {
1809                  break;
1810              }
1811  
1812              $object_subtype = 'user';
1813              break;
1814      }
1815  
1816      /**
1817       * Filters the object subtype identifier for a non-standard object type.
1818       *
1819       * The dynamic portion of the hook name, `$object_type`, refers to the meta object type
1820       * (post, comment, term, user, or any other type with an associated meta table).
1821       *
1822       * Possible hook names include:
1823       *
1824       *  - `get_object_subtype_post`
1825       *  - `get_object_subtype_comment`
1826       *  - `get_object_subtype_term`
1827       *  - `get_object_subtype_user`
1828       *
1829       * @since 4.9.8
1830       *
1831       * @param string $object_subtype Empty string to override.
1832       * @param int    $object_id      ID of the object to get the subtype for.
1833       */
1834      return apply_filters( "get_object_subtype_{$object_type}", $object_subtype, $object_id );
1835  }


Generated : Tue Jan 21 08:20:01 2025 Cross-referenced by PHPXref