Aggiungere un'azione solo alla pubblicazione del post - non all'aggiornamento
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.

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-draft
→ publish
funziona solo alla prima pubblicazione di un articolo e solo se l'articolo viene pubblicato direttamente. Potrebbe essere necessario coprire più casi, ad esempio draft
→ publish
o pending
→ publish
.
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
}
}

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