函数文档

_transition_post_status()

💡 云策文档标注

概述

_transition_post_status() 是一个 WordPress 钩子函数,用于管理文章状态从未来状态过渡到发布状态时的处理逻辑。它执行关键操作如重置 GUID、清理缓存和取消预定发布任务。

关键要点

  • 这是一个内部钩子函数,处理文章状态从非发布状态到发布状态的过渡。
  • 当文章从非发布状态过渡到发布状态时,如果 GUID 为空,会自动更新为文章永久链接。
  • 触发已弃用的 'private_to_published' 钩子,建议使用 'private_to_publish' 替代。
  • 清理与发布文章相关的缓存,包括 lastpostmodified 和 lastpostdate 缓存。
  • 当文章状态改变时,清除文章计数缓存。
  • 总是清除 'publish_future_post' 的预定钩子,以防文章状态从未来跳转到草稿。

代码示例

function _transition_post_status( $new_status, $old_status, $post ) {
    global $wpdb;

    if ( 'publish' !== $old_status && 'publish' === $new_status ) {
        if ( '' === get_the_guid( $post->ID ) ) {
            $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) );
        }
        do_action_deprecated( 'private_to_published', array( $post->ID ), '2.3.0', 'private_to_publish' );
    }

    if ( 'publish' === $new_status || 'publish' === $old_status ) {
        foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
            wp_cache_delete( "lastpostmodified:$timezone", 'timeinfo' );
            wp_cache_delete( "lastpostdate:$timezone", 'timeinfo' );
            wp_cache_delete( "lastpostdate:$timezone:{$post->post_type}", 'timeinfo' );
        }
    }

    if ( $new_status !== $old_status ) {
        wp_cache_delete( _count_posts_cache_key( $post->post_type ), 'counts' );
        wp_cache_delete( _count_posts_cache_key( $post->post_type, 'readable' ), 'counts' );
    }

    wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) );
}

注意事项

  • 此函数是 WordPress 核心内部函数,通常不应直接调用,而是通过相关钩子触发。
  • 使用 'private_to_published' 钩子已被弃用,建议改用 'private_to_publish'。
  • 函数涉及数据库操作和缓存管理,确保在开发插件或主题时理解其影响。

📄 原文内容

Hook for managing future post transitions to published.

Description

See also

Parameters

$new_statusstringrequired
New post status.
$old_statusstringrequired
Previous post status.
$postWP_Postrequired
Post object.

Source

function _transition_post_status( $new_status, $old_status, $post ) {
	global $wpdb;

	if ( 'publish' !== $old_status && 'publish' === $new_status ) {
		// Reset GUID if transitioning to publish and it is empty.
		if ( '' === get_the_guid( $post->ID ) ) {
			$wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) );
		}

		/**
		 * Fires when a post's status is transitioned from private to published.
		 *
		 * @since 1.5.0
		 * @deprecated 2.3.0 Use 'private_to_publish' instead.
		 *
		 * @param int $post_id Post ID.
		 */
		do_action_deprecated( 'private_to_published', array( $post->ID ), '2.3.0', 'private_to_publish' );
	}

	// If published posts changed clear the lastpostmodified cache.
	if ( 'publish' === $new_status || 'publish' === $old_status ) {
		foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
			wp_cache_delete( "lastpostmodified:$timezone", 'timeinfo' );
			wp_cache_delete( "lastpostdate:$timezone", 'timeinfo' );
			wp_cache_delete( "lastpostdate:$timezone:{$post->post_type}", 'timeinfo' );
		}
	}

	if ( $new_status !== $old_status ) {
		wp_cache_delete( _count_posts_cache_key( $post->post_type ), 'counts' );
		wp_cache_delete( _count_posts_cache_key( $post->post_type, 'readable' ), 'counts' );
	}

	// Always clears the hook in case the post status bounced from future to draft.
	wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) );
}

Hooks

do_action_deprecated( ‘private_to_published’, int $post_id )

Fires when a post’s status is transitioned from private to published.

Changelog

Version Description
2.3.0 Introduced.