Agregar acción solo en la publicación - no en la actualización

2 nov 2013, 17:21:08
Vistas: 31.1K
Votos: 10

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.

5
Comentarios

Algunas preguntas de contraparte: 1. ¿Estás seguro de que tienes correctos los estados de tus publicaciones? 2. Por la pregunta de ayer, sé que esto es sobre el sistema de valoración que implementaste - ¿lo único que intentas asegurar es que haya un valor devuelto o mostrado?

Nicolai Grossherr Nicolai Grossherr
2 nov 2013 18:05:46

¿Por qué no simplemente usar tu primer ejemplo pero verificando si los metadatos ya existen primero y solo agregarlos si no existen?

Milo Milo
2 nov 2013 18:10:01

Consulto las publicaciones por votes_count con meta_key="votes_count" y meta_value="meta_value_num" y hoy me di cuenta de que las consultas no muestran publicaciones sin votos. Revisé la base de datos y ahí los campos meta llamados votes_count solo tienen publicaciones con 1 o más votos. Así que llegué a la conclusión de que los campos meta se crean cuando un usuario vota y el siguiente paso en mi razonamiento fue crear automáticamente el campo meta votes_count con valor 0 para cada publicación nueva. Eso es lo que intento hacer con esta función. Intenté editar el código de ayer pero sin éxito.

th3rion th3rion
2 nov 2013 18:15:01

@milo tienes toda la razón

Nicolai Grossherr Nicolai Grossherr
2 nov 2013 18:18:19

No respondí las preguntas. 1. Estoy bastante seguro con los estados - cuando un usuario crea una publicación queda como "pendiente" y yo la publico después de revisarla 2. Creo que ya respondí eso.

th3rion th3rion
2 nov 2013 18:19:02
Todas las respuestas a la pregunta 3
1

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-draftpublish 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 draftpublish o pendingpublish.

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
    }
}
2 nov 2013 17:38:01
Comentarios

Gracias por la ayuda. Pensé en esa condición antes pero no me parecía lógico que vacío o '' equivalga a no existir. Creía que un campo meta con '' (o vacío como escribiste en el código) existe pero no tiene valor.

th3rion th3rion
2 nov 2013 18:56:08
1

Esto debería funcionar mejor:

add_action( 'publish_post' , 'my_func' , 10 , 2 );
function my_func( $ID , $post )
{
  if ( $post->post_date != $post->post_modified )
  {
    //ESTO ES UNA ACTUALIZACIÓN
  }
  else
  {
    //EL POST ACABA DE SER PUBLICADO
  }
}
25 mar 2017 03:55:36
Comentarios

esto no funciona la primera vez que se actualiza una publicación, después de la publicación inicial.

sarcastasaur sarcastasaur
24 ago 2019 06:58:37
0

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

}
}

}
2 nov 2013 18:51:02