using new WP_Query in save_post function alters $post

I’m trying to include a WP_Query in a save_post function for a custom post type. The query is used to check all the other posts for a custom field bh_shortcode to make sure the content of the field is not duplicated.

However, when I create and loop through the wp_query, the value of $post changes, and one of the post entires that appears in the results of the wp_query is then set to $post, and as a result, all the fields are then saved to the wrong post (rather than the one I have open).

Read More

The wp_reset_query() doesn’t appear to have any effect.

How can I correct this?

function save_bhour_details(){
    global $post;

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ){
        return;
    }

    if ( get_post_type($post) != 'bhours'){
        return;
    }

    //validate shortcode
    $bh_shortcode='';
    $error_shortcode_empty=false;
    $error_shortcode_duplicate=false;


    if(isset($_POST['bh_shortcode']) && !empty($_POST['bh_shortcode'])){
        $bh_shortcode=bh_strip_special_chars($_POST['bh_shortcode']);

        if(empty($bh_shortcode)){
            $error_shortcode_empty=true;
        }
        else{

            $query_validate = new WP_Query(array(
                'post_type'=>'bhours',
            ));

            while($query_validate->have_posts()){
                $query_validate->the_post();
                $bh_post_shortcode=array_shift(get_post_custom_values('bh_shortcode'));

                if($bh_post_shortcode==$bh_shortcode){
                    $error_shortcode_duplicate=true;
                    break;
                }
            }
            wp_reset_query();           
        }

    }
    else{
        $error_shortcode_empty=true;
    }

    if(!$error_shortcode_empty && !$error_shortcode_duplicate){
        update_post_meta($post->ID, 'bh_shortcode', $bh_shortcode);
    }
    else{
        update_post_meta($post->ID, 'bh_shortcode', '');
    }

}
add_action('save_post', 'save_bhour_details');

Related posts

Leave a Reply

1 comment

  1. Since wp_reset_query() and wp_reset_post() didn’t appear to do anything in this situation, here’s something that seems to work. I’m not entirely sure if this is the accepted approach, but I got it working by temporarily storing the $post value before the WP_Query, then setting it back to the $post variable after the query was complete.

    $currentpost = $post;
    
    $query = new WP_Query(/* ... */);
    
    while($query->have_posts()){
         $query->the_post();
         //do stuff
    }
    
    $post = $currentpost;