Добавьте кнопки с пользовательскими действиями на экране редактирования записи в WordPress.

Вопрос или проблема

Я создаю что-то для клиента, и у меня есть класс, который я создал с пользовательским типом записи под названием ‘PuSH Feeds’. Когда пользователь добавляет новую запись и публикует ее, он может нажать на одну из двух кнопок, которые у меня есть в настраиваемом мета-боксе.

Одна кнопка предназначена для ‘Подписки’, а другая – для ‘Отписки’. Я использую хук действия save_post и проверяю, имеет ли глобальная переменная $_POST значение ‘pushfeed-subscribe’ или ‘pushfeed-unsubscribe’, и затем выполняю необходимые действия. Однако по какой-то причине я обнаружил, что после нажатия на подписку на моем локальном компьютере скрипт останавливается из-за 100 последовательных вызовов и т. д., и в итоге я получаю множество дублирующих записей без заголовка.

Какой был бы лучший способ избежать этого, и есть ли лучший хук, который я могу использовать для этих специальных пользовательских действий, которые я хочу активировать для подписки на фид (что переходит в другой класс и выполняет метод подписки)?

Это разметка, которую я использую для тех двух кнопок, о которых я упоминал, которые находятся внутри мета-бокса:

<input type="submit" class="button-secondary" name="pushfeed-subscribe" id="pushfeed-subscribe" value="Subscribe">
<input type="submit" class="button-secondary" name="pushfeed-unsubscribe" id="pushfeed-unsubscribe" value="Unsubscribe">

Затем у меня есть это для хука действия:

add_action( 'save_post', array( $this, 'pushfeed_save_post_meta' ) );

Сам хук выглядит так:

public function pushfeed_save_post_meta( $post_id ) {

    // Выход, если происходит автоматическое сохранение
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    // если наш nonce отсутствует или мы не можем его проверить, выходим
    if( !isset( $_POST['pushfeed-nonce-field'] ) || !wp_verify_nonce( $_POST['pushfeed-nonce-field'], basename( __FILE__ ) ) ) return;

    // Если идентификатор подписки пуст, создадим случайное длинное число и сохраним его
    if ( empty( $_POST['pushfeed-subscription-id'] ) ) {

        $random_number = substr(number_format(time() * mt_rand(),0,'',''),0,10);
        $pushfeed_subscription_id = $random_number . $post_id;
        update_post_meta( $post_id, 'pushfeed-subscription-id', $pushfeed_subscription_id );
    }

    ...

    if ( isset( $_POST['pushfeed-subscribe'] ) || isset( $_POST['pushfeed-unsubscribe'] ) ) {

        $subscription_domain = get_post_meta($post_id, 'pushfeed-domain', true);
        $subscription_id = get_post_meta($post_id, 'pushfeed-subscription-id', true);
        $subscription_feed_url = get_post_meta($post_id, 'pushfeed-feed-url', true);
        $subscription_callback_url = $subscription_domain . '/pushfeed/' . $subscription_id;


        $sub = PuSHSubscriber::instance($subscription_domain, $subscription_id, 'PuSHSubscription', new PuSHEnvironment());

        if ( isset( $_POST['pushfeed-subscribe'] ) ) {
            $sub->subscribe($subscription_feed_url, $subscription_callback_url);
        } elseif ( isset( $_POST['pushfeed-unsubscribe'] ) ) {
            $sub->unsubscribe($subscription_feed_url, $subscription_callback_url);
        }

    }

}

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

Обновление :

Всем привет. Я в итоге использовал Ajax-запрос с помощью wordpress admin-ajax.php при нажатии кнопки, а затем выполнял метод подписки. После этого метод подписки выполняет GET-запрос, и, если он возвращает код 200, метод возвращает true в Ajax.

Не уверен, если это точно та проблема, которую вы имеете, но похоже, что хук ‘save_post’ зацикливается.

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

{
    remove_action('save_post', array( $this, 'pushfeed_save_post_meta' ));
    // Выполните работу по обновлению...
    add_action('save_post', array( $this, 'pushfeed_save_post_meta' ));
}

Ответ или решение

Создание кастомных кнопок для выполнения нестандартных действий на экране редактирования поста в WordPress требует особенно тщательного подхода, учитывая вашу ситуацию с пользовательскими действиями "Подписаться" и "Отписаться". Мы столкнулись с проблемой рекурсивного вызова хука save_post, что привело к созданию многочисленных дубликатов постов без заголовка. Рассмотрим лучшие практики и решения для этой задачи.


Краткий контекст и задача

В рамках вашего проекта для клиента, вы создали кастомный тип записи "PuSH Feeds" и добавили кастомную метабокс, содержащую две кнопки для подписки и отписки. Ваш текущий подход использует хук save_post, который может быть не лучшим выбором из-за рискованного поведения и возникновения рекурсивных вызовов.

Решения

  1. Использование AJAX для обработки пользовательских действий

    Вместо использования хука save_post, рекомендуется обрабатывать действия "Подписаться" и "Отписаться" с помощью AJAX. Этот подход минимизирует риск рекурсии и позволяет напрямую взаимодействовать с функциями вашего класса, отправляя асинхронные запросы к серверу. Процедура выглядит следующим образом:

    • Создайте JavaScript, который будет слушать нажатия кнопок и отправлять AJAX-запросы к обработчикам на стороне сервера.
    • В functions.php зарегистрируйте AJAX-обработчики через add_action('wp_ajax_ВАШЕ_ДЕЙСТВИЕ', 'callback_function').
    • В коллбэк-функциях выполните подписку или отписку, возвращая соответствующий ответ клиенту.
  2. Защита от рекурсии

    Если все же необходимо оставить логику в хук save_post, убедитесь в предотвращении рекурсии:

    • Отключение хуков: временно удаляйте хук перед обновлением данных и возвращайте его после завершения функции.

      remove_action('save_post', array($this, 'pushfeed_save_post_meta'));
      // Выполнение действий...
      add_action('save_post', array($this, 'pushfeed_save_post_meta'));
    • Проверка состояний поста: добавляйте проверки на изменение содержимого и статуса публикации, чтобы избежать ненужных срабатываний функции.

    • Использование транзитных данных: для предотвращения повторных вызовов, храните временные данные о выполнении действий в транзиентах или других безопасных местах хранения.

  3. Обеспечение корректной работы с мета-данными

    Если вы оставляете обработку внутри save_post, допускать минимальное количество операций и уделить внимание валидации данных, получаемых из $_POST. Обязательно выполняйте проверку nonce-поля и валидацию данных перед их использованием.

Подводя итог

Работа с нестандартными действиями в WordPress требует внимательного выбора хуков и инструментов для реализации. Используйте AJAX для уменьшения зависимости от тяжёлой серверной логики, и избегайте рекурсивных вызовов. Подход с поверкой состояния системы и временным отключением хука поможет избежать проблем и улучшить производительность.

Надеемся, что данное решение окажется полезным для вашего проекта. Успехов в разработке!

Оцените материал
Добавить комментарий

Капча загружается...