Bagaimana menghindari infinite loop di callback save_post

12

Saya telah menggunakan banyak situs ini untuk memecahkan masalah saya, tetapi kali ini saya tidak berhasil menemukan dan menjawab untuk masalah saya.

Saya mendapatkan dan loop tak terbatas saat menggunakan wp_update_postdi dalam fungsi yang dipanggil save_post. Saya tahu bahwa ini adalah masalah umum, tetapi saya tidak tahu bagaimana cara menghindarinya.

Saya ingin menyimpan urutan posting saya (yang merupakan 'bagian' jenis posting). Jadi saya telah membuat kotak meta khusus yang berisi beberapa elemen html yang bisa diurutkan. Di setiap elemen ada tag input tersembunyi dengan name = 'sectionorder []'. Jadi ketika saya mengklik buttom standar WordPress 'Perbarui', sebuah array yang berisi semua ID posting (dalam urutan) dikirim melalui POST. Jadi di sini adalah kode tempat saya mengambil array, dan ingin menyimpan pesanan:

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

Tetapi masalahnya adalah itu memulai loop tak terbatas. Bagaimana saya menghindarinya? Mungkin saya bisa melakukannya dengan cara yang sama sekali berbeda?

Hargai bantuan Anda!

elgehelge
sumber

Jawaban:

26

Anda dapat menghapus callback dari save_posthook, memperbarui postingan dan kemudian menambahkan kembali panggilan ke hook. The Codex memberikan contoh .

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');
}
Stephen Harris
sumber
Wow. Terima kasih atas balasan cepatnya. Bekerja seperti pesona! Tidak tahu mengapa saya tidak melihat contoh kode itu sendiri ..
elgehelge
@Stephen, saya menggunakan update_post_metafungsi yang terkait dengan save_postapakah saya juga harus melepas dan membuat ulang update_post_meta?
Anagio
Tidak, update_post_metatidak akan (umumnya) menyebabkan save_postdipicu.
Stephen Harris
Setelah membuang satu jam menemukan ini dan ini juga menghemat lebih banyak jam, terima kasih.
Manchumahara
13

Saya belum memiliki reputasi untuk berkomentar, jadi saya menambahkan jawaban meskipun jawaban Stephen sangat bagus dan benar. Itu hanya tidak menangani contoh ketika Anda ingin menetapkan prioritas tindakan.

Jika Anda menetapkan prioritas saat menambahkan tindakan tetapi tidak menentukan prioritas saat Anda menghapusnya, Anda masih akan mendapatkan loop tak terbatas.

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

// Cara SALAH untuk menangani ini - mengarah ke loop tak terbatas

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

// Cara KANAN untuk menangani ini - dieksekusi hanya sekali

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 );
Charles Jaimet
sumber
1
Wow terima kasih! Saya akan gila mencoba mencari tahu mengapa saya masih mendapatkan loop tak terbatas, bahkan ketika menambahkan remove_action/add_action.
Banjer
1
WordPress Codex :: API Plugin / Referensi Tindakan / simpan posting :: Menghindari loop tak terbatas. Mereka mendemonstrasikan ini. Jika Anda melihat WordPress Codex :: Function Reference / remove action :: Usage "Prioritas fungsi (sebagaimana didefinisikan saat fungsi awalnya dikaitkan)." Jika tidak ditentukan, ia menggunakan prioritas default (10). A / K / A - Anda harus menentukan prioritas SAMA seperti ketika tindakan ditambahkan, agar AKTIFKAN menghapus tindakan.
Michael Ecklund
Ini adalah respons yang saya cari. Terima kasih :)
manuman94