Come evitare il loop infinito nel callback save_post


12

Ho usato questo sito molto per risolvere i miei problemi, ma questa volta non sono riuscito a trovare e rispondere al mio problema.

Ottengo un ciclo infinito quando utilizzo wp_update_postall'interno di una funzione chiamata save_post. So che questo è un problema comune, ma non riesco a capire come evitarlo.

Voglio salvare l'ordine dei miei post (che è di tipo post "sezione"). Quindi ho creato una meta box personalizzata che contiene alcuni elementi html ordinabili. In ogni elemento è presente un tag di input nascosto con name = 'sectionorder []'. Quindi, quando faccio clic sul pulsante standard 'Aggiorna' di WordPress, un array contenente tutti gli ID dei post (in ordine) vengono inviati tramite POST. Quindi ecco il codice in cui recupero l'array e vuole salvare l'ordine:

    // Update section sort order
$sectionorder = $_POST['sectionorder'];
if (isset($sectionorder)) { // Avoid error if there is no sections added yet
    foreach( $sectionorder as $no => $sectionID ) {
        $post_update = array();
        $post_update['ID'] = $sectionID;
        $post_update['menu_order'] = $no;
        wp_update_post( $post_update );
    }
}

Ma il problema è che inizia un ciclo infinito. Come posso evitarlo? Forse posso farlo in un modo completamente diverso?

Apprezzo il tuo aiuto!

Risposte:


26

È possibile rimuovere il callback dal save_posthook, aggiornare il post e quindi aggiungere nuovamente il call al hook. Il Codice fornisce un esempio .

add_action('save_post', 'wpse51363_save_post');

function wpse51363_save_post($post_id) {

    //Check it's not an auto save routine
     if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
          return;

    //Perform permission checks! For example:
    if ( !current_user_can('edit_post', $post_id) ) 
          return;

    //Check your nonce!

    //If calling wp_update_post, unhook this function so it doesn't loop infinitely
    remove_action('save_post', 'wpse51363_save_post');

    // call wp_update_post update, which calls save_post again. E.g:
    wp_update_post(array('ID' => $post_id, 'post_status' => 'private'));

    // re-hook this function
    add_action('save_post', 'wpse51363_save_post');
}

Wow. Grazie per la risposta rapida. Funziona come un fascino! Non so perché non ho visto quell'esempio di codice da solo ..
elgehelge,

@Stephen, utilizzo update_post_metain una funzione agganciata save_postse dovessi anche sganciare e riagganciare dopo update_post_meta?
Anagio,

No, update_post_meta(generalmente) non causerà save_postl'attivazione.
Stephen Harris,

Dopo aver perso un'ora ho trovato questo e questo ha anche risparmiato più ore, grazie.
Manchumahara,

13

Non ho abbastanza la reputazione di commentare, quindi sto aggiungendo una risposta anche se quella di Stephen è eccellente e corretta. Semplicemente non gestisce le istanze quando si desidera impostare la priorità dell'azione.

Se imposti la priorità quando aggiungi l'azione ma non specifichi la priorità quando la rimuovi otterrai comunque un ciclo infinito.

add_action('save_post', 'wpse51363_save_post', 25 );

// Il modo ERRATO di gestirlo - porta a un ciclo infinito

remove_action('save_post', 'wpse51363_save_post');
wp_update_post(array('ID' => $post_id, 'post_status' => 'private'));
add_action('save_post', 'wpse51363_save_post');

// Il modo GIUSTO per gestirlo: viene eseguito una sola volta

remove_action('save_post', 'wpse51363_save_post', 25 );
wp_update_post(array('ID' => $post_id, 'post_status' => 'private'));
add_action('save_post', 'wpse51363_save_post', 25 );

1
Wow grazie! Stavo impazzendo cercando di capire perché stavo ancora ottenendo il ciclo infinito, anche quando aggiungevo remove_action/add_action.
Banjer,

1
Codice WordPress :: API plug-in / Riferimento azione / salva post :: Evitare cicli infiniti Lo dimostrano. Se guardi WordPress Codex :: Riferimento funzioni / rimuovi azione :: Utilizzo "La priorità della funzione (come definita quando la funzione era originariamente agganciata)." Se non specificato, utilizza la priorità predefinita (10). A / K / A - Devi specificare la priorità SAME come quando l'azione è stata aggiunta, per rimuovere REALMENTE l'azione.
Michael Ecklund,

Questa è la risposta che stavo cercando. Grazie :)
manuman94
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.