Wordpress - hooking into saving post data

2019-09-07 08:19发布

This piece of code is supposed to set post data if post custom field is set to true, or set post status to draft, if it is not. The action needs to be called after post_save/post_updated action, so one of our colleges suggested me the way (old question: wordpress set post_status as "draft" in 'save_post' action):

add_filter( 'wp_insert_post_data', 'set_post_parameters', 99, 2 );
function set_post_parameters( $data, $postarr ) {
    if ( get_post_meta( $postarr['ID'], '_cs_tweet_ok_status', true ) == 'true' ) {
        $data['post_date']      = get_post_meta( $postarr['ID'], '_cs_system_tweet_date', true );   
        $data['post_date_gmt']  = get_gmt_from_date( get_post_meta( $postarr['ID'], '_cs_system_tweet_date', true ) );
    } else {
        $data['post_status'] = 'draft';
    }
    return $data;
}

And it does what it should - it sets published dates to one provided with custom fields (that are saved before) or sets a post to draft. The only thing is, that it is also fired when post-new.php is being called, those creating "empty" posts that cannot be deleted (in case user doesnt fill all data and doesnt save the post correctly). How should I create a "check" in that function, so it only runs when post is being saved or updated?

I have also a small problem with setting those post_data with function:

add_action( 'save_post', 'cs_twitter_save_meta' );
function cs_twitter_save_meta( $post_id ) {
    if ( isset($_POST['post_type']) && 'tweets' == $_POST['post_type'] ) :
        if ( isset($_POST['post_title']) ) :
            $url = 'https://api.twitter.com/1/statuses/show.json?id='.$_POST['post_title'];
            $json = @file_get_contents($url,0,null,null);
            if ( $json != false ) {
                $json_output = json_decode($json);
                $post_date = date('c', strtotime($json_output->created_at));
                $post_save_date = date('G:i - d M y', strtotime($json_output->created_at));
                update_post_meta( $post_id, '_cs_tweet_content', $json_output->text  );
                update_post_meta( $post_id, '_cs_tweet_date', $post_save_date  );
                update_post_meta( $post_id, '_cs_system_tweet_date', $post_date  );
                update_post_meta( $post_id, '_cs_tweet_user', $json_output->user->screen_name );
                update_post_meta( $post_id, '_cs_tweet_ok_status', 'true' );
            } else {
                update_post_meta( $post_id, '_cs_tweet_content', 'There is an error with tweet Api. Too many connections in one hour. Try again after 60 minutes' );
                update_post_meta( $post_id, '_cs_tweet_ok_status', 'false'  );
            }
        endif;
    endif;
}

The problem shows while saving for the first time. It seems that add_filter( 'wp_insert_post_data', 'set_post_parameters', 99, 2 ); fires in first place, doesnt see custom_meta and sets post_status to draft. Then add_action( 'save_post', 'cs_twitter_save_meta' ); fires, but it is already to late for the first script.

So another question - how should I slove this situation, so all data is set correctly at first place: 1. User creates new custom_post_type. 2. He enters tweets id to import, and push publish. 3. Script checks if it can fetch the data from twitter api 4. If it can, it fets all necesary data, publishes the post and sets it's publish date to publish date of the tweet. 5. If not, it displays info about an error and sets post_status to draft.

2条回答
Luminary・发光体
2楼-- · 2019-09-07 08:55

This should resolve Your problem. Instead using of wp_insert_post_data hook, use only save_post and use $wpdb to alter database entry.

add_action( 'save_post', 'cs_twitter_save_meta' );
function cs_twitter_save_meta( $post_id ) {
    if ( isset($_POST['post_type']) && 'tweets' == $_POST['post_type'] ) :
        if ( isset($_POST['post_title']) ) :
            $url = 'https://api.twitter.com/1/statuses/show.json?id='.$_POST['post_title'];
            $json = @file_get_contents($url,0,null,null);
            if ( $json != false ) {
                $json_output = json_decode($json);
                $post_date = date('Y-m-d H:i:s', strtotime($json_output->created_at));
                $post_date_gmt = get_gmt_from_date( $post_date );
                $post_save_date = date('G:i - d M y', strtotime($json_output->created_at));
                update_post_meta( $post_id, '_cs_tweet_content', $json_output->text  );
                update_post_meta( $post_id, '_cs_tweet_date', $post_save_date  );
                update_post_meta( $post_id, '_cs_system_tweet_date', $post_date  );
                update_post_meta( $post_id, '_cs_tweet_user', $json_output->user->screen_name );
                update_post_meta( $post_id, '_cs_tweet_ok_status', 'true' );
                global $wpdb;
                $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_date = '$post_date', post_date_gmt = '$post_date_gmt' WHERE id = $post_id", $post_id ));
            } else {
                update_post_meta( $post_id, '_cs_tweet_content', 'There is an error with tweet Api. Too many connections in one hour. Try again after 60 minutes' );
                update_post_meta( $post_id, '_cs_tweet_ok_status', 'false'  );
                global $wpdb;
                $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_status = 'draft' WHERE id = $post_id", $post_id ));
            }
        endif;
    endif;
}
查看更多
▲ chillily
3楼-- · 2019-09-07 08:57

You can try to prevent the function from running unless you explicitly hit save.

Add the following snippet at the beginning of your function:

// Autosave
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
        return;
// AJAX
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) 
        return;
// Post revision
if ( false !== wp_is_post_revision( $post_id ) )
        return;
查看更多
登录 后发表回答