delete_metadata

The timeline below displays how wordpress function delete_metadata has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.2

/**
 * Deletes metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 *                           or any other object type with an associated meta table.
 * @param int    $object_id  ID of the object metadata is for.
 * @param string $meta_key   Metadata key.
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar.
 *                           If specified, only delete metadata entries with this value.
 *                           Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null`, `false`, or an empty string to skip this check.
 *                           (For backward compatibility, it is not possible to pass an empty string
 *                           to delete those entries with an empty string for a value.)
 *                           Default empty string.
 * @param bool   $delete_all Optional. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete
 *                           matching metadata entries for the specified object_id. Default false.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' === $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Short-circuits deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     * Returning a non-null value will effectively short-circuit the function.
     *
     * Possible hook names include:
     *
     *  - `delete_post_metadata`
     *  - `delete_comment_metadata`
     *  - `delete_term_metadata`
     *  - `delete_user_metadata`
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  ID of the object metadata is for.
     * @param string    $meta_key   Metadata key.
     * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(' AND meta_value = %s', $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     *
     * Possible hook names include:
     *
     *  - `delete_post_meta`
     *  - `delete_comment_meta`
     *  - `delete_term_meta`
     *  - `delete_user_meta`
     *
     * @since 3.1.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' === $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . ' )';
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        $data = (array) $object_ids;
    } else {
        $data = array($object_id);
    }
    wp_cache_delete_multiple($data, $meta_type . '_meta');
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     *
     * Possible hook names include:
     *
     *  - `deleted_post_meta`
     *  - `deleted_comment_meta`
     *  - `deleted_term_meta`
     *  - `deleted_user_meta`
     *
     * @since 2.9.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' === $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 6.1

/**
 * Deletes metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 *                           or any other object type with an associated meta table.
 * @param int    $object_id  ID of the object metadata is for.
 * @param string $meta_key   Metadata key.
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar.
 *                           If specified, only delete metadata entries with this value.
 *                           Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null`, `false`, or an empty string to skip this check.
 *                           (For backward compatibility, it is not possible to pass an empty string
 *                           to delete those entries with an empty string for a value.)
 * @param bool   $delete_all Optional. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete
 *                           matching metadata entries for the specified object_id. Default false.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' === $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Short-circuits deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     * Returning a non-null value will effectively short-circuit the function.
     *
     * Possible hook names include:
     *
     *  - `delete_post_metadata`
     *  - `delete_comment_metadata`
     *  - `delete_term_metadata`
     *  - `delete_user_metadata`
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  ID of the object metadata is for.
     * @param string    $meta_key   Metadata key.
     * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(' AND meta_value = %s', $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     *
     * Possible hook names include:
     *
     *  - `delete_post_meta`
     *  - `delete_comment_meta`
     *  - `delete_term_meta`
     *  - `delete_user_meta`
     *
     * @since 3.1.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' === $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . ' )';
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        $data = (array) $object_ids;
    } else {
        $data = array($object_id);
    }
    wp_cache_delete_multiple($data, $meta_type . '_meta');
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     *
     * Possible hook names include:
     *
     *  - `deleted_post_meta`
     *  - `deleted_comment_meta`
     *  - `deleted_term_meta`
     *  - `deleted_user_meta`
     *
     * @since 2.9.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' === $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 5.9

/**
 * Deletes metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 *                           or any other object type with an associated meta table.
 * @param int    $object_id  ID of the object metadata is for.
 * @param string $meta_key   Metadata key.
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar.
 *                           If specified, only delete metadata entries with this value.
 *                           Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null`, `false`, or an empty string to skip this check.
 *                           (For backward compatibility, it is not possible to pass an empty string
 *                           to delete those entries with an empty string for a value.)
 * @param bool   $delete_all Optional. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete
 *                           matching metadata entries for the specified object_id. Default false.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' === $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Short-circuits deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     * Returning a non-null value will effectively short-circuit the function.
     *
     * Possible hook names include:
     *
     *  - `delete_post_metadata`
     *  - `delete_comment_metadata`
     *  - `delete_term_metadata`
     *  - `delete_user_metadata`
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  ID of the object metadata is for.
     * @param string    $meta_key   Metadata key.
     * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(' AND meta_value = %s', $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     *
     * Possible hook names include:
     *
     *  - `delete_post_meta`
     *  - `delete_comment_meta`
     *  - `delete_term_meta`
     *  - `delete_user_meta`
     *
     * @since 3.1.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' === $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . ' )';
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     *
     * Possible hook names include:
     *
     *  - `deleted_post_meta`
     *  - `deleted_comment_meta`
     *  - `deleted_term_meta`
     *  - `deleted_user_meta`
     *
     * @since 2.9.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' === $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 5.5

/**
 * Deletes metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 *                           or any other object type with an associated meta table.
 * @param int    $object_id  ID of the object metadata is for.
 * @param string $meta_key   Metadata key.
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar.
 *                           If specified, only delete metadata entries with this value.
 *                           Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null`, `false`, or an empty string to skip this check.
 *                           (For backward compatibility, it is not possible to pass an empty string
 *                           to delete those entries with an empty string for a value.)
 * @param bool   $delete_all Optional. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete
 *                           matching metadata entries for the specified object_id. Default false.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' === $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Short-circuits deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     * Returning a non-null value will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  ID of the object metadata is for.
     * @param string    $meta_key   Metadata key.
     * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(' AND meta_value = %s', $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     *
     * @since 3.1.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value. Serialized if non-scalar.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' === $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . ' )';
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta object type
     * (post, comment, term, user, or any other type with an associated meta table).
     *
     * @since 2.9.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value. Serialized if non-scalar.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' === $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 5.4

/**
 * Deletes metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 *                           or any other object type with an associated meta table.
 * @param int    $object_id  ID of the object metadata is for.
 * @param string $meta_key   Metadata key.
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar.
 *                           If specified, only delete metadata entries with this value.
 *                           Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null`, `false`, or an empty string to skip this check.
 *                           (For backward compatibility, it is not possible to pass an empty string
 *                           to delete those entries with an empty string for a value.)
 * @param bool   $delete_all Optional. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete
 *                           matching metadata entries for the specified object_id. Default false.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  ID of the object metadata is for.
     * @param string    $meta_key   Metadata key.
     * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(' AND meta_value = %s', $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 3.1.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value. Serialized if non-scalar.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . ' )';
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 2.9.0
     *
     * @param string[] $meta_ids    An array of metadata entry IDs to delete.
     * @param int      $object_id   ID of the object metadata is for.
     * @param string   $meta_key    Metadata key.
     * @param mixed    $_meta_value Metadata value. Serialized if non-scalar.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param string[] $meta_ids An array of metadata entry IDs to delete.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 5.2

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null`, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(' AND meta_value = %s', $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids    An array of metadata entry IDs to delete.
     * @param int    $object_id   Object ID.
     * @param string $meta_key    Meta key.
     * @param mixed  $_meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . ' )';
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids    An array of deleted metadata entry IDs.
     * @param int    $object_id   Object ID.
     * @param string $meta_key    Meta key.
     * @param mixed  $_meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 5.1

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null`, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(' AND meta_value = %s', $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . ' )';
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 9.9

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 9.3

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: .20

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 9.2

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: .10

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, term, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 8.6

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 8.2

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $value_clause = '';
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $value_clause = $wpdb->prepare(" AND meta_value = %s", $meta_value);
        }
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s {$value_clause}", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: .10

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 6.3

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $value_clause = '';
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $value_clause = $wpdb->prepare(" AND meta_value = %s", $meta_value);
        }
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s {$value_clause}", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: .20

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 6.2

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $value_clause = '';
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $value_clause = $wpdb->prepare(" AND meta_value = %s", $meta_value);
        }
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s {$value_clause}", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: .11

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 4.6

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filters whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $value_clause = '';
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $value_clause = $wpdb->prepare(" AND meta_value = %s", $meta_value);
        }
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s {$value_clause}", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 5.4

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $value_clause = '';
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $value_clause = $wpdb->prepare(" AND meta_value = %s", $meta_value);
        }
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s {$value_clause}", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: .30

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 5.3

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $value_clause = '';
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $value_clause = $wpdb->prepare(" AND meta_value = %s", $meta_value);
        }
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s {$value_clause}", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: .20

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 5.2

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $value_clause = '';
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $value_clause = $wpdb->prepare(" AND meta_value = %s", $meta_value);
        }
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s {$value_clause}", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: .14

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value));
        } else {
            $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 4.5

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $value_clause = '';
        if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
            $value_clause = $wpdb->prepare(" AND meta_value = %s", $meta_value);
        }
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s {$value_clause}", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 4.3

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id  ID of the object metadata is for
 * @param string $meta_key   Metadata key
 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
 *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
 *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
 *                           it is not possible to pass an empty string to delete those entries with an empty string
 *                           for a value.)
 * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
 *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
 *                           the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ('' !== $meta_value && null !== $meta_value && false !== $meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 4.1

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
 * @param int $object_id ID of the object metadata is for
 * @param string $meta_key Metadata key
 * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete metadata entries
 * 		with this value. Otherwise, delete all entries with the specified meta_key.
 * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries
 * 		for all objects, ignoring the specified object_id. Otherwise, only delete matching
 * 		metadata entries for the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ($meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, `$meta_type`, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 4.0

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 * @uses $wpdb WordPress database object for queries.
 *
 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
 * @param int $object_id ID of the object metadata is for
 * @param string $meta_key Metadata key
 * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete metadata entries
 * 		with this value. Otherwise, delete all entries with the specified meta_key.
 * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries
 * 		for all objects, ignoring the specified object_id. Otherwise, only delete matching
 * 		metadata entries for the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    global $wpdb;
    if (!$meta_type || !$meta_key || !is_numeric($object_id) && !$delete_all) {
        return false;
    }
    $object_id = absint($object_id);
    if (!$object_id && !$delete_all) {
        return false;
    }
    $table = _get_meta_table($meta_type);
    if (!$table) {
        return false;
    }
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, $meta_type, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ($meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, $meta_type, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, $meta_type, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 3.9

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 * @uses $wpdb WordPress database object for queries.
 *
 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
 * @param int $object_id ID of the object metadata is for
 * @param string $meta_key Metadata key
 * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete metadata entries
 * 		with this value. Otherwise, delete all entries with the specified meta_key.
 * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries
 * 		for all objects, ignoring the specified object_id. Otherwise, only delete matching
 * 		metadata entries for the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    if (!$meta_type || !$meta_key) {
        return false;
    }
    if (!($object_id = absint($object_id)) && !$delete_all) {
        return false;
    }
    if (!$table = _get_meta_table($meta_type)) {
        return false;
    }
    global $wpdb;
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    /**
     * Filter whether to delete metadata of a specific type.
     *
     * The dynamic portion of the hook, $meta_type, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|bool $delete     Whether to allow metadata deletion of the given type.
     * @param int       $object_id  Object ID.
     * @param string    $meta_key   Meta key.
     * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
     * @param bool      $delete_all Whether to delete the matching metadata entries
     *                              for all objects, ignoring the specified $object_id.
     *                              Default false.
     */
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ($meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
    }
    /**
     * Fires immediately before deleting metadata of a specific type.
     *
     * The dynamic portion of the hook, $meta_type, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 3.1.0
     *
     * @param array  $meta_ids   An array of metadata entry IDs to delete.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately before deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of post metadata entry IDs to delete.
         */
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    /**
     * Fires immediately after deleting metadata of a specific type.
     *
     * The dynamic portion of the hook name, $meta_type, refers to the meta
     * object type (comment, post, or user).
     *
     * @since 2.9.0
     *
     * @param array  $meta_ids   An array of deleted metadata entry IDs.
     * @param int    $object_id  Object ID.
     * @param string $meta_key   Meta key.
     * @param mixed  $meta_value Meta value.
     */
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        /**
         * Fires immediately after deleting metadata for a post.
         *
         * @since 2.9.0
         *
         * @param array $meta_ids An array of deleted post metadata entry IDs.
         */
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}

