WP笔记

WordPress 后台Post Actions(2021)

WordPress 后台Post Actions包括Edit、Trash、Untrash和delete。如果你写了一些自定义代码,希望在文章发生变化时更新一些信息,那么了解这些事件发生时可以使用的actions就变的很有用。

后台Post Actions

除了delete事件,其它都会调用wp_insert_post(),所以save_post或者wp_insert_post对它们都是可用的。

事件Action
Edit or Updatesave_post
Trashwp_trash_post
Untrashuntrash_post
Deletedeleted_post

Delete事件还有其它几个action:

  • before_delete_post – 准备删除之前触发
  • delete_post – 删除post之后触发,此时post meta信息还未删除
  • after_delete_post – 删的一点不剩了,顺带刷新了post cache

后台Post Actions使用示例

例1:在文章更新时执行代码

function action_on_save( $post_id, $post ){
    // $post_id and $post are required
    if ( empty( $post_id ) || empty( $post ) ) {
        return;
    }

    // Dont' save meta boxes for revisions or autosaves
    if ( defined( 'DOING_AUTOSAVE' ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) {
        return;
    }
    
    // Check the post being saved == the $post_id to prevent triggering this call for other save_post events
    if ( empty( $_POST['post_ID'] ) || $_POST['post_ID'] != $post_id ) {
        return;
    }
    // Check user has permission to edit
    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        return;
    }

    // If you want to check the custom post type
    global $post_type;
    if( $post_type == '[CPT]' ){
        // Your code here   
    }       
}

add_action( 'save_post', 'action_on_save', 100, 2 );

这段代码不会再trash、untrash时执行,前面的判断条件把这两种情况过滤掉了。

例2:移动到回收站时执行代码

function action_on_trash ( $post_id ){
    global $post_type; 
    if ( $post_type == '[CPT]' ){
        // Your code here   
    }
}
add_action( 'wp_trash_post', 'action_on_trash' );

批量操作posts时避免实用上述actions

批量回收、复原或删除文章时,上述actions会被执行若干次,如果你的操作很费资源,就会严重影响性能。

这时可以在WordPress的批量操作执行结束并准备跳转时运行你的代码,要用到wp_redirect filter,虽然filter不能影响程序执行,但更新一下数据库还是可以的。

批量操作posts 代码

下面这段代码在WordPress操作Posts时记录被影响的Post的ID,如果批量操作,就记录所有ID,在wp_redirect时显示哪些ID被影响了,根据传回的post IDs可以进行自己的操作。

注意程序运行到wp_redirect时,若删除文章,则文章已经被删的一干二净了,想再访问post meta已经不可能。

下面的代码只是演示,使用时应判断使用场景。

class Sola_Post_Actions{

    var $post_IDs = array(); // 记录受影响的Post IDs

    public function __construct(){
        add_action( 'save_post',        array( $this, 'save' ), 100, 2 );
        add_action( 'wp_trash_post',    array( $this, 'trash' ) );
        add_action( 'untrash_post',     array( $this, 'untrash' ) );
        add_action( 'deleted_post',     array( $this, 'delete' ) );
        add_filter( 'wp_redirect',      array( $this, 'catch_results') );
    }

    // 新建或更新posts时执行
    function save( $post_id, $post ){

        // $post_id and $post are required
        if ( empty( $post_id ) || empty( $post ) ) {
            return;
        }

        // Dont' save for revisions or autosaves
        if ( defined( 'DOING_AUTOSAVE' ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) {
            return;
        }
        
        // Check user has permission to edit
        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return;
        }

        // 存储受影响的Post ID,如果指定了CPT,则移动到CPT的判断里
        $this->post_IDs['saved'][] = $post_id;
    }

    // 删除posts时执行
    function delete( $post_id ){
        //你的代码,这里我们只记录post IDs,如果批量删除,会有多个post IDs被记录
        $this->post_IDs['deleted'][] = $post_id;
    }

    // 删除到回收站时执行
    function trash ( $post_id ){
        $this->post_IDs['trashed'][] = $post_id;
    }

    //从回收站恢复时执行
    function untrash( $post_id ){     
        $this->post_IDs['untrashed'][] = $post_id;
    }

    // WordPress处理结束后准备跳转,在这里更新数据
    function catch_results( $location ){

        // 根据受影响的post IDs来操作
        if( !empty( $this->post_IDs ) ){
            echo '<pre> ', print_r( $this->post_IDs ) ,'</pre>';
            echo '<a href="'.$location.'">Continue</a>';
            exit;
        }

        // 操作完成后进行正常的跳转
        return $location;
    }
}
new Sola_Post_Actions();

将代码放到子主题的functions.php中,到后台批量保存以下posts,效果如下:

WordPress 后台Post Actions