WordPress как на ладони
Черная пятница на хостинге fornex.com! Хостинг, VPS/VDS и отдельные сервера только на SSD дисках. 7 дней бесплатного тестирования.

wp_transition_post_status() WP 2.3

Запускает хуки (события) для любых изменений статусов записей (с draft на publish, с publish на private и т.д.).

Эта функция не меняет статус поста, она только вызывает 3 хука. Функция вызывается из других функций, после того, как статус был изменен, чтобы уведомить плагины, темы и функции ядра о смене статуса поста.

Для реальной смены статуса поста, используйте функции: wp_update_post() или wp_publish_post().

Хуки, которые вызывает функция:

  1. Первый хук: transition_post_status:

    do_action('transition_post_status', $new_status, $old_status, $post);

    Используйте когда нужно подключиться при любом изменении статуса.

  2. Второй хук: OLDSTATUS_to_NEWSTATUS:

    do_action("{$old_status}_to_{$new_status}", $post);

    Используйте когда нужно подключиться при конкретных изменениях статуса (с одного на другой).

    Несколько полезных вариантов хука:

    • new_to_publish - при первой публикации новой записи, например если запись добавляется функцией wp_insert_post().
    • auto-draft_to_publish - при первой публикации новой записи из админки WP.
    • draft_to_publish - при публикации, сохраненной записи.
    • future_to_publish - при публикации запланированной записи.
  3. Третий хук: NEWSTATUS_POSTTYPE:

    do_action("{$new_status}_{$post->post_type}", $post->ID, $post);

    Используйте когда нужно сделать что-либо для указанного статуса и типа поста.

    Несколько полезных вариантов хука:

    • publish_post - срабатывает всякий раз когда обновляется/создается пост со статусом publish. В wp_insert_post() вызывается эта функцию когда обновляется пост любого типа кроме attachment. Получается что если у поста статус publish, то при обновлении этот хук будет срабатывать всегда. Поэтому, если нужно делать что-либо один раз, только когда пост публикуется (а не обновляется), используйте хуки выше...

    • pending_post - срабатывает всякий раз когда обновляется/создается пост со статусом pending.

    • draft_post - срабатывает всякий раз когда обновляется/создается черновик - пост со статусом draft.
Список всех статусов, которые могут применяться в хуках:
  • new - если еще не было установленных никаких статусов.
  • publish - опубликованный пост (страница или тип записи).
  • pending - запись на рассмотрении перед публикацией.
  • draft - черновик записи.
  • auto-draft - только созданный пост, еще без заголовка, контента и другой информации.
  • future - запись запланированная к публикации в будущем.
  • private - запись не доступная не авторизованным пользователям.
  • inherit - ревизия или вложение (revision or attachment). Смотрите get_children().
  • trash - запись находящаяся в корзине.

Эта функция уже используется, где это необходимо в базовых функциях WordPress. Нет необходимости вызывать её при смене статуса поста, при использовании wp_update_post() или wp_insert_post().

Является основой для: wp_publish_post()
Хуки из функции:
Возвращает

Null. Ничего не возвращает.

Использование

wp_transition_post_status( $new_status, $old_status, $post );
$new_status(строка) (обязательный)
Какой статус поста будет.
По умолчанию: нет
$old_status(строка) (обязательный)
Какой статус поста был.
По умолчанию: нет
$post(объект) (обязательный)
Данные поста. Объект.
По умолчанию: нет

Примеры

#1. Посмотрим как работает функция

Для этого давайте взглянем на код функции wp_publish_post():

function wp_publish_post( $post ) {
	global $wpdb;

	if ( ! $post = get_post( $post ) )
		return;

	if ( 'publish' == $post->post_status )
		return;

	$wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post->ID ) );

	clean_post_cache( $post->ID );

	$old_status = $post->post_status;
	$post->post_status = 'publish';

	// теперь, когда статус поста изменен, вызываем хуки,
	// к которым в последствии смогут подключится плагины, темы и другие функции.
	wp_transition_post_status( 'publish', $old_status, $post );

	do_action( 'edit_post', $post->ID, $post );

	do_action( "save_post_{$post->post_type}", $post->ID, $post, true );

	do_action( 'save_post', $post->ID, $post, true );

	do_action( 'wp_insert_post', $post->ID, $post, true );
}

#2. Использование хука {$old_status}_to_{$new_status}

Добавим действие, которое будет срабатывать при изменении статуса draft на publish - draft_to_publish, т.е. при публикации черновика.

add_action( 'draft_to_publish', function( $post ){
	// ваш код
} );

Если нужно подключится к моменту одобрения (pending) поста, то нужно использовать хук pending_to_publish.

#3. Использование хука transition_post_status

Это общий хук, срабатывает когда нам нужно подключиться в момент смены любого статуса на любой. Хук передает 3 параметра: $new_status, $old_status, $post.
Этот пример показывает как подключаться, когда статус поста меняется с publish на любой другой статус:

add_action( 'transition_post_status', 'post_unpublished', 10, 3 );
function post_unpublished( $new_status, $old_status, $post ) {
	if ( $old_status == 'publish' && $new_status != 'publish' ) {
		// Пост снят с публикации
	}
}

#3.1. Хук, срабатывающий при любой смене статуса

add_action( 'transition_post_status', 'intercept_all_status_changes', 10, 3 );
function intercept_all_status_changes( $new_status, $old_status, $post ) {
	if ( $new_status != $old_status ) {
		// Статус поста изменен
	}
}

#3.2 Использование хука {$new_status}_{$post->post_type}

Если нужно подключиться к текущему статусу, независимо от того какой был статус до этого используем конструкцию: СТАТУС_ТИПЗАПИСИ.

Например, если нужно что-то сделать когда пост публикуется или обновляется со статусом publish, то конструкция будет выглядеть так publish_post:

add_action( 'publish_post', 'publish_post_action', 10, 2 );
function publish_post_action($post_id, $post){
		// что делать при публикации поста
}

Обратите внимание, что этот хук будет срабатывать и при обновлении записи, если при обновлении статут указан publish или если статус не был указан, но при этом до этого он был publish.

Код wp_transition_post_status: wp-includes/post.php VER 4.9.8

<?php
function wp_transition_post_status( $new_status, $old_status, $post ) {
	/**
	 * Fires when a post is transitioned from one status to another.
	 *
	 * @since 2.3.0
	 *
	 * @param string  $new_status New post status.
	 * @param string  $old_status Old post status.
	 * @param WP_Post $post       Post object.
	 */
	do_action( 'transition_post_status', $new_status, $old_status, $post );

	/**
	 * Fires when a post is transitioned from one status to another.
	 *
	 * The dynamic portions of the hook name, `$new_status` and `$old status`,
	 * refer to the old and new post statuses, respectively.
	 *
	 * @since 2.3.0
	 *
	 * @param WP_Post $post Post object.
	 */
	do_action( "{$old_status}_to_{$new_status}", $post );

	/**
	 * Fires when a post is transitioned from one status to another.
	 *
	 * The dynamic portions of the hook name, `$new_status` and `$post->post_type`,
	 * refer to the new post status and post type, respectively.
	 *
	 * Please note: When this action is hooked using a particular post status (like
	 * 'publish', as `publish_{$post->post_type}`), it will fire both when a post is
	 * first transitioned to that status from something else, as well as upon
	 * subsequent post updates (old and new status are both the same).
	 *
	 * Therefore, if you are looking to only fire a callback when a post is first
	 * transitioned to a status, use the {@see 'transition_post_status'} hook instead.
	 *
	 * @since 2.3.0
	 *
	 * @param int     $post_id Post ID.
	 * @param WP_Post $post    Post object.
	 */
	do_action( "{$new_status}_{$post->post_type}", $post->ID, $post );
}

Cвязанные функции

Из метки: statuses (статус записи коммента юзера)

Еще из раздела: Остальное

