Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

share|improve this question
    
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? –  ialocin Nov 2 '13 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 '13 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 '13 at 16:15
    
@milo you're absolutely right –  ialocin Nov 2 '13 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 '13 at 16:19
add comment

2 Answers

up vote 1 down vote accepted

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
    }
}
share|improve this answer
    
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 '13 at 16:56
add comment

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');

}
}

}
share|improve this answer
    
+1 for getting there yourself –  ialocin Nov 2 '13 at 17:00
    
Eventually Ill have to pay you - thanks again :) –  th3rion Nov 2 '13 at 17:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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