Функция WP_UPDATE_POST() в WordPress: обновление поста │ WP 1.0.0

# Функция 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() в своей работе.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *