Come impostare un post con data futura come pubblicato
Caso d'uso:
Ho un custom post type relativo a uno spettacolo musicale. L'orario dello spettacolo viene preso dalla data di pubblicazione del post, che è impostata a un momento futuro. Ho trovato una funzione che prende i post blog con data futura e li marca come pubblicati al salvataggio, mantenendo però la data futura, ma non sono riuscito a capire come adattarla per un custom post type.
La funzione è la seguente.
<?php
function setup_future_hook() {
// Sostituisce la funzione nativa future_post con la nostra versione
remove_action('future_post','show', '_future_post_hook');
add_action('future_post', 'show', 'publish_future_post_now');
}
function publish_future_post_now($id) {
// Imposta lo stato del nuovo post su "publish" invece che "future"
wp_publish_post($id);
}
add_action('init', 'setup_future_hook');
?>

Fantastico! Combinando entrambe le risposte di Mike e Jan ho creato questa soluzione che funziona solo sul post type in questione. Non abbiamo bisogno del condizionale show perché l'hook 'future_show' intercetta solo il post type show e lo aggiorna.
<?php
function setup_future_hook() {
// Sostituisce la funzione native future_post con la nostra versione
remove_action('future_show','_future_post_hook');
add_action('future_show','publish_future_post_now');
}
function publish_future_post_now($id) {
wp_publish_post($id);
}
add_action('init', 'setup_future_hook');
?>

Non posso dirlo con certezza poiché non ho il tuo sito per testare, ma credo che tu debba semplicemente rimuovere 'show'
dalle chiamate remove_action()
e add_action()
. La funzione wp_publish_post()
è indipendente dal tipo di post, almeno questo è quello che sembra leggendo il codice. Quindi prova così:
<?php
function setup_future_hook() {
// Sostituisci la funzione future_post nativa con una alternativa
remove_action('future_post', '_future_post_hook');
add_action('future_post', 'publish_future_post_now');
}
function publish_future_post_now($id) {
// Imposta lo stato del nuovo post su "publish" invece che "future"
wp_publish_post($id);
}
add_action('init', 'setup_future_hook');
?>
Ovviamente se vuoi limitarti solo agli spettacoli potresti fare qualcosa del genere (anche se la logica sarà più complicata se hai bisogno che funzioni anche con altri tipi di post):
function publish_future_post_now($id) {
$post = get_post($id);
if ('show' == $post->post_type)
wp_publish_post($id);
}
Spero sia utile?

Sì, il primo pezzo di codice è quello con cui ho iniziato e funziona sui normali post di WordPress, ma se aggiungi la condizione 'show' non funziona su nulla. Anche senza la condizione non funziona su un custom post type.

Ho letto la tua domanda più volte ma mi è ancora poco chiaro cosa stai cercando di ottenere se ignoriamo il codice suggerito che non funziona. Puoi chiarire cosa stai cercando di fare esattamente? Vuoi pubblicare il post alla data/ora che è nel post_date, o qualcos'altro? O l'hai già risolto?

Penso che questa azione venga chiamata da wp_transition_post_status
. Il codice è:
function wp_transition_post_status($new_status, $old_status, $post) {
do_action('transition_post_status', $new_status, $old_status, $post);
do_action("${old_status}_to_$new_status", $post);
do_action("${new_status}_$post->post_type", $post->ID, $post);
}
Quindi per i normali post futuri l'ultimo hook sarà future_post
, ma per il tuo tipo sarà future_show
o qualunque sia lo slug del tuo tipo.

Se tutto ciò che vuoi fare è aggiungere una data extra per gli 'orari degli spettacoli', potrebbe essere più semplice aggiungere un meta box che faccia esattamente questo - utilizzare la data di pubblicazione per simularlo potrebbe essere potenzialmente problematico, poiché WordPress lo imposterà su stato "futuro" ogni volta che viene aggiornato con una data di pubblicazione futura (credo), quindi dovrai agganciarti ogni volta che un post viene aggiornato per ripristinarlo. Inoltre, in questo modo potresti riservare la "Data di pubblicazione" per ciò per cui è pensata.
Probabilmente userei semplicemente un meta_key
e un meta box personalizzato. Anche se dipende da quanto complesse sono le tue query che mostrano i post.
Se imposti il meta_value come timestamp, puoi ancora ordinare per la data dell'orario dello spettacolo, oppure selezionare prima/dopo una certa data:
$events = get_posts( 'post_type=events&meta_key=show_time&meta_value=' . strtotime( '+1 week' ) . '&meta_compare=<&orderby=meta_value' );
Ottenerebbe tutti gli "eventi" con un orario di spettacolo non oltre una settimana dalla data corrente. Nota: quanto sopra non è testato, ma dovrebbe funzionare :)

Sono d'accordo al 100% - è molto meglio usare un meta box piuttosto che usare la data di pubblicazione come espediente per la data dell'evento.

Sì, un meta_box potrebbe funzionare ma ho trovato difficile aggiungere un bel selettore di data e ora jQuery. Quello predefinito di WP era molto meglio di qualsiasi cosa potessi creare.

WP Dev Nacin utilizza un semplice override di funzione:
// Rimuove l'azione che imposta i post come "future"
remove_action('future_post', '_future_post_hook');
// Aggiunge un filtro per modificare lo stato dei post
add_filter( 'wp_insert_post_data', 'nacin_do_not_set_posts_to_future' );
// Funzione che impedisce ai post di essere impostati come "future"
function nacin_do_not_set_posts_to_future( $data ) {
// Se il post è impostato come "future" ed è di tipo "post"
if ( $data['post_status'] == 'future' && $data['post_type'] == 'post' )
// Imposta lo stato del post come "publish" invece di "future"
$data['post_status'] = 'publish';
return $data;
}
