WordPress Version: 6.2
/**
* Updates metadata for the specified object. If no value already exists for the specified object
* ID and metadata key, the metadata will be added.
*
* @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 Metadata value. Must be serializable if non-scalar.
* @param mixed $prev_value Optional. Previous value to check before updating.
* If specified, only update existing metadata entries with
* this value. Otherwise, update all entries. Default empty string.
* @return int|bool The new meta field ID if a field with the given key didn't exist
* and was therefore added, true on successful update,
* false on failure or if the value passed to the function
* is the same as the one that is already in the database.
*/
function update_metadata($meta_type, $object_id, $meta_key, $meta_value, $prev_value = '')
{
global $wpdb;
if (!$meta_type || !$meta_key || !is_numeric($object_id)) {
return false;
}
$object_id = absint($object_id);
if (!$object_id) {
return false;
}
$table = _get_meta_table($meta_type);
if (!$table) {
return false;
}
$meta_subtype = get_object_subtype($meta_type, $object_id);
$column = sanitize_key($meta_type . '_id');
$id_column = ('user' === $meta_type) ? 'umeta_id' : 'meta_id';
// expected_slashed ($meta_key)
$raw_meta_key = $meta_key;
$meta_key = wp_unslash($meta_key);
$passed_value = $meta_value;
$meta_value = wp_unslash($meta_value);
$meta_value = sanitize_meta($meta_key, $meta_value, $meta_type, $meta_subtype);
/**
* Short-circuits updating 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:
*
* - `update_post_metadata`
* - `update_comment_metadata`
* - `update_term_metadata`
* - `update_user_metadata`
*
* @since 3.1.0
*
* @param null|bool $check Whether to allow updating metadata for 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 mixed $prev_value Optional. Previous value to check before updating.
* If specified, only update existing metadata entries with
* this value. Otherwise, update all entries.
*/
$check = apply_filters("update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value);
if (null !== $check) {
return (bool) $check;
}
// Compare existing value to new value if no prev value given and the key exists only once.
if (empty($prev_value)) {
$old_value = get_metadata_raw($meta_type, $object_id, $meta_key);
if (is_countable($old_value) && count($old_value) === 1) {
if ($old_value[0] === $meta_value) {
return false;
}
}
}
$meta_ids = $wpdb->get_col($wpdb->prepare("SELECT {$id_column} FROM {$table} WHERE meta_key = %s AND {$column} = %d", $meta_key, $object_id));
if (empty($meta_ids)) {
return add_metadata($meta_type, $object_id, $raw_meta_key, $passed_value);
}
$_meta_value = $meta_value;
$meta_value = maybe_serialize($meta_value);
$data = compact('meta_value');
$where = array($column => $object_id, 'meta_key' => $meta_key);
if (!empty($prev_value)) {
$prev_value = maybe_serialize($prev_value);
$where['meta_value'] = $prev_value;
}
foreach ($meta_ids as $meta_id) {
/**
* Fires immediately before updating 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:
*
* - `update_post_meta`
* - `update_comment_meta`
* - `update_term_meta`
* - `update_user_meta`
*
* @since 2.9.0
*
* @param int $meta_id ID of the metadata entry to update.
* @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("update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value);
if ('post' === $meta_type) {
/**
* Fires immediately before updating a post's metadata.
*
* @since 2.9.0
*
* @param int $meta_id ID of metadata entry to update.
* @param int $object_id Post ID.
* @param string $meta_key Metadata key.
* @param mixed $meta_value Metadata value. This will be a PHP-serialized string representation of the value
* if the value is an array, an object, or itself a PHP-serialized string.
*/
do_action('update_postmeta', $meta_id, $object_id, $meta_key, $meta_value);
}
}
$result = $wpdb->update($table, $data, $where);
if (!$result) {
return false;
}
wp_cache_delete($object_id, $meta_type . '_meta');
foreach ($meta_ids as $meta_id) {
/**
* Fires immediately after updating 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:
*
* - `updated_post_meta`
* - `updated_comment_meta`
* - `updated_term_meta`
* - `updated_user_meta`
*
* @since 2.9.0
*
* @param int $meta_id ID of updated metadata entry.
* @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("updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value);
if ('post' === $meta_type) {
/**
* Fires immediately after updating a post's metadata.
*
* @since 2.9.0
*
* @param int $meta_id ID of updated metadata entry.
* @param int $object_id Post ID.
* @param string $meta_key Metadata key.
* @param mixed $meta_value Metadata value. This will be a PHP-serialized string representation of the value
* if the value is an array, an object, or itself a PHP-serialized string.
*/
do_action('updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value);
}
}
return true;
}