Perché wp_update_post() non aggiorna il campo post_status?
Sto utilizzando questo codice per inserire/aggiornare un custom post type dal front-end. La data viene impostata da un datepicker jQuery personalizzato.
if (strtotime($date) < strtotime('tomorrow')) {
$newpostdata['post_status'] = 'publish';
} elseif (strtotime($date) > strtotime('today')) {
$newpostdata['post_status'] = 'future';
$newpostdata['post_date'] = date('Y-m-d H:i:s', strtotime($date));
}
if ('insert' == $operation) {
$err = wp_insert_post($newpostdata, true);
} elseif ('edit' == $operation) {
$newpostdata['ID'] = $post_id;
$err = wp_update_post($newpostdata);
}
Funziona quando pubblico il post per la prima volta, impostandolo correttamente come publish
o future
, con la data corretta.
Non funziona quando modifico lo stesso post, né da publish
a future
né viceversa. Tutto il resto viene aggiornato correttamente, tranne lo stato del post/future_date.
AGGIORNAMENTO 9 ottobre Sto iniziando a pensare che possa essere un bug, quindi ho avviato una discussione nella mailing list wp-hackers. Nel link ci sono alcuni risultati di test su installazioni fresh.
ALTRI TENTATIVI FALLITI:
Ho provato a lasciare le decisioni su post_status
a wp_insert_post()
usando:
elseif ('edit' == $operation) {
$newpostdata['post_status'] = '';
$newpostdata['ID'] = $post_id;
$err = wp_update_post($newpostdata);
}
E questo imposta lo stato del post su draft
mantenendo le date richieste.
Ho anche provato a richiamare wp_transition_post_status()
nuovamente (viene chiamato una volta dentro wp_insert_post()):
elseif ('edit' == $operation) {
$newpostdata['ID'] = $post_id;
$err = wp_update_post($newpostdata);
wp_transition_post_status($old_status, $status, $post_id);
}
ma anche questo non sembra funzionare.
Sto finendo le idee. Qualche suggerimento?

La risposta non potrebbe essere più semplice.
Come sottolineato da Otto nella mailing list wp-hackers, il problema era che non impostavo post_date_gmt
quando utilizzavo wp_update_post()
.
Il codice finale risulta così:
if ( $post_date < strtotime( "tomorrow" ) ) {
$status = 'publish';
$newpostdata['post_status'] = $status;
$newpostdata['post_date'] = date( 'Y-m-d H:i:s', $post_date );
// Passo anche 'post_date_gmt' in modo che WP gestisca correttamente le date
$newpostdata['post_date_gmt'] = gmdate( 'Y-m-d H:i:s', $post_date );
} elseif ( $post_date > strtotime( 'today' ) ) {
$status = 'future';
$newpostdata['post_status'] = $status;
$newpostdata['post_date'] = date( 'Y-m-d H:i:s', $post_date );
// Passo anche 'post_date_gmt' in modo che WP gestisca correttamente le date
$newpostdata['post_date_gmt'] = gmdate( 'Y-m-d H:i:s', $post_date );
}
if ('insert' == $operation) {
$err = wp_insert_post($newpostdata, true);
} elseif ('edit' == $operation) {
$newpostdata['ID'] = $post_id;
$err = wp_update_post($newpostdata);
}

Ho anche provato il codice sopra utilizzando wp_update_post()
, ma non funziona bene con WordPress 3.9, rende vuoto il post_status
e cancella tutti i campi personalizzati. Ho quindi creato una query personalizzata utilizzando la classe wpdb
. Spero che funzioni anche per voi:
$wpdb->query(
$wpdb->prepare(
"UPDATE $wpdb->posts SET post_status = 'draft' WHERE ID = %d",
$post_id
)
);
e questo ha funzionato bene sia sul mio localhost che sull'hosting.

Benvenuto su [wordpress.se]. Spero non ti dispiacciano le modifiche. Ho corretto l'istruzione prepare.

Aggiorniamo lo stato dei post continuamente, ecco un esempio di come permettiamo agli utenti (sul front end editor che abbiamo costruito) di "mettere in pausa" gli annunci cambiandoli in bozza:
if ($action == 'pause') {
$my_post = array();
$my_post['ID'] = $aid;
$my_post['post_status'] = 'draft';
wp_update_post($my_post);
$action_msg = __('L\'annuncio è stato messo in pausa', 'mytheme');
}

Non è il problema dell'OP, ma come un punto di riferimento degno di nota per altri che arrivano qui cercando una soluzione a un problema simile in cui wp_update_post()
non aggiorna post_status
...
Come ha notato @adrianthedev sopra in un commento all'OP, tieni presente che la lunghezza massima di uno stato personalizzato del post è di 20 caratteri.
https://developer.wordpress.org/reference/functions/register_post_status/#comment-3927
Quando si superano i 20 caratteri, è possibile registrare lo stato personalizzato del post utilizzando register_post_status()
, ma attualmente non è possibile impostare un post con questo stato usando wp_update_post()
, almeno a partire da WordPress v5.5.1
