2

In my custom plugin, I have a custom post type and have a custom meta box for it. I have few fields in it, one of it is a check box. I want this check box to be checked by default when I go for a add new post and then proceed with the selection of the user ie checked/not checked.

I am adding the related codes ie: for the metabox and how I am saving it.

function coupon_add_metabox() {
    add_meta_box( 'coupon_details', __( 'Coupon Details', 'domain' ), 'wpse_coupon_metabox', 'coupons', 'normal', 'high' );
}

function wpse_coupon_metabox( $post ) {

    // Retrieve the value from the post_meta table
    $coupon_status   = get_post_meta( $post->ID, 'coupon_status', true );

    // Checking for coupon active option.
    if ( $coupon_status ) {
        if ( checked( '1', $coupon_status, false ) )
            $active = checked( '1', $coupon_status, false );
    }

    // Html for the coupon details
    $html = '';

    $html .= '<div class="coupon-status"><label for="coupon-status">';
    $html .= __( 'Active', 'domain' );
    $html .= '</label>';
    $html .= '<input type="checkbox" id="coupon-status-field" name="coupon-status-field" value="1"' . $active . ' /></div>';

    echo $html;
}

function wpse_coupons_save_details( $post_id ) {
    // If this is an autosave, our form has not been submitted, so we don't want to do anything.
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
        return $post_id;

    // Check the user's permissions.
    if ( ! current_user_can( 'activate_plugins' ) )
        return $post_id;

    $coupon_status   = sanitize_text_field( $_POST['coupon-status-field'] );

    // Update the meta field in the database.
    update_post_meta( $post_id, 'coupon_status', $coupon_status );
}
add_action( 'save_post', 'wpse_coupons_save_details' );
2

save_post being called multiple times is expected behavior, but because of how it’s used, you may not always want your code to execute until the user actually clicks on the save button. Like you have mentioned above regarding your requirement.

So you can check the current page ( i.e post-new.php ) in the wp-admin and can put conditions based upon that. Here is how you can implement.

global $pagenow;

// Checking for coupon active option.
if ( $coupon_status ) {
    if ( checked( '1', $coupon_status, false ) )
        $active = checked( '1', $coupon_status, false );
}

if ( 'post-new.php' == $pagenow ) {
    $active = 'checked';
}

========== Or you can check this too ============

if( ! ( wp_is_post_revision( $post_id) && wp_is_post_autosave( $post_id ) ) ) {
    // do the work that you want to execute only on "Add New Post"
} // end if

It’s worth understanding Why It Happens & what's goes on behind the scenes of save_post:

  • Posts go through an autosave process whenever it's created and whenever it's being drafted. As such, save_post is actually fired multiple times while a user is drafting a post.
  • When the user clicks "Save" or "Publish" the function fires thus kicking off yet-another-round of the function being called.
  • Finally, it's worth noting the the edit_post function fires once, but only when the user has actually edited an existing post.
  • -
  • It worked. Thanks a lot for the explanation at the bottom. – Maruti Mohanty Nov 22 '13 at 8:43
1

If the post is new the value of get_post_meta( $post->ID, 'coupon_status' ) will be null. Once saved, and the custom field is unchecked, it will be an empty string (""). So, you should just be able to add a check for a null value:

if ( checked( '1', $coupon_status, false ) || $coupon_status == null ) {
    $active = 'checked';
}
  • Sorry, but this doesn't work because when I go for add new post then save_post hook is fired and it calls my function wpse_coupons_save_details and hence saves a empty string. I don't know how and why save_post is called on add new post. I can say this because wordpress.org/plugins/debug-bar and wordpress.org/extend/plugins/… activated and i see the list of hooks – Maruti Mohanty Nov 21 '13 at 19:14
  • 1
    Your wpse_coupons_save_details function is exiting when doing an autosave so no custom field data should be saved therefore the coupon_status field should remain as null. I just tested this locally and it's working as expected. – Joey Yax Nov 21 '13 at 21:10
  • sadly this is not happening... for example try if ( is_null( $coupon_status ) ) { echo 'null'; } else { echo 'not null'; } in the wpse_coupon_metabox function and you would see not null even when you go for add new post – Maruti Mohanty Nov 22 '13 at 6:17
  • In this case the value of $coupon_status is never null, by default it is empty. – Maruti Mohanty Nov 22 '13 at 6:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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