WordPress Version: 3.7

/**
 * Delete metadata for the specified object.
 *
 * @since 2.9.0
 * @uses $wpdb WordPress database object for queries.
 * @uses do_action() Calls 'deleted_{$meta_type}_meta' after deleting with meta_id of
 * 		deleted metadata entries, object ID, meta key, and meta value
 *
 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
 * @param int $object_id ID of the object metadata is for
 * @param string $meta_key Metadata key
 * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete metadata entries
 * 		with this value. Otherwise, delete all entries with the specified meta_key.
 * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries
 * 		for all objects, ignoring the specified object_id. Otherwise, only delete matching
 * 		metadata entries for the specified object_id.
 * @return bool True on successful delete, false on failure.
 */
function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false)
{
    if (!$meta_type || !$meta_key) {
        return false;
    }
    if (!($object_id = absint($object_id)) && !$delete_all) {
        return false;
    }
    if (!$table = _get_meta_table($meta_type)) {
        return false;
    }
    global $wpdb;
    $type_column = sanitize_key($meta_type . '_id');
    $id_column = ('user' == $meta_type) ? 'umeta_id' : 'meta_id';
    // expected_slashed ($meta_key)
    $meta_key = wp_unslash($meta_key);
    $meta_value = wp_unslash($meta_value);
    $check = apply_filters("delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all);
    if (null !== $check) {
        return (bool) $check;
    }
    $_meta_value = $meta_value;
    $meta_value = maybe_serialize($meta_value);
    $query = $wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s", $meta_key);
    if (!$delete_all) {
        $query .= $wpdb->prepare(" AND {$type_column} = %d", $object_id);
    }
    if ($meta_value) {
        $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value);
    }
    $meta_ids = $wpdb->get_col($query);
    if (!count($meta_ids)) {
        return false;
    }
    if ($delete_all) {
        $object_ids = $wpdb->get_col($wpdb->prepare("SELECT {$type_column} FROM {$table} WHERE meta_key = %s", $meta_key));
    }
    do_action("delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        do_action('delete_postmeta', $meta_ids);
    }
    $query = "DELETE FROM {$table} WHERE {$id_column} IN( " . implode(',', $meta_ids) . " )";
    $count = $wpdb->query($query);
    if (!$count) {
        return false;
    }
    if ($delete_all) {
        foreach ((array) $object_ids as $o_id) {
            wp_cache_delete($o_id, $meta_type . '_meta');
        }
    } else {
        wp_cache_delete($object_id, $meta_type . '_meta');
    }
    do_action("deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value);
    // Old-style action.
    if ('post' == $meta_type) {
        do_action('deleted_postmeta', $meta_ids);
    }
    return true;
}