I have some custom meta values to a custom post type ('event'). The custom post type is displayed in the admin and the custom meta fields are appearing fine. I am using save_post_{$post->post_type} hook to validate the meta fields and change the post_status to draft (using wp_update_post) depending upon the validation of the meta fields and the newly set post_status.


All things are working except the top right section (in the admin post edit page) do not reflect the change of status. If I publish a post, the validation is working fine with the post_status set to draft depending upon the set condition inside save_post_{$post->post_type}. But the top right corner of UI shows 'the post is now live', 'visit links' etc.(Screens #1). Upon refreshing the page, the proper draft status view is reflected (Screens #2).

Screens #1:

Although the post_status is successfully set to draft from save_post_{$post->post_type}, the UI view reflects the 'published' status.

Although the post_status is successfully set to draft from save_post_{$post->post_type} the UI view reflects the 'published' status. enter image description here

Screens #2:

Upon refreshing, the actual draft status is restored:

enter image description here

public function __construct()
    $this->sconfig= ['post_type'=> 'event', 'slug'=>'events'];
    post type and meta declarations
    add_action('save_post_'.$this->sconfig['post_type'], array($this, 'event_mbox_save'), 10, 2);

function event_mbox_save($post_id, $post=false)
    if (!isset($_POST['event_mbox_nonce']) || !wp_verify_nonce($_POST['event_mbox_nonce'], basename(__FILE__)))
        return $post_id;
    $valstat= $this->get_meta_posted_vals($_POST); // Validates the custom meta values. Returns $valstat['stat']= 0 if invalid and $valstat['log']= 'error message'.
    $original_pstat= $_POST['original_post_status'];
    $new_pstat= $_POST['post_status'];
    $insmeta= true;
    $errmsg= '';

    if(($valstat['stat'] == 0) && (!empty($original_pstat)))
         if(($new_pstat == 'publish') || ($new_pstat == 'future'))
            remove_action('save_post_'.$this->sconfig['post_type'], array($this, 'event_mbox_save'), 10, 3);
            wp_update_post(array( 'ID' => $post_id, 'post_status' => 'draft') ); // Setting the post to draft
            add_action('save_post_'.$this->sconfig['post_type'], array($this, 'event_mbox_save'), 10, 3);
            $errmsg= 'ERROR: '.$valstat['log'].' ('.$this->sconfig['post_type'].' reverted to '.$original_pstat.' status.)';
            $insmeta= false; // setting meta insertion false
        setcookie('event8273_add_notice', $errmsg, 0, '/' );

        $evabstract = isset($postVal['evabstract']) ? $postVal['evabstract'] : '';
        if (empty($evabstract))
            add_post_meta($post_id, 'evabstract', $_POST['evabstract'], true);
            update_post_meta($post_id, 'evabstract', $_POST['evabstract']);


I have tried using wp_insert_post_data alongwith redirect_post_location which did not work either.


1 Answer 1


After some research, I altered my approach to validate the meta values in the following way:

  1. Create a new meta key(for post type) to store the validation (0 and 1).
  2. Initiate it with 0.
  3. This need not be kept/shown in the meta form.
  4. While saving the meta fields (preferably within save_post hook), set its value depending upon the validation.
  5. Use this meta value to detect the validation status of the post. For example you can display/hide the post depending upon this value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.