# Функция WP_UPDATE_POST() │ WP 1.0.0
Функция wp_update_post()
обновляет пост в базе данных WordPress с новыми данными. Чтобы функция работала корректно, необходимо передать ID поста, который нужно обновить.
Функция ожидает, что данные будут экранированы (подготовлены для использования). То есть, нельзя использовать функцию wp_unslash()
для данных, полученных из $_POST
. Если это сделать, возникнет двойное экранирование! Если же мы передаем данные без экранирования, их нужно подготовить с помощью wp_slash()
.
Эта функция является оберткой для wp_insert_post()
.
Основное отличие между wp_update_post()
и wp_insert_post()
заключается в том, что не нужно передавать все данные; можно указать лишь те, которые необходимо обновить. Остальные данные будут взяты из базы данных.
Если включены ревизии постов, обновление не удаляет предыдущие данные, а создает новую ревизию. При этом все связи (с пользовательскими полями, категориями, тегами) будут перенесены в основной или новый пост.
Дата не обязательно должна быть установлена для черновиков. Вы можете установить дату, и она не будет изменена.
## КАТЕГОРИИ
Категории нужно передавать в виде массива целых чисел (ID категории, к которой будет прикреплён пост). Это необходимо даже если к посту назначена только одна категория, например: array(1)
.
## БЕССКОНЕЧНЫЙ ЦИКЛ
Если необходимо использовать wp_update_post()
внутри хука save_post
, убедитесь, что post_type
не является ревизией. Дело в том, что когда wp_update_post()
используется внутри хука save_post
(например, для обновления пользовательского метабокса), обычно возникает бесконечный цикл. Это происходит потому, что save_post
вызывается дважды если ревизии включены: в первый раз при создании ревизии и второй раз при обновлении оригинального поста. В результате получается самоуничтожающийся цикл и создание бесконечного числа ревизий.
Та же проблема возникает, когда wp_update_post()
используется внутри хука edit_attachment
, когда параметр ID относится к прикрепляемому файлу.
Вот пример того, как избежать бесконечного цикла при использовании wp_update_post()
внутри хука save_post
:
```php
add_action( 'save_post', 'my_function' );
function my_function( $post_id ) {
if ( ! wp_is_post_revision( $post_id ) ) {
// Убираем этот хуки, чтобы избежать бесконечного цикла
remove_action( 'save_post', __FUNCTION__ );
// Обновляем пост, когда хук save_post вызывается снова
wp_update_post( $my_args );
// Возвращаем хук обратно
add_action( 'save_post', __FUNCTION__ );
}
}
ПУБЛИКАЦИЯ ЧЕРНОВИКА В БУДУЩЕМ
Если вы планируете опубликовать черновик в будущем и используете функцию wp_update_post()
для этого, функция не сработает, если не указать edit_date = true
. Иными словами, WordPress проигнорирует post_date
, когда обновляет черновики, если edit_date
не установлен в true.
Возвращаемое значение
Int|WP_Error
- ID поста — когда пост успешно обновлен.
0
— если произошла ошибка и параметр$wp_error
отключен.- Объект
WP_Error
— если произошла ошибка и параметр$wp_error
включен.
ИСПОЛЬЗОВАНИЕ
wp_update_post( $postarr, $wp_error );
Параметры:
-
$postarr
(array/object) — Данные поста в виде массива. Ключи массива соответствуют полям таблицыwp_posts
в базе данных WordPress.Для списка доступных ключей массива смотрите описание функции
wp_insert_post()
.Обратите внимание, что
$postarr['ID']
является обязател��ным полем. -
$wp_error
(true/false) — Разрешить возвращениеWP_Error
в случае ошибки. По умолчанию:false
.
ПРИМЕРЫ
Перед использованием функции необходимо собрать массив данных, который затем будет передан в качестве параметра. Этот массив должен содержать данные, которые вы хотите обновить.
Пример 1: Обновление содержимого поста с ID 37
// Создаем массив данных
$my_post = array();
$my_post['ID'] = 37;
$my_post['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://example.com/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://example.com/post_name
[menu_order] => 0
[post_type] => post
[post_mime_type] =>
[comment_count] => 41
[filter] => raw
)
Пример 2: Обновление мета-полей поста с ID 37
В этой функции, как и в wp_insert_post()
, вы можете указать массив мета-полей, которые нужно добавить или обновить.
// Создаем массив данных
$my_post = [
'ID' => 37,
'meta_input' => [
'meta_key_1' => 'Значение мета поля 1',
'meta_key_2' => 'Значение мета поля 2',
],
];
// Обновляем
wp_update_post( wp_slash($my_post) );
ИСТОРИЯ ИЗМЕНЕНИЙ
С версии 1.0.0 — Функция была добавлена.
С версии 3.5.0 — Добавлен параметр $wp_error
, чтобы разрешить возвращение WP_Error
в случае ошибки.
С версии 5.6.0 — Добавлен параметр $fire_after_hooks
.
SV_UPDATE_POST() Код
function wp_update_post( $postarr = array(), $wp_error = false, $fire_after_hooks = true ) {
if ( is_object( $postarr ) ) {
// Неэкранированный пост был передан.
$postarr = get_object_vars( $postarr );
$postarr = wp_slash( $postarr );
}
// Сначала получаем все оригинальные поля.
$post = get_post( $postarr['ID'], ARRAY_A );
if ( is_null( $post ) ) {
if ( $wp_error ) {
return new WP_Error( 'invalid_post', __( 'Неверный ID поста.' ) );
}
return 0;
}
// Экранируем данные, полученные из БД.
$post = wp_slash( $post );
// Список категорий поста, переданный с постом, заменяет существующий в случае, если он не пуст.
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'];
}
// Черновики не должны иметь дату, если это не сделано пользователем явно.
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;
}
// Объединяем старые и новые поля, новые поля заменяют старые.
$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 );
}
// Отбрасываем параметр 'tags_input', если он такой же, как существующие теги поста.
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 );
}
Эта структура статьи с использованием разметки Markdown обеспечит удобное восприятие и поможет начинающим пользователям WordPress понять, как использовать функцию wp_update_post()
в своей работе.