È possibile nell'ambito dell'azione save_post determinare se si tratta di un nuovo post in fase di creazione o di un post esistente in fase di aggiornamento?
È possibile nell'ambito dell'azione save_post determinare se si tratta di un nuovo post in fase di creazione o di un post esistente in fase di aggiornamento?
Risposte:
Dalla versione 3.7 di WordPress. - IIRC - l' save_post
hook - ulteriori informazioni sull'hook e sul suo utilizzo in Codice di riferimento:save_post
e Codice:save_post
- ha un terzo parametro $update
che può essere utilizzato per determinare proprio questo.
@param int $ post_ID ID post.
@param WP_Post $ post Oggetto post.
@param bool $ update Se questo è un post esistente in fase di aggiornamento o meno.
Nota:
$update
non è sempre true
- puoi vederlo e testarlo tu stesso con il codice seguente. Tuttavia, non è ben documentato, probabilmente lontano dal nome ottimale, e quindi crea aspettative fuorvianti. Sotto il codice può essere usato per alcuni debug, gioca con quando intercettare l'esecuzione del codice, perché altrimenti non vedrai le informazioni / i messaggi. Penso che il colpevole del comportamento ingannevole sia la gestione delle revisioni e dei salvataggi automatici, che potrebbero essere disabilitati, ma non lo consiglio e non l'ho testato. Non sono sicuro che ciò meriti un Biglietto Trac , quindi non ne ho aperto uno, se lo pensi, segui il link e fallo da solo. A parte questo, come indicato nei commenti, se hai un problema specifico, pubblica una nuova domanda.
add_action( 'save_post', 'debug_save_post_update', 10, 3 );
function debug_save_post_update( $ID, $post, $update ) {
echo '<pre>';
print_r( $post ); echo '<br>';
echo '$update == ';
echo $update ? 'true' : 'false';
//conditions
if( ! $update && $post->post_status == "auto-draft" ) {
// applies to new post
echo ' && $post->post_status == "auto-draft"';
//die();
} else if ( ! $update ) {
// applies basically to the (auto saved) revision
//die();
} else {
// applies to updating a published post
// when there is a revision, which is normally the case,
// standard behavior of WordPress, then it is considered
// an update, which is where the confusion sets in
// there are other methods, like checking time or post status
// depending on your use case it might be more appropriate
// to use one of those alternatives
//die();
}
echo '</pre>';
//die();
}
$update
parametro è SEMPRE vero anche quando si tratta di un nuovo post. Quindi questo parametro è inutile. Non sono sicuro che abbia mai funzionato, ma sicuramente non funziona come è documentato nell'ultima versione di WordPress 4.8.
wp_publish_post
, allora sì. Ma questo non è vero per il suo utilizzo in wp_insert_post
. Ho scritto una funzione di debug, la aggiungo alla risposta.
save_post
hook ha un terzo parametro che è sempre impostato su TRUE, quindi non sono sicuro di cosa abbia a che fare con altri hook, non parlando di altri hook. Sto parlando del gancio nella tua risposta. Questo non è corretto
wp_insert_post()
, wp_publish_post()
. Quest'ultimo è solo post futuri, $update
è impostato per essere sempre true
. Altrimenti, per quanto riguarda wp_insert_post()
, $update
non è sempre true
.
Il modo in cui eseguo questo controllo (all'interno di una funzione agganciata) consiste nel confrontare la data di pubblicazione e la data di modifica (in GMT per la standardizzazione)
function check_new_vs_update( $post_id ){
$myPost = get_post($post_id);
$post_created = new DateTime( $myPost->post_date_gmt );
$post_modified = new DateTime( $myPost->post_modified_gmt );
if( abs( $post_created->diff( $post_modified )->s ) <= 1 ){
// New post
}else{
// Updated post
}
}
add_action('save_post', 'check_new_vs_update' );
Questo funziona perché anche al momento della creazione al post è associata una data "modificata", che è esattamente la stessa della data "creata", ma consentiamo una variazione di 1 secondo in entrambi i casi nel caso in cui un secondo ticchetti durante la creazione di il post.
post_date_gmt
è 2019-03-12 01:31:30
e post_modified_gmt
è 2019-03-12 01:31:31
. :(
Ho finito per verificare l'esistenza di un valore personalizzato prima di impostarlo. In questo modo, se si tratta di un post appena creato, il valore personalizzato non esisterebbe ancora.
function attributes_save_postdata($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!wp_verify_nonce($_POST['_attributes_noncename'], plugin_basename(__FILE__))) return;
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) return;
} else {
if (!current_user_can('edit_post', $post_id)) return;
}
$termid = get_post_meta($post_id, '_termid', true);
if ($termid != '') {
// it's a new record
$termid = 'update';
} else {
// it's an existing record
}
update_post_meta($post_id, '_termid', $termid);
}
add_action('save_post', 'attributes_save_postdata');
Esempio di risposta ialocin con paremetro "aggiornamento":
function save_func($ID, $post,$update) {
if($update == false) {
// do something if its first time publish
} else {
// Do something if its update
}
}
add_action( 'save_post', 'save_func', 10, 3 );
if($update)
o mantenere il nuovo blocco per primo ma usando if( ! $update )
. Quest'ultimo porterà OP in una migliore pratica ed è preferito al tuo metodo dagli standard di codifica di WordPress in casi come l' operatore ternario
È possibile utilizzare l'hook di azioni pre_post_update per il codice di aggiornamento e save_post per il nuovo codice postale. Funziona prima che un post venga aggiornato.
save_post
l'hook viene attivato sia quando un post viene creato e aggiornato (dopo che WordPress lo ha salvato nel database). pre_post_update
viene attivato quando un post viene aggiornato, ma prima che il post venga aggiornato, questo può essere importante.
Come ha suggerito Darshan Thanki (e Stephen Harris ha ulteriormente elaborato), puoi sfruttarlo pre_post_update
a tuo vantaggio.
global $___new_post;
$___new_post = true;
add_action(
'pre_post_update',
function() {
global $___new_post;
$___new_post = false;
},
0
);
function is_new_post() {
global $___new_post;
return $___new_post;
}
Il motivo per cui ho usato i globali è perché function is_new_post() use ( &$new_post )
non è valido in PHP (scioccante ...), quindi il pull in quella variabile nell'ambito della funzione non funziona - da qui il globale.
Si noti che questo può davvero essere utilizzato in modo affidabile solo all'interno / dopo l' save_post
evento (che di solito è sufficiente, almeno per quello che stiamo facendo con esso).
Quando viene attivato save_post, tutte le informazioni su quel post sono già disponibili, quindi in teoria potresti usarle
function f4553265_check_post() {
if (!get_posts($post_id)) {
// if this is a new post get_posts($post_id) should return null
} else {
// $post_id already exists on the database
}
}
add_action('save_post','f4553265_check_post');
questo non è testato, però. =)
save_post
post stesso sarebbe già stato salvato nel database, quindi get_posts
restituirebbe il post corrente.
Un altro approccio che utilizza una funzione integrata e nessuna aggiunta al database comporterebbe get_post_status()
.
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
Tieni presente, tuttavia, che potrebbe non essere appropriato se prevedi di reimpostare lo stato su "bozza": le istruzioni verranno ripetute al successivo aggiornamento del post. A seconda del contesto, è possibile prendere in considerazione le varie stringhe che possono essere restituite get_post_status()
per creare uno scenario più appropriato.
Vedi Codex per get_post_status () e Post Status
I valori possibili sono:
- "pubblica": un post o una pagina pubblicati
- 'in sospeso': il post è in attesa di revisione
- "bozza": un post nello stato bozza
- "bozza automatica": un post appena creato, senza contenuto
- 'futuro' - un post da pubblicare in futuro
- "privato": non visibile agli utenti che non hanno effettuato l'accesso
- 'eredita' - una revisione. vedi get_children.
- 'cestino': la posta è nel cestino. aggiunto con la versione 2.9.
save_post()
viene eseguito per la prima volta, ma durante tale esecuzione get_post_status()
restituisce già "pubblica" e non "bozza", anche se è solo in fase di pubblicazione.