save_post
Срабатывает всякий раз, когда запись (пост, страница) создается или обновляется, в том числе при публикации через импорт, xmlrpc или по email.
Данные записи передаются во втором параметре $post, но их еще как правило, можно получить через $_POST, $_GET или глобальную переменную global $post_data
. Когда и что используется, зависит от того, как запись редактируется. Например, "быстрое редактирование" (quick edits) использует $_POST.
Хук срабатывает в самом конце, после обновления данных поста, очистки кэша и прочих действий.
Хук срабатывает после того, как был сброшен объектный кэш поста. Поэтому если изменяются какие-то данные поста на этом хуке, то кэш поста нужно сбросить еще раз
// очистим кэш поста clean_post_cache( $post_ID );
Или нужно использовать хук wp_insert_post_data или wp_insert_attachment_data. Только эти хуки срабатывают до сброса кэша, но они не будут работать при вызове функции wp_publish_post().
С версии 3.7 появился точно такой же хук save_post_(post_type). Где вместо post_type нужно указать название типа записи и событие будет срабатывать только при сохранении/добавлении записи этого типа. Выглядит хук так:
do_action( "save_post_{$post->post_type}", $post_ID, $post, $update );
save_post - это копия хука wp_insert_post.
Хук edit_post - такой же как и save_post, но срабатывает только при обновлении записи.
Внимание! Зацикливание
В хуке save_post нужно аккуратно использовать функцию wp_update_post(). Потому что она повторно взывает этот хук и код попадет в бесконечный цикл. Как этого избежать смотрите ниже в примере #3. Также об этом написано в описании функции wp_update_post().
Использование
add_action( 'save_post', 'wp_kama_save_post_action', 10, 3 ); /** * Function for `save_post` action-hook. * * @param int $post_id Post ID. * @param WP_Post $post Post object. * @param bool $update Whether this is an existing post being updated. * * @return void */ function wp_kama_save_post_action( $post_id, $post, $update ){ // action... }
- $post_id(строка)
- ID записи, которая обновляется.
- $post(объект)
- Объект записи, которая обновляется. Объект такой же как обычно в глобальной переменной $post.
- $update(логический)
- true — это обновление записи.
false — это добавление новой записи.
Примеры
#1 Отправка email при обновлении записи
Этот демонстративный пример, показывает как, всякий раз когда запись обновляется отправлять письмо администратору сайта с сообщением об обновлении:
add_action( 'save_post', 'my_project_updated_send_email' ); function my_project_updated_send_email( $post_id ) { // Если это ревизия, то не отправляем письмо if ( wp_is_post_revision( $post_id ) || get_post($post_id)->post_status != 'publish' ) return; $post_title = get_the_title( $post_id ); $post_url = get_permalink( $post_id ); $subject = 'Запись была обновлена'; $message = "На вашем сайте следующая запись была обновлена:\n\n"; $message .= $post_title . ": " . $post_url; // Отправляем письмо. wp_mail( get_option('admin_email'), $subject, $message ); }
#2 Произвольный тип записи "book"
Предположим у вас есть тип поста book и вам нужно добавить к нему информацию об авторе, издателе и о печатной копии. Этот код показывает как можно сохранить эти данные в метаданные записи:
/** * Сохраняем метаданные записи при сохранении поста. */ add_action( 'save_post', 'save_book_meta' ); function save_book_meta( $post_id ) { // слаг лучше указать единожды и использовать во всех кодах // связанных с типом записи, как это принято в классах $slug = 'book'; // Проверяем тип записи, если не boo то выходим. if ( $slug != $_POST['post_type'] ) return; // Обновляем метаданные записи. if ( isset( $_REQUEST['book_author'] ) ) { update_post_meta( $post_id, 'book_author', sanitize_text_field( $_REQUEST['book_author'] ) ); } if ( isset( $_REQUEST['publisher'] ) ) { update_post_meta( $post_id, 'publisher', sanitize_text_field( $_REQUEST['publisher'] ) ); } // inprint - это чекбокс. if ( isset( $_REQUEST['inprint'] ) ) { update_post_meta( $post_id, 'inprint', TRUE ); } else { update_post_meta( $post_id, 'inprint', FALSE ); } }
В этом примере, проверку if ( $slug != $_POST['post_type'] ), можно заменить: вместо события save_post, можно использовать save_post_book
.
#3 Как избежать зацикливания
Если вы вызываете функцию wp_update_post() внутри события save_post, то вы наткнетесь на зацикливание, потому что wp_update_post() вызывает save_post. Чтобы этого избежать, удалите добавленный хук, перед тем как вызывать wp_update_post(), а затем добавьте его снова:
// Эта функция делает все записи в дефолтной категории частными add_action( 'save_post', 'set_private_categories' ); function set_private_categories( $post_id ){ // Получим реальный ID поста, если это ревизия if ( $parent_id = wp_is_post_revision( $post_id ) ) $post_id = $parent_id; // Получим ID категории по умолчанию из опций $defaultcat = get_option( 'default_category' ); // Проверим находится ли пост в категории по умолчанию if ( in_category( $defaultcat, $post_id ) ) { // Удаляем хук, чтобы не было зацикливания remove_action( 'save_post', 'set_private_categories' ); // обновляем запись. В это время срабатывает событие save_post wp_update_post( array( 'ID' => $post_id, 'post_status' => 'private' ) ); // Ставим хук обратно add_action( 'save_post', 'set_private_categories' ); } }
Эта часть кода, должна быть обязательно:
// Удаляем хук, чтобы не было зацикливания remove_action( 'save_post', 'set_private_categories' ); // обновляем запись. В это время срабатывает событие save_post wp_update_post( array( 'ID' => $post_id, 'post_status' => 'private' ) ); // Ставим хук обратно add_action( 'save_post', 'set_private_categories' );
Список изменений
С версии 1.5.0 | Введена. |
Где вызывается хук
do_action( 'save_post', $post_id, $post, $update );
do_action( 'save_post', $post->ID, $post, true );
do_action( 'save_post', $post->ID, $post, true );
Где используется хук в WordPress
add_action( 'save_post', 'delete_get_calendar_cache' );