✅ Новости WEB и WordPress, темы, плагины. Здесь мы делимся советами и лучшими решениями для веб-сайтов.

Сохранение статуса записи при обновлении записи WordPress

27

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

Однако есть одна проблема:

Скажем, у вас есть сообщение, которое в настоящее время опубликовано (то есть его «post_status» установлено на «опубликовать»), но когда вы обновляете сообщение через wp_update_post, его атрибут post_status устанавливается на «будущее».

Другими словами, всякий раз, когда вы программно обновляете публикацию, статус публикации устанавливается на «Запланировано» (в соответствии с пользовательским интерфейсом) и «Будущее» (в соответствии со столбцом базы данных).

Так что дает?

Статус публикации при обновлении

Вообще говоря, я не сторонник того, чтобы заставить что-то работать, выяснить, что это работает, и перейти к следующей задаче, если я точно не понимаю, почему это не сработало [как ожидалось] в первую очередь.

Это не означает, что нет случаев, когда ограничения вызывали это (по крайней мере, в рабочее время). Но если сейчас полночь, я исправляю ошибку, а потом я не совсем уверен, что понимаю, почему она, по-видимому, была сломана в первую очередь, я мог бы также остаться и выяснить это, верно?

Это похоже на предвзятость невозвратных издержек в версии программиста .

В любом случае, как указано выше, вот суть проблемы:

  1. Данная запись существует в WordPress.
  2. Когда пользователь удаляется, система проверяет, существует ли определенный контент в данном сообщении, и если да, то удаляет его.
  3. Затем сообщение обновляется с помощью функции WordPress API.

Все работает отлично, но есть проблема: всякий раз, когда сообщение программно обновляется, оно помечает статус сообщения как «будущий» в базе данных, в конечном итоге устанавливая элемент строки сообщения в  представлении «Все сообщения» как «Запланировано».

Два решения

Есть два способа решить эту проблему:

  1. Запустите быстрый запрос непосредственно к базе данных, чтобы устранить проблему.
  2. Обновите аргументы сообщения, чтобы использовать правильное время по Гринвичу (я расскажу об этом подробнее чуть позже).

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

<?php

// First, update the post using the available WordPress API.
wp_update_post( $post );

/**
 * If the post status attribute of the post that was just updated
 * maintains the 'publish' post setatus, then manually update the 
 * database column.
 */
if ('publish' === $post->post_status) {

    global $wpdb;
    $wpdb->query(
        $wpdb->prepare(
            "
            UPDATE $wpdb->posts
            SET post_status = '%s'
            WHERE ID = %d
            ",
            'publish',
            $post->ID) );
}

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

<?php

$event_post->post_date_gmt = gmdate( 'Y-m-d H:i:s', $event_post->post_date_gmt );
wp_update_post( $event_post );

Я не говорю, что при работе над проектом нет места для любого из этих решений, но вопрос остается:

Почему WordPress помечает публикацию, запланированную на будущее, если запись перед прохождением процедуры обновления была настроена на публикацию?

И если вы не знакомы с остальными аргументами, которые передаются в WordPress при обновлении поста, потребуется некоторое время, чтобы отследить их.

Понимание проблемы

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

Чтобы выяснить, почему происходит такое поведение, вы можете обратиться к другому разработчику или отладить код. Учитывая, что я работал над этим поздно ночью, я выбрал последнее.

Запуск отладчика и трассировка кода через post.php.

Я не буду описывать все точки останова и контрольные точки, которые я установил, поэтому я постараюсь сделать это максимально кратким.

Во-первых, когда код проходит через функцию wp_update_post, он столкнется с этим блоком кода :

<?php

if ('attachment' !== $post_type) {
    if ('publish' == $post_status) {
        $now = gmdate('Y-m-d H:i:59');
        if (mysql2date('U', $post_date_gmt, false) > mysql2date('U', $now, false)) {
            $post_status = 'future';
        }
    } elseif ('future' == $post_status) {
        $now = gmdate('Y-m-d H:i:59');
        if (mysql2date('U', $post_date_gmt, false) <= mysql2date('U', $now, false)) {
            $post_status = 'publish';
        }
    }
}

Обратите внимание, что в условном выражении мы не работаем с вложением, а работаем со статусом публикации «опубликовать». Итак, мы найдем первое условное предложение внутри внешнего условного предложения (немного запутанно, не правда ли?).

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

<?php

$post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_ID, compact( array_keys( $postarr) ), $postarr );

Здесь вы увидите, что он работает с набором ключей массива, которые содержатся в переменной $postarr. Эта переменная используется ранее в коде (см. здесь, на Trac). И если вы внимательно присмотритесь, вы увидите, что сначала он проверяет, пусто ли свойство post_date_gmt или оно полностью обнулено.

А поскольку это не так, будет использоваться значение, которое мы указали в свойстве при первом вызове функции :

<?php

if (empty( $postarr['post_date_gmt']) || '0000-00-00 00:00:00' == $postarr['post_date_gmt']) {
        if (! in_array( $post_status, array( 'draft', 'pending', 'auto-draft') )) {
            $post_date_gmt = get_gmt_from_date( $post_date );
        } else {
            $post_date_gmt = '0000-00-00 00:00:00';
        }
    } else {
        $post_date_gmt = $postarr['post_date_gmt'];
    }

Ждать.

Зачем возвращаться к функции, когда код уже прошел это? Такова природа отладки. Иногда вы видите переменные и ничего о них не думаете только для того, чтобы увидеть, как они используются, устанавливаются, манипулируются, комбинируются или что-то еще в коде.

Такова реальность.

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

И это основание для использования wp_delete_post. Но у него есть свои предостережения, особенно в отношении пользовательских типов сообщений.

Это попадает в другой пост, хотя.

Источник записи: tommcfarlin.com

Этот веб-сайт использует файлы cookie для улучшения вашего опыта. Мы предполагаем, что вы согласны с этим, но вы можете отказаться, если хотите. Принимаю Подробнее