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


12

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

wp_update_post呼び出される関数内で使用すると、無限ループが発生しsave_postます。これはよくある問題ですが、どうすれば回避できるかわかりません。

投稿の順序を保存したい(投稿タイプの「セクション」)。だから私はいくつかのソート可能な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 );
    }
}

しかし問題は、それが無限ループを開始することです。どうすればそれを回避できますか?多分私はそれを完全に異なる方法で行うことができますか?

あなたの助けを正当化してください!

回答:


26

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

ワオ。早速のお返事ありがとうございます。魅力的な作品!なぜ自分でそのコード例を見なかったのかわからない..
elgehelge

@Stephen、私はupdate_post_metaフックされた関数で使用しますが、save_postその後フックを外して再度フックする必要がありupdate_post_metaますか?
Anagio 2013年

いいえ、トリガーupdate_post_metaされません(通常)save_post
スティーブンハリス

1時間を無駄にした後、これが見つかり、これにより時間も節約できました。ありがとうございます。
Manchumahara

13

私はコメントする評判があまりないので、スティーブンは優秀で正解ですが、答えを追加します。アクションの優先度を設定したい場合は、インスタンスを処理しません。

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

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

1
すごい!を追加しremove_action/add_actionた場合でも、なぜ無限ループが発生するのかを理解しようと一生懸命でした。
Banjer 2014

1
WordPress Codex ::プラグインAPI /アクションリファレンス/投稿の保存::無限ループの回避彼らはこれを実証しています。WordPress Codex ::関数リファレンス/削除アクション::を見ると、「関数の優先度(関数が最初にフックされたときに定義されたもの)」。指定しない場合、デフォルトの優先順位(10)が使用されます。A / K / A-アクションを実際に削除するには、アクションが追加されたときと同じ優先度を指定する必要があります。
Michael Ecklund

これが私が探していた回答です。ありがとうございました:)
manuman94
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.