WordPress как на ладони
wordpress jino

update_metadata() WP 2.9

Обновляет метаданные для указанного объекта (пост, юзер, коммент). Если указанных данных не найдено, то они будут добавлены, как новые.

Хуки из функции:
Возвращает

true или false, в зависимости, удалось или нет обновить/добавить данные.

Использование

update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_value );
$meta_type(строка) (обязательный)
Тип объекта метаданных которого обновляем. Например: comment, post, or user
По умолчанию: нет
$object_id(число) (обязательный)
ID объекта метаданные которого обновляем. Например, для поста, это будет ID поста.
По умолчанию: нет
$meta_key(строка) (обязательный)
Ключ (название) метаданных.
По умолчанию: нет
$meta_value(строка) (обязательный)

Новое значение которое нужно изменить/добавить.

Если указать значение, которое уже записано в метаполе (такое же), то функция не будет делать лишних запросов по обновлению старого значения на такое же новое, а просто прервет работу...

По умолчанию: нет

$prev_value(строка)
Предыдущее значение. Если указать, обновит только данные совпадающие в этим значением, а не все метаданных с указанным в $meta_key ключом.
По умолчанию: ''

Примеры

#1. Базовый пример, показывающий как обновить метаданные у поста.

Точный аналог работы функции update_post_meta(). Обновим метаданные с ключом key_1, у поста 76 - изменим значения "грустный" на "веселый":

update_metadata('post', 76, 'key_1', 'веселый', 'грустный');

Код update metadata: wp-includes/meta.php WP 4.9

<?php
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;
	}

	$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 );

	/**
	 * Filters whether to update 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 $check      Whether to allow updating metadata for 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 mixed     $prev_value Optional. If specified, only update existing
	 *                              metadata entries with the specified 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($meta_type, $object_id, $meta_key);
		if ( 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, `$meta_type`, refers to the meta
		 * object type (comment, post, or user).
		 *
		 * @since 2.9.0
		 *
		 * @param int    $meta_id    ID of the metadata entry to update.
		 * @param int    $object_id  Object ID.
		 * @param string $meta_key   Meta key.
		 * @param mixed  $meta_value Meta 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  Object ID.
			 * @param string $meta_key   Meta key.
			 * @param mixed  $meta_value Meta value.
			 */
			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, `$meta_type`, refers to the meta
		 * object type (comment, post, or user).
		 *
		 * @since 2.9.0
		 *
		 * @param int    $meta_id    ID of updated metadata entry.
		 * @param int    $object_id  Object ID.
		 * @param string $meta_key   Meta key.
		 * @param mixed  $meta_value Meta 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  Object ID.
			 * @param string $meta_key   Meta key.
			 * @param mixed  $meta_value Meta value.
			 */
			do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
		}
	}

	return true;
}

Cвязанные функции

Из метки: metadata (метаданные)

Еще из раздела: Метаданные

