web-dev-qa-db-fra.com

Comment éviter la boucle infinie dans le rappel save_post

J'utilise beaucoup ce site pour résoudre mes problèmes, mais cette fois, je n'ai pas réussi à trouver le problème et à y répondre.

J'obtiens une boucle infinie en utilisant wp_update_post dans une fonction appelée sur save_post. Je sais que c'est un problème courant, mais je ne vois pas comment l'éviter.

Je souhaite enregistrer l'ordre de mes publications (qui est du type "section"). J'ai donc créé une boîte à méta personnalisée contenant des éléments html pouvant être triés. Dans chaque élément, il y a une balise d’entrée cachée avec name = 'sectionorder []'. Ainsi, lorsque je clique sur le bouton standard "Mise à jour" de WordPress, un tableau contenant tous les identifiants des publications (dans l'ordre) est envoyé via POST. Donc, voici le code où je récupère le tableau, et veut enregistrer la commande:

    // 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 );
    }
}

Mais le problème est que cela commence une boucle infinie. Comment puis-je éviter cela? Peut-être que je peux le faire d'une manière complètement différente?

Appréciez votre aide!

10
elgehelge

Vous pouvez supprimer le rappel du point d'ancrage save_post, mettre à jour la publication, puis rajouter à nouveau l'appel au point d'ancrage. Le Codex donne un exemple .

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');
}
22
Stephen Harris

Je n'ai pas encore la réputation de commenter, alors j'ajoute une réponse même si Stephen est excellent et correct. Cela ne gère tout simplement pas les cas où vous souhaitez définir la priorité de l'action.

Si vous définissez la priorité lors de l'ajout de l'action mais ne spécifiez pas la priorité lorsque vous la supprimez, vous obtiendrez toujours une boucle infinie.

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

// La mauvaise façon de gérer cela - conduit à une boucle infinie

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

// La bonne façon de gérer cela - ne s'exécute qu'une fois

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 );
13
Charles Jaimet