Aggiungere un'azione solo alla pubblicazione del post - non all'aggiornamento

2 nov 2013, 17:21:08
Visualizzazioni: 31.1K
Voti: 10

Ho un'azione che aggiunge un campo meta con un valore alla pubblicazione del post. Il problema è che quando aggiorno il post, il campo meta viene reimpostato al valore predefinito.

Ho già provato 'new_to_publish' invece di 'publish_post' ma non funziona.

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

Non riesco ancora a farlo funzionare

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

Per come lo capisco io - ogni volta che lo stato cambia da pending a publish esegue ciò che c'è dentro l'if. Ma non funziona.

Nel mio sito ho un sistema di valutazione dei post con un campo meta 'votes_count' dove vengono memorizzati i voti. Quando faccio una query di votes_count dal più alto al più basso non mostra i post senza voti, quindi ho bisogno di popolarlo con il valore predefinito 0 per includerli nella query. Tutto funziona bene ma quando aggiorno i voti vengono reimpostati a 0... I post vengono pubblicati dagli utenti con stato pending che io controllo e pubblico.

5
Commenti

Alcune controdomande: 1. Sei sicuro di aver impostato correttamente gli stati dei post? 2. So - dalla domanda di ieri - che riguarda il sistema di valutazione che hai implementato - l'unica cosa che stai cercando di fare è assicurarti che venga restituito o visualizzato un valore?

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

perché non usare semplicemente il tuo primo esempio ma verificare prima se i metadati esistono già e aggiungerli solo se non esistono?

Milo Milo
2 nov 2013 18:10:01

Eseguo query sui post per votes_count con meta_key="votes_count" e meta_value="meta_value_num" e oggi ho realizzato che le query non mostrano i post senza voti. Ho controllato il database e lì i campi meta chiamati votes_count esistono solo per i post con 1 o più voti. Quindi sono giunto alla conclusione che i campi meta vengono creati quando un utente vota e il passo successivo nel mio ragionamento è stato creare automaticamente il campo meta votes_count con valore 0 per ogni nuovo post. Questo è quello che sto cercando di fare con questa funzione. Ho provato a modificare il codice di ieri ma senza successo.

th3rion th3rion
2 nov 2013 18:15:01

@milo hai assolutamente ragione

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

Non ho risposto alle domande. 1. Sono abbastanza sicuro riguardo agli stati - quando un utente crea un post è "pending" e io lo pubblico dopo averlo controllato 2. Penso di aver già risposto a questo.

th3rion th3rion
2 nov 2013 18:19:02
Tutte le risposte alla domanda 3
1

Come ha sottolineato @milo nel commento, verificare se il post meta esiste è il modo più semplice per ottenere ciò che vuoi - in questo modo:

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




→ Alla creazione/pubblicazione, non agli aggiornamenti

Mantengo questa parte perché si adatta al contesto di fare le cose alla pubblicazione e non agli aggiornamenti. Ma auto-draftpublish funziona solo alla prima pubblicazione di un articolo e solo se l'articolo viene pubblicato direttamente. Potrebbe essere necessario coprire più casi, ad esempio draftpublish o pendingpublish.

Potresti provare:

//è specifico perché specifichi l'hook in questo modo {$old_status}_to_{$new_status}
add_action( 'auto-draft_to_publish', 'wpse120996_specific_post_status_transition' );
function wpse120996_specific_post_status_transition() { 
        //il tuo codice
}

invece di usare new_to_publish.

→ Dai un'occhiata a Transizioni dello stato degli articoli per ulteriori informazioni.

Oppure potresti lavorare con l'hook generico transition_post_status in questo modo:

//è generico perché specifichi gli stati degli articoli all'interno della funzione, non tramite l'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' ) {
        //il tuo codice
    }
}


Un altro metodo pulito per fare le cose alla pubblicazione o più precisamente alla prima creazione e non agli aggiornamenti sarebbe procedere come mostrato di seguito. Ho optato per usare l'hook save_post, ma questo potrebbe essere fatto anche con l'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 se l'articolo non è ancora nel database
    if( get_post( $post_id ) == null ) {
        //il tuo codice
    }
}
2 nov 2013 17:38:01
Commenti

Grazie per l'aiuto. Avevo pensato a una condizione simile prima, ma non mi sembrava logico che vuoto o '' equivalga a non esistente. Pensavo che un campo meta con '' (o vuoto come hai scritto nel codice) esistesse ma non avesse un valore.

th3rion th3rion
2 nov 2013 18:56:08
1

Questo dovrebbe funzionare al meglio:

add_action( 'publish_post' , 'my_func' , 10 , 2 );
function my_func( $ID , $post )
{
  if ( $post->post_date != $post->post_modified )
  {
    //QUESTO È UN AGGIORNAMENTO
  }
  else
  {
    //IL POST È APPENA STATO PUBBLICATO
  }
}
25 mar 2017 03:55:36
Commenti

questo non funziona la prima volta che un post viene aggiornato, dopo la pubblicazione iniziale.

sarcastasaur sarcastasaur
24 ago 2019 06:58:37
0

Sorprendentemente funziona. Forse non sono così stupido come pensavo. Grazie a entrambi per l'aiuto.

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

    global $wpdb;

    // Controlla se il campo personalizzato esiste già
    $meta_count = get_post_meta($post_ID, "votes_count", true);
    if($meta_count == '') {
        // Evita di aggiornare durante le revisioni
        if(!wp_is_post_revision($post_ID)) {
            // Imposta il conteggio voti iniziale a 0
            update_post_meta($post_ID, 'votes_count', '0');
        }
    }

}
2 nov 2013 18:51:02