Почему срабатывает действие save_post при создании новой записи?

8 июн. 2011 г., 21:31:22
Просмотры: 15.5K
Голосов: 38

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

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

Вот мой код:

add_action('save_post', 'MyNS\save_event_metabox', 10, 2);
function save_event_metabox($post_id, $post){
  echo "<h1>ДА!</h1>";
}

Это "ДА!" выводится (в верхней части страницы) при нажатии на "Новая запись", но НЕ выводится при вводе текста и последующем нажатии Обновить, Опубликовать или Сохранить черновик. Это кажется противоречащим документации по действию save_post и функции wp_insert_post().

Может кто-нибудь прояснить эту ситуацию?

1
Комментарии

Отлично!!! Я сталкиваюсь с такой же ситуацией при сохранении полей пользовательских метабоксов. Есть идеи, что можно использовать??

Prasath Nadarajah Prasath Nadarajah
9 июн. 2012 г. 14:45:45
Все ответы на вопрос 1
5
46

При нажатии на кнопку "Новая запись" загружается страница wp-admin/post-new.php.

При этом WordPress всегда создает новую запись ("Автосохраненный черновик"), чтобы обеспечить корректную работу всех остальных функций (например, загрузки медиафайлов) и плагинов, даже до того, как вы сохраните черновик или опубликуете запись.

Это, в свою очередь, вызывает срабатывание хука save_post. Отсюда и ваше сообщение через echo.

Хорошо, но почему тогда я не вижу сообщения при обновлении или публикации?

Между сохранением и последующей загрузкой страницы WordPress фактически отправляет GET-редирект обратно на ту же страницу, который выглядит прозрачным (это можно наблюдать с помощью монитора HTTP-запросов, например HttpFox).

Другими словами:

  1. Вы нажимаете Обновить или Опубликовать
  2. Браузер отправляет данные на сервер
  3. WordPress обрабатывает их, в процессе срабатывает хук save_post
  4. WordPress отправляет обратно заголовок редиректа и завершает работу до появления какого-либо вывода в браузере (включая ваш echo)*
  5. Браузер следует редиректу и загружает страницу редактирования записи.

Редирект может показаться излишним (ведь можно просто отправить POST на ту же страницу), но это часть техники, известной как Post/Redirect/Get, которая позволяет избежать повторной отправки форм.

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

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

8 июн. 2011 г. 21:58:38
Комментарии

Потрясающе. Спасибо за такой полный и детальный ответ! Чтобы узнать больше, расскажи, как ты впервые нашел эту информацию?

Tom Auger Tom Auger
8 июн. 2011 г. 23:14:39

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

TheDeadMedic TheDeadMedic
8 июн. 2011 г. 23:31:59

Точно, брат. Спасибо, что поделился своим опытом!

Tom Auger Tom Auger
9 июн. 2011 г. 18:20:07

Отличная информация. Я сходил с ума, потому что на локальном сервере всё вроде работало "нормально", но не на продакшн-сервере... Похоже, на локальном сервере метод post/redirect/get не применялся правильно, так как не отправлялся заголовок перенаправления (хотя не знаю, почему).

The WebMacheter The WebMacheter
15 дек. 2011 г. 08:20:46

Спасибо за ответ. Я надеялся использовать параметр $update, чтобы определить, было ли событие сохранения первым или обновлением, но узнал, что все ручные сохранения будут иметь $update как true. Так ли это? Интересно, есть ли элегантное решение без сравнения статусов записи, которые могут быть динамичными. (Пока это мой любимый ответ: https://wordpress.stackexchange.com/a/365727/2798)

atwellpub atwellpub
5 февр. 2021 г. 20:36:40