update_metadata 8 комментариев
  • JamaRolex

    Здравствуйте Тимур, Вы не могли бы мне поточней обьяснить как работатет последний аргумент функции "$prev_value", что конкретно мне вписать в него, могу ли я просто указать ключ ? или мне сначала надо каким то образом вытащить $prev_value, типа
    $prev_value = get_post_meta( $post_id, 'prev_value'); ?

    Спасибо за ранее за ответ, да и за сайт спасибо smile

    Ответить3.6 года назад #
    • Kama4558

      Это не обязательный параметр и нужен он, когда существуют несколько полей с одинаковым ключом и разными значениями, и когда нужно обновить одно из таких полей. Тогда указывается ключ и значение поля, и именно оно будет обновляться.

      Да, значение нужно будет скорее всего получить с помощью get_post_meta().

      Ответить3.6 года назад #
  • JamaRolex

    Не хочу Вам навязываться, но не могли бы вы мне посоветовать, я почти закончил систему тестирования на WP, и по сути она у меня работает, но так как у нас корпоративная Система Тестирования, мне надо сохранить результаты прохождения теста как в пользователя так и в сам тест, вот тут у меня и возникла проблема, я решил сделать так:
    В Тесте создаю поле с ключём: ans_user и в него сливаю данные по типу № теста:ID Пользователя: Результат ответа(Верен не верен). В целом сторка выгляди так
    "88:1:1" .
    В Ползователе создаю поле quest : "№ теста:ID теста: Результат ответа(Верен не верен)". Вид строки идентичный(только цифры)

    Далее я расчитывал вытащить эти данные ввиде строки и создать массив с помощью
    explode(':', get_post_meta() ).
    Теперь вопрос, как мне правильней сделать, делать это в одной строке или в нескольких ключах, но так же надо учитывать что о прохождение теста В Один тест будет записываться прохождение многих человек. Надеюсь Вы поняли меня smile Спасибо за прошлый ответ.

    Ответить3.6 года назад #
    • Kama4558

      Если я правильно понял.

      1. Можно создать дополнительную таблицу: ID пользователя (индексированный столбец), ID теста (поста) (индексированный столбец), данные прохождения теста.

      2. Если возиться с доп таблицей нет желания и там не большие объемы. Можно произвольные поля задействовать: в одно поле писать массив: ID пользователя => результаты прохождения теста. Но в этом случае быстро проверить и найти результаты ответов нужного пользователя будет немного затруднительно, через PHP придется обрабатывать: получать данные поля, делать из них массив и в нем уже искать пользователя и результаты. В прочем это тоже вариант, если пользователей не много убдет. Тут я бы порекомендовал сразу записывать в произвольное поле массив. Он сам будет серриализоватся при записи и десерриализоваться при получении, т.е. без всяких explode.

      3. Создавать разные произвольные поля, выгодно только в том случае, если нужно будет быстро искать проходил ли пользователь тест и какие результаты: создаем поля с ключами ans_user_{user_ID}, так по ID пользователя можно будет быстро получить поле, проверить есть ли оно. (впрочем второй вариант это не исключает, только там в php нужно будет обрабатывать). Также в этом случае нужно учесть, что количество произвольный полей у поста ограничено (насколько я знаю, не сталкивался). Допустим, 200 пользователей ответят - это 200 произвольных полей с разными ключами, по моему WP этого не допустит. Также все эти поля будут искаться и выводиться в админке на страницах постов, админка будет грузить. Чтобы этого не было можно добавить к ключу поля _ - _ans_user_{user_ID}.

      4. А еще, можно в метаданные пользователя (произвольные поля для пользователя) записывать все тесты которые он прошел. А произвольные поля поста (теста) вообще не трогать. Писать только у пользователя в данных все...

      Подведу итог рассуждений:
      Если предполагается, что не много пользователей будут проходить тест, скажем не больше 100, то, думаю, 2-й или 4-й вариант подойдут. Если их будет больше, то лучше создать доп таблицу или использовать 4-й вариант. 3-й вариант я бы не рекомендовал вообще, не грамотный он какой-то и админку грузить будет, произвольные опля все таки для всех постов используются, а тут только для одного или нескольких тестов нужно...

      В общем, смотрите на то как потом эти данные нужно будет обрабатывать, что проверять и как выводить...

      Ответить3.6 года назад #
      • JamaRolex

        Спасибо большое вам. Вы мне прям прозреть помогли smile, то есть по вашим словам если я отправлю в мета поле данные ввиде массива они сохраняться в сериализированном ввиде, этого я не знал, спасибо вам, создавать дополнительную Таблицу, это вариант конечно, но я любитель родных возможностей WP(она действительно крутая). 3 вариант это будет просто HARDCOREsmile. По поводу 4-го варианта, да вы правы можно и только в пользователя записать, только потом с обработкой этих данных я замучаюсь + нужно будет делать миллионы запросов что бы узнавать все свойства одного Теста всех тестов Одного пользователя. Спасибо вам smile. Вы мне действительно помогли smile. По поводу вашего сайта, у вас тут супер, но вам не хватаете одной вещи, мне бы как девелоперу, а таких тут много(я думаю), было бы удобней что бы когда в "преследующую" панель поиска вводил текст или название функции он бы раскрылся ajax'ом в виде списка и я выбрал бы нужную, а если таковой нет тогда будь добр нажми enter и и смотри как нашёл яндекс. И "Связанные Функции" мне кажеться было бы правильней как то в право засунуть, но в целом ваш сайт очень крутой, без него я бы наверно и не знал WP как сейчас знаю, спасибо вам и за сайт и за помощь smile

        Ответить3.6 года назад #
  • Ильдар

    Добрый день.

    Судя по коду функции, передавать в качестве $object_id массив смысла нет, она вернет false

    Ответитьгод назад #
    • Kama4558

      Поправил описание, спасибо. Да, туда только число можно передавать...

      Ответитьгод назад #
  • Сергей

    Здравствуй, Kama. Как изменить порядок отображения мета вначале статьи после заголовка. По умолчанию показывается дата, автор, категория.

    Мне нужно категория, дата, автор

    Ответить4 месяца назад #

Здравствуйте, !

Ваш комментарий