De ce funcția wp_update_post() nu actualizează câmpul post_status?
Folosesc acest cod pentru a insera/actualiza un tip de postare personalizată din front-end. Data este setată dintr-un datepicker jQuery personalizat.
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);
}
Aceasta funcționează când publică postarea pentru prima dată, setând-o corect ca publish
sau future
, cu data corectă.
Aceasta nu funcționează când editezi aceeași postare, nici de la publish
la future
și nici invers. Orice altceva este actualizat corect, cu excepția statusului postării/data_viitoare.
ACTUALIZARE 9 Octombrie Încep să cred că aceasta ar putea fi o eroare, așa că am inițiat o discuție pe lista de discuții wp-hackers, despre acest subiect. Există câteva rezultate de testare pe link.
ALTE ÎNCERCĂRI ESUATE:
Am încercat să las deciziile post_status
la wp_insert_post()
folosind:
elseif ('edit' == $operation) {
$newpostdata['post_status'] = '';
$newpostdata['ID'] = $post_id;
$err = wp_update_post($newpostdata);
}
Și acest lucru setează statusul postării la draft
păstrând în același timp datele solicitate.
Am încercat și să apelez wp_transition_post_status()
din nou (este apelată o dată în wp_insert_post()):
elseif ('edit' == $operation) {
$newpostdata['ID'] = $post_id;
$err = wp_update_post($newpostdata);
wp_transition_post_status($old_status, $status, $post_id);
}
dar nici asta nu a funcționat.
Nu mai am idei. Aveți vreo sugestie?

Răspunsul nu ar putea fi mai simplu.
După cum a subliniat Otto pe lista wp-hackers, problema a fost că nu am setat post_date_gmt
când am folosit wp_update_post()
.
Codul final arată astfel:
if ( $post_date < strtotime( "tomorrow" ) ) {
$status = 'publish';
$newpostdata['post_status'] = $status;
$newpostdata['post_date'] = date( 'Y-m-d H:i:s', $post_date );
// De asemenea, trebuie să transmitem 'post_date_gmt' pentru ca WordPress să gestioneze corect datele
$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 );
// De asemenea, trebuie să transmitem 'post_date_gmt' pentru ca WordPress să gestioneze corect datele
$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);
}

Am încercat și codul de mai sus folosind wp_update_post()
, dar nu funcționează bine cu WordPress 3.9, lasă post_status
gol și șterge toate câmpurile personalizate. Prin urmare, am creat o interogare personalizată folosind clasa wpdb
. Sper că acest lucru va funcționa pentru toți:
$wpdb->query(
$wpdb->prepare(
"UPDATE $wpdb->posts SET post_status = 'draft' WHERE ID = %d",
$post_id
)
);
Și acest lucru a funcționat bine atât pe localhost, cât și pe hosting.

Bun venit pe [wordpress.se]. Sper că nu te deranjează modificările. Am rezolvat instrucțiunea prepare.

Actualizăm statusul postărilor în mod constant, iată un exemplu de cum le permitem utilizatorilor (în editorul front-end pe care l-am construit) să "pauzeze" anunțurile prin schimbarea lor în stadiul de draft:
if ($action == 'pause') {
$my_post = array();
$my_post['ID'] = $aid; // ID-ul anunțului
$my_post['post_status'] = 'draft'; // Schimbă statusul în draft
wp_update_post($my_post); // Actualizează postarea
$action_msg = __('Anunțul a fost pus pe pauză', 'mytheme'); // Mesaj de confirmare
}

Nu este problema OP-ului, dar ca un punct de referință notabil pentru alții care ajung aici în căutarea unei probleme similare, unde wp_update_post()
nu actualizează post_status
...
După cum a menționat @adrianthedev mai sus într-un comentariu la OP, rețineți că lungimea maximă a unui status personalizat al postării este de 20 de caractere.
https://developer.wordpress.org/reference/functions/register_post_status/#comment-3927
Când se depășesc 20 de caractere, puteți înregistra statusul personalizat al postării folosind register_post_status()
, dar în prezent nu puteți seta o postare să îl folosească cu wp_update_post()
, cel puțin începând cu WordPress v5.5.1
