10

I have action which adds meta field with value on post publish. Problem is that when I update post meta field is reset to default value.

I already tried 'new_to_publish' instead of 'publish_post' but it doesn't work.

add_action('publish_post', 'add_custom_field_automatically');
function add_custom_field_automatically($post_ID) {
  global $wpdb;

  if(!wp_is_post_revision($post_ID)) {
    update_post_meta($post_ID, 'votes_count', '0');

}
}

Still can't make it work

add_action( 'transition_post_status', 'wpse120996_post_status_publish', 10, 3 );
function wpse120996_post_status_publish( $new_status, $old_status, $post_ID ) { 
    if ( $new_status == 'publish' && $old_status == 'pending' ) {
          global $wpdb;

  if(!wp_is_post_revision($post_ID)) {
    update_post_meta($post_ID, 'votes_count', '0');
    }
}}

As I can understand it - every time status changes from pending to publish do whatever is inside if. But it doesn't work.

In my site I have post rating system with meta field 'votes_count' where are stored votes. When I query votes_count from highest to lowest it doesn't show posts with no votes, so I need to populate it with default value 0 to include them into query. Everything works fine but when i update votes are reset to 0... Posts are published by users with pending status which I check and publish.

5
  • Some counter questions: 1. Are you sure if you got your post statuses right? 2. I know - from yesterdays question - this is about the rating system you implemented - is the only thing you are trying to make sure that there is a value returned or echoed? Nov 2, 2013 at 16:05
  • 1
    why not just use your first example but check if the meta data already exists first and only add it if it doesn't?
    – Milo
    Nov 2, 2013 at 16:10
  • I query post by votes_count with meta_key="votes_count" and meta_value="meta_value_num" and today I realized that queries don't show posts with no votes. I checked database and there meta fields named votes_count have only posts with 1 or more votes. So I came into conclusion that meta fields are created when user votes and next step in my thinking was to auto create meta field votes_count with value 0 for every new post. That Im trying to make with this function. I tried to edit code from yesterday but with no luck.
    – th3rion
    Nov 2, 2013 at 16:15
  • @milo you're absolutely right Nov 2, 2013 at 16:18
  • I didnt answer questions. 1. Im pretty sure with statuses - when user creates post its "pending" and I publish it after checking 2. I think I already answered it.
    – th3rion
    Nov 2, 2013 at 16:19

3 Answers 3

4

Like @milo pointed out in the comment, checking if the post meta exists is the easiest way to achieve what you want - like this:

add_action('publish_post', 'wpse120996_add_custom_field_automatically');
function wpse120996_add_custom_field_automatically($post_id) {
    global $wpdb;
    $votes_count = get_post_meta($post_id, 'votes_count', true);
    if( empty( $votes_count ) && ! wp_is_post_revision( $post_id ) ) {
        update_post_meta($post_id, 'votes_count', '0');
    }
}




→ On creation/publish not on updates

I'm keeping this, because it fits the matter of doing things on publish and not on update. But auto-draftpublish only works on first publishing a post and only if a post gets published directly. There might be the need to cover more cases, for example draftpublish or pendingpublish.

You could try:

//it's specific because you specify the hook like this {$old_status}_to_{$new_status}
add_action( 'auto-draft_to_publish', 'wpse120996_specific_post_status_transition' );
function wpse120996_specific_post_status_transition() { 
        //your code
}

instead of using new_to_publish.

→ Take a look at Post Status Transitions for additional information.

Or you could work with the generic hook transition_post_status like this:

//it's generic because you specify post statuses inside the function not via the hook
add_action( 'transition_post_status', 'wpse120996_generic_post_status_transition', 10, 3 );
function wpse120996_generic_post_status_transition( $new_status, $old_status, $post ) { 
    if ( $new_status == 'publish' && $old_status == 'auto-draft' ) {
        //your code
    }
}


Another neat method doing things on publish or to be exact first creation and not on updates would be going like shown below. I opted for using the save_post hook, but this could be done with the publish_post hook too.

add_action('save_post', 'wpse120996_on_creation_not_update');
function wpse120996_on_creation_not_update($post_id) {
    //get_post( $post_id ) == null checks if the post is not yet in the database
    if( get_post( $post_id ) == null ) {
        //your code
    }
}
1
  • Thank you for help. I thought about such conditional earlier but it was not logical for my that empty or '' equals not exist. I thought that meta field with '' (or empty as you wrote the code) exists but has no value.
    – th3rion
    Nov 2, 2013 at 16:56
3

This should work best:

add_action( 'publish_post' , 'my_func' , 10 , 2 );
function my_func( $ID , $post )
{
  if ( $post->post_date != $post->post_modified )
  {
    //THIS IS AN UPDATE
  }
  else
  {
    //POST JUST GOT PUBLISHED
  }
}
1
  • this does not work the first time a post has been updated, after the initial publish. Aug 24, 2019 at 3:58
1

Suprisingly it works. Maybe I'm not as stupid as I thought. Thank you both for help.

add_action('publish_post', 'add_custom_field_automatically');
function add_custom_field_automatically($post_ID) {

global $wpdb;

$meta_count = get_post_meta($post_ID, "votes_count", true);
if($meta_count == '') {
if(!wp_is_post_revision($post_ID)) {
    update_post_meta($post_ID, 'votes_count', '0');

}
}

}
0

Your Answer

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

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