Agregar acción solo en la publicación - no en la actualización
Tengo una acción que agrega un campo meta con un valor cuando se publica un post. El problema es que cuando actualizo el post, el campo meta se reinicia al valor predeterminado.
Ya intenté usar 'new_to_publish' en lugar de 'publish_post' pero no funciona.
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');
}
}
Todavía no puedo hacer que funcione
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');
}
}}
Según entiendo - cada vez que el estado cambia de pendiente a publicado debe hacer lo que está dentro del if. Pero no funciona.
En mi sitio tengo un sistema de calificación de posts con un campo meta 'votes_count' donde se almacenan los votos. Cuando consulto votes_count de mayor a menor no muestra posts sin votos, por lo que necesito poblarlo con un valor predeterminado 0 para incluirlos en la consulta. Todo funciona bien pero cuando actualizo, los votos se reinician a 0... Los posts son publicados por usuarios con estado pendiente que yo reviso y publico.

Como @milo señaló en el comentario, verificar si el meta del post existe es la forma más fácil de lograr lo que deseas - así:
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');
}
}
→ En la creación/publicación, no en actualizaciones
Mantengo esto porque se ajusta al tema de hacer cosas al publicar y no al actualizar. Pero auto-draft
→ publish
solo funciona al publicar por primera vez un post y solo si el post se publica directamente. Podría ser necesario cubrir más casos, como draft
→ publish
o pending
→ publish
.
Podrías probar:
//Es específico porque especificas el hook así {$old_status}_to_{$new_status}
add_action( 'auto-draft_to_publish', 'wpse120996_specific_post_status_transition' );
function wpse120996_specific_post_status_transition() {
//tu código
}
en lugar de usar new_to_publish
.
→ Echa un vistazo a Transiciones de Estado del Post para información adicional.
O podrías trabajar con el hook genérico transition_post_status
así:
//Es genérico porque especificas los estados del post dentro de la función, no a través del 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' ) {
//tu código
}
}
Otro método ingenioso para hacer cosas al publicar o, para ser exactos, en la primera creación y no en actualizaciones sería como se muestra a continuación. Opté por usar el hook save_post
, pero esto también podría hacerse con el hook publish_post
.
add_action('save_post', 'wpse120996_on_creation_not_update');
function wpse120996_on_creation_not_update($post_id) {
//get_post( $post_id ) == null verifica si el post aún no está en la base de datos
if( get_post( $post_id ) == null ) {
//tu código
}
}

Sorprentemente funciona. Quizás no soy tan tonto como pensaba. Gracias a ambos por la ayuda.
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');
}
}
}