10 комментов
  • Игорь

    Cоздал вот такой плагин для постинга о новых записях с помощью бота в дискорд

    function cta_send_notification( $new_status, $old_status, $post ) {
    	$sxss=get_post_type();
    // проверка на новую запись и тип записи
      if(
    	  'publish' === $new_status && 
    	'publish' !== $old_status && 
    	$sxss == 'cta'
      ) {
    // функция формирования и отправки запроса в дискорд
    	   function postToDiscord($message)
    {
    	$data = array(
    		"content" => $message,
    		"username" => "CTA PING BOT",
    	);
    	$curl = curl_init("https://discordapp.com/api/webhooks/айдиканала/код");
    	curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
    	curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
    	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    	return curl_exec($curl);
    	curl_close($curl);
    }  
    
    // получаем айди поста, тайтл и допполе
    $postid =get_the_ID();
    $taste=get_the_title($postid);
    global $post;
    // get post meta 
    $pstmt1=get_post_meta( $postid, 'wpcf-fleetformat', true );
    
    $message="**";
     $message.=$taste;
     $message.='ФФ:  '.$pstmt1.'
    ';
    
    postToDiscord($message);
      }
    }
    add_action( 'transition_post_status', 'cta_send_notification', 10, 3 );

    Все работает, но не могу получить допполей к записи

    get_the_title($postid) срабатывает нормально. пробовал сохранять все поля в файл - та же ситуация, они пустые. в цикле поля вытягиваются нормально через archive-cta.php
    судя по всему оно или не успевает записать в бд до срабатывания, или я где-то налажал. подскажите пожалуйста

    Ответить3 месяца назад #
    • Kama7021

      $sxss == 'cta' замени на $post->post_status. Ну и $sxss=get_post_type(); удали.

      Далее замени функцию function postToDiscord($message) на анонимную и передай ей $post.

      function postToDiscord($message){ ... }
      // на 
      $fn_postToDiscord = function ($message) use ($post){ ... }
      
      // и 
      
      postToDiscord($message);
      // на 
      $fn_postToDiscord($message);

      Далее удали лучше global $post; и замени get_the_ID() и get_the_title() на аналоги через $post->ID, $post->post_title.

      Ответить3 месяца назад #
      • Игорь

        Спасибо за ответ!
        Заменил кроме последних
        ID 237
        Title xxx1
        post meta :
        допполя пустые
        Также слетел фильтр по типу записей. теперь оно постит в дискорд и простые записи, и и другие отз
        придется наверное пробовать через save_post
        так как подозреваю что сперва оно записывает стандартные данные (тайтл, текст поста) в бд, потом меняет статус поста на паблишед, потом кидает в базу данные допполей. поэтому и идет такой вывод с пустыми значениями

        Ответить3 месяца назад #
        • Kama7021

          Там сначала все обрабатывается и только потом срабатывает этот хук. Подозреваю что вы что-то не так делаете и с save_post будет тоже самое эти хуки прям рядом срабатывают.

          1
          Ответить3 месяца назад #
          • Игорь

            Вы правы. вывод аналогичный получился.
            допполя не подтягиваются

            Ответить3 месяца назад #
            • Kama7021

              Упс $sxss == 'cta' нужно заменить на $post->post_type == 'cta'. Еще раз попробуй сделать как я написал, должно работать!

              Ответить3 месяца назад #
              • Игорь

                get_post_custom : {"_edit_lock":["1534691011:1"],"_edit_last":["1"]}
                вот что я получил из плагина
                оно допполя сохраняет не знаю когда....

                Ответить3 месяца назад #
                • Игорь

                  кажется нашел проблему laugh
                  Toolset плагин для допполей
                  он кажется тоже использует данную методику для записи допполей в базу

                  Ответить3 месяца назад #
          • Игорь

            подозреваю User Role Editor
            может плагин блочит доступ. так как сайт закрытый. доступ только через esi ccp. + мой плагин на доступ только зарегистрированым. сейчас высоконаучным методом буду по очереди отключать плагины и пробовать laugh

            Ответить3 месяца назад #
            • Игорь

              Вот оно что, Михалыч... Использование плагинов, если можно сделать самому все, это зло

              add_action( 'save_post', 'wpcf_admin_save_post_hook', 10, 2 );
              /**
               * save_post hook.
               *
               * @param type $post_ID
               * @param type $post
               */
              function wpcf_admin_save_post_hook( $post_ID, $post ) {
              	require_once WPCF_EMBEDDED_INC_ABSPATH . '/fields.php';
              	require_once WPCF_EMBEDDED_INC_ABSPATH . '/fields-post.php';
              	wpcf_admin_post_save_post_hook( $post_ID, $post );
              	cta_send_notification ($post_ID);
              }
              Ответить3 месяца назад #
Здравствуйте, !     Войти . Зарегистрироваться