What action is called when drafts are saved?

I would like to add a metadata field to the current post based on a checkbox in a custom meta box to be able to toggle my custom plugin on a post by post basis.

For this I coded the following things

Read More
  1. generate a meta box on the new post and new page page
  2. handle the value of the checkbox in the meta box and set the metadata of the post or page accordingly

I succeded in 1. but I have problems with number 2. I have the following code to handle the setting of the metadata:

Update metadata depending on value of checkbox in meta box

// register action
add_action( 'save_post', 'cl_save_postdata');
/* When the post is saved, saves our custom data */

function cl_save_postdata( $post_id ) {
  // check if $post_id is just a revision id and if so get the parent id
  if($parent_id = wp_is_post_revision($post_id)){
    $post_id = $parent_id;
  }  
  // verify this came from the our screen and with proper authorization,
  // because save_post can be triggered at other times

  if ( !wp_verify_nonce( EMU2_I18N_DOMAIN, plugin_basename(__FILE__) ) )
      return $post_id;
  // verify if this is an auto save routine. 
  // If it is our form has not been submitted, so we dont want to do anything
  if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
      return $post_id;

  // Check permissions
  if ( 'page' == $_POST['post_type'] ) {
    if ( !current_user_can( 'edit_page', $post_id ) )
        return $post_id;
  } else {
    if ( !current_user_can( 'edit_post', $post_id ) )
        return $post_id;
  }

  // OK, we're authenticated: we need to find and save the data

  if ($_POST['cl-activated']) {
     add_post_meta( $post_id, 'cl-activated', true, true) or update_post_meta( $post_id, 'cl-activated', true);
  } elseif (get_post_meta ($post_id, 'cl-activated', true)) {
    delete_post_meta( $post_id, 'cl-activated');
  }
  return $cl_is_activated;
}

The idea of this code is to set or unset the ‘cl-activated’ metadata depending on the checkbox value. The form of the meta box is the following:

Generate inner meta box HTML

function cl_generate_inner_box($post, $metabox) {
      // Use nonce for verification
  wp_nonce_field( plugin_basename(__FILE__), EMU2_I18N_DOMAIN );

  // The actual fields for data entry
  echo '<label for="cl-activated">';
       _e("Activate collect links", EMU2_I18N_DOMAIN );
  echo '</label> ';
  echo '<input type="checkbox" id="cl-activated" name="cl-activated" value='.$metabox['args']['cl-parameter-name'];
  if (get_post_meta($post_id, 'cl-activated', true)==true) {
    echo ' checked="checked"';
  }
  echo ' />';
}

My problems

  1. the metadata of the post is not set. I tried looking up the metadata in the wp-postmeta table in the database and it is not there, no matter what I do.
  2. Is there a way to save the metadata even if the post or page is still a draft and the user only hits save draft? If I use the action save_post like I am doing now, I have the impression that it is called only when the post is already published.

Edit

The first problem is solved. I have double-checked the transition hooks that are provided by WordPress. It seemed to me that the save_post hook should be fired when I edit a post. However what happens is that it is called when I click on the new post button but not when I then save the post as a draft.

To clearify I need a hook that allows me to get a function executed when the user has changed anything on the post to see if my custom checkbox has been changed so I can update the post’s metadata accordingly.

Related posts

Leave a Reply

1 comment

  1. After WP 2.3 you have for all status an hook: {$new_status}_{$post->post_type}

    Alternative you can use ans if for the status on hook save_post; an example for post_type post, you can change this ‘post’ to your post_type or defaults form WP:

        public function set_status_private($id, $post) {
    
            if ( is_object($post) && 
                 'post' === $post->post_type && 
                 'publish' === $post->post_status
                ) {
                $post->post_status = 'private';
    
                wp_update_post($post);
            }
        }
    

    I hope this helps you.