wp_update_post()WP 1.0.0

Обновляет запись (пост) в Базе Данных WordPress.

Для того, чтобы функция работала правильно, необходимо указать идентификатор (ID) поста, который будет обновляться.

Функция ожидает экранированные данные. Т.е. нельзя использовать wp_unslash() для полученных $_POST данных. Если это сделать, будет двойное удаление экранируемых слэшей! И наоборот, если мы передаем обычные данные (не экранированные) их нужно экранировать с помощью wp_slash().

Эта функция является оберткой для wp_insert_post().

Отличие этой функции от wp_insert_post() в том, что здесь нет необходимости передавать все данные, можно указать только те, которые нужно обновить, остальные данные будут скопированы из уже имеющихся в базе данных.

Если ревизии записей включены, при обновлении прошлые данные не удаляются, а становятся ревизией. При этом, все связи (с произвольными полями, категориями, метками) переходят к основной/новой записи.

Категории

Категории нужно передватсья в виде массива чисел (ID категорий к которым будет прикреплена запись). Это касается и случаев, когда указывается только одна категория для записи - все равно передаем так: array(1).

Внимание - бесконечный цикл

Если нужно использовать wp_update_post() (обновить запись) во время хука save_post, обязательно сделайте проверку на тип поста - чтобы он не был revision. Дело в том, что когда wp_update_post() используется во время хука save_post (например, для произвольных метаблоков), обычно создается бесконечный цикл. Это получается потому что save_post вызывается дважды, если включены ревизии: первый раз при создании ревизии, второй раз при обновлении основного поста. В результате, цикл замыкается и создаются бесконечное множество ревизий.

Тоже самое происходит во время срабатывания хука edit_attachment, если во время него вызывается функция wp_update_post() с параметром ID, которое относится к вложению (attachment).

Вот пример, показывающий как нужно действовать в ситуации, когда wp_update_post() вызывает ошибку при использовании его во время хука save_post:

add_action( 'save_post', 'my_function' );
function my_function( $post_id ){
	if ( ! wp_is_post_revision( $post_id ) ){
		// удаляем этот хук, чтобы он не создавал бесконечного цикла
		remove_action('save_post', 'my_function');

		// обновляем пост, когда снова вызовется хук save_post
		wp_update_post( $my_args );

		// снова вешаем хук
		add_action('save_post', 'my_function');
	}
}
Будущая публикация поста

Если вы планируете публикацию черновика в будущем и используете для этого функцию wp_update_post(), то функция не будет работать, если не указать параметр $my_post->edit_date = true. WP игнорирует параметр post_date, если обновляется черновик, но не в случае, когда указан параметр edit_date = true.

Заметки

Использует: wp_restore_post_revision()

Работает на основе: wp_insert_post()

Хуков нет.

Возвращает

int|WP_Error.

  • ID обновленной записи — при удачной операции.
  • 0 — если обновить запись не удалось и параметр $wp_error отключен.
  • WP_Error — если обновить запись не удалось и параметр $wp_error включен.

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

wp_update_post( $post, $wp_error, $fire_after_hooks );
$post(массив/объект)

Ассоциативный массив данных, содержащий данные о посте, которые нужно обновить. Ключи массива идентичны полям таблицы wp_posts в Базе Данных WordPress.

Указывать ID в массиве обязательно! (пример: $my_post['ID'] = 37;).

Понимает все параметры которые можно передать wp_insert_post().
По умолчанию: array()

$wp_error(true/false)
true — включает возврат объекта WP_Error при ошибке.
По умолчанию: false
$fire_after_hooks(логический) (WP 5.6)
Нужно ли запускать функцию wp_after_insert_post(), которая запускает хуки в конце работы функции.
По умолчанию: true

Примеры

2

#1 Обновим контент у записи 37

// Создаем массив данных
$my_post = [
	'ID' => 37,
	'post_content' => 'Здесь новый контент записи',
];

// Обновляем данные в БД
wp_update_post( wp_slash( $my_post ) );

Поля, которые можно изменить

Это массив полей, которые содержит любая запись WordPress.

WP_Post Object (
	[ID]                    => 1
	[post_author]           => 1
	[post_date]             => 2010-03-26 09:27:40
	[post_date_gmt]         => 2010-03-26 05:27:40
	[post_content]          => Контент записи...
	[post_title]            => Название записи
	[post_excerpt]          =>
	[post_status]           => publish
	[comment_status]        => open
	[ping_status]           => open
	[post_password]         =>
	[post_name]             => post_name
	[to_ping]               =>
	[pinged]                => http://wp-kama.ru/dopolnitelnyie-knopki
	[post_modified]         => 2014-02-10 10:31:17
	[post_modified_gmt]     => 2014-02-10 06:31:17
	[post_content_filtered] =>
	[post_parent]           => 0
	[guid]                  => http://wp-kama.ru/post_name
	[menu_order]            => 0
	[post_type]             => post
	[post_mime_type]        =>
	[comment_count]         => 41
	[filter]                => raw
)
0

#2 Обновим мета-поля у записи 37

В эту функцию также как и в wp_insert_post() можно указать массив метаполей которые нужно добавить или обновить.

// Создаем массив данных
$my_post = [
	'ID' => 37,
	'meta_input' => [
		'meta_key_1' => 'Meta value 1',
		'meta_key_2' => 'Meta value 2',
	],
];

// Обновляем
wp_update_post( wp_slash($my_post) );

Список изменений

С версии 1.0.0 Введена.
С версии 3.5.0 Added the $wp_error parameter to allow a WP_Error to be returned on failure.
С версии 5.6.0 Added the $fire_after_hooks parameter.

Код wp_update_post() WP 6.4.3

function wp_update_post( $postarr = array(), $wp_error = false, $fire_after_hooks = true ) {
	if ( is_object( $postarr ) ) {
		// Non-escaped post was passed.
		$postarr = get_object_vars( $postarr );
		$postarr = wp_slash( $postarr );
	}

	// First, get all of the original fields.
	$post = get_post( $postarr['ID'], ARRAY_A );

	if ( is_null( $post ) ) {
		if ( $wp_error ) {
			return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) );
		}
		return 0;
	}

	// Escape data pulled from DB.
	$post = wp_slash( $post );

	// Passed post category list overwrites existing category list if not empty.
	if ( isset( $postarr['post_category'] ) && is_array( $postarr['post_category'] )
		&& count( $postarr['post_category'] ) > 0
	) {
		$post_cats = $postarr['post_category'];
	} else {
		$post_cats = $post['post_category'];
	}

	// Drafts shouldn't be assigned a date unless explicitly done so by the user.
	if ( isset( $post['post_status'] )
		&& in_array( $post['post_status'], array( 'draft', 'pending', 'auto-draft' ), true )
		&& empty( $postarr['edit_date'] ) && ( '0000-00-00 00:00:00' === $post['post_date_gmt'] )
	) {
		$clear_date = true;
	} else {
		$clear_date = false;
	}

	// Merge old and new fields with new fields overwriting old ones.
	$postarr                  = array_merge( $post, $postarr );
	$postarr['post_category'] = $post_cats;
	if ( $clear_date ) {
		$postarr['post_date']     = current_time( 'mysql' );
		$postarr['post_date_gmt'] = '';
	}

	if ( 'attachment' === $postarr['post_type'] ) {
		return wp_insert_attachment( $postarr, false, 0, $wp_error );
	}

	// Discard 'tags_input' parameter if it's the same as existing post tags.
	if ( isset( $postarr['tags_input'] ) && is_object_in_taxonomy( $postarr['post_type'], 'post_tag' ) ) {
		$tags      = get_the_terms( $postarr['ID'], 'post_tag' );
		$tag_names = array();

		if ( $tags && ! is_wp_error( $tags ) ) {
			$tag_names = wp_list_pluck( $tags, 'name' );
		}

		if ( $postarr['tags_input'] === $tag_names ) {
			unset( $postarr['tags_input'] );
		}
	}

	return wp_insert_post( $postarr, $wp_error, $fire_after_hooks );
}