web-dev-qa-db-ja.com

Save_postコールバックで無限ループを回避する方法

私は自分の問題を解決するためにこのサイトをたくさん使っていますが、今回私は自分の問題を見つけて答えることができませんでした。

wp_update_postで呼び出される関数内でsave_postを使用すると無限ループになります。これは一般的な問題であることを私は知っていますが、私はそれを回避する方法を理解することはできません。

私は私の投稿の順番を保存したいのです(これは投稿タイプの 'section'です)。だから私はいくつかのソート可能なHTML要素を含むカスタムメタボックスを作りました。各要素には、name = 'sectionorder []'の隠し入力タグがあります。そのため、標準のWordPressの「更新」ボタンをクリックすると、投稿のすべてのIDを(順番に)含む配列がPOSTで送信されます。だからここに私は配列を取得し、順序を保存したいコードです:

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

しかし問題はそれが無限ループを開始することです。どうやってそれを避けるのですか?まったく別の方法でそれを実行できますか。

あなたの助けを評価します!

10
elgehelge

save_postフックからコールバックを削除し、投稿を更新してから、コールをフックに再度追加することができます。 コーデックスは を例に挙げています。

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

私はコメントする評判があまり得られていないので、Stephenが優れていて正しいにもかかわらず答えを追加しています。アクションの優先順位を設定したい場合は、インスタンスを処理しません。

アクションを追加するときに優先順位を設定し、削除するときに優先順位を指定しないと、無限ループが発生します。

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

//これを処理するための間違った方法 - 無限ループにつながる

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

//これを処理する正しい方法 - 一度だけ実行

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