Como evitar um loop infinito no retorno de chamada save_post

9

Eu tenho usado muito este site para resolver meus problemas, mas desta vez não consegui encontrar e responder para o meu problema.

Eu recebo um loop infinito quando uso wp_update_post dentro de uma função que é chamada em save_post . Eu sei que isso é um problema comum, mas não consigo descobrir como evitá-lo.

Eu quero salvar a ordem das minhas postagens (que é do tipo "seção" do post). Por isso, criei uma meta box customizada que contém alguns elementos html classificáveis. Em cada elemento há uma tag de entrada oculta com o nome = 'sectionorder []'. Então, quando eu clico no botão 'Atualizar' padrão do WordPress, um array contendo todos os IDs dos posts (em ordem) é enviado via POST. Então aqui está o código onde eu recupero o array, e quero salvar o pedido:

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

Mas o problema é que ele inicia um loop infinito. Como evito isso? Talvez eu possa fazer isso de uma maneira completamente diferente?

Aprecie sua ajuda!

    
por elgehelge 07.05.2012 / 12:21

2 respostas

22

Você pode remover o retorno de chamada do gancho save_post , atualizar o post e adicionar novamente a chamada ao gancho. O Codex dá um exemplo .

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');
}
    
por Stephen Harris 07.05.2012 / 12:43
11

Eu ainda não tenho a reputação de comentar, então estou adicionando uma resposta, mesmo que o Stephen's seja excelente e correto. Ele simplesmente não lida com instâncias quando você deseja definir a prioridade da ação.

Se você definir a prioridade ao adicionar a ação, mas não especificar a prioridade ao removê-la, ainda obterá um loop infinito.

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

// A maneira ERRADA de lidar com isso - leva a loop 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');

// A maneira certa de lidar com isso - executa somente uma vez

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 );
    
por Charles Jaimet 20.06.2014 / 20:05