web-dev-qa-db-ja.com

save_postのflush_rewrite_rulesが最初の投稿の保存で機能しない

私はカスタム投稿タイプを作成する私自身の急速な開発のためのプラグインを開発しています。この投稿タイプの「リスト」は、プラグインによって作成および管理されている特定のページに表示されます。このページはサイトのページ階層内のどこにでも配置できるため、サイト管理者がリストページの場所を変更した場合は、単一の投稿のスラッグを更新する必要があります。

init中に投稿タイプを作成するとき、私は以下の書き換え規則をカスタム投稿タイプに割り当てることでこれを達成します(コードは簡潔にするためにトリミングされています)。

$post_type_slug = "/" . get_page_uri( $page_id );
register_post_type( 'post_type_name',
        ... 
        'rewrite'   => array( 'slug' => $post_type_slug, 'with_front' => true),
        ...
      )
);  

これは最初にすべてをセットアップするのに完璧に機能するようです。ユーザーが「リスト」ページを保存したら、次のコードを実行して書き換え規則を更新します。

add_action( 'save_post', array(__CLASS__, 'flush_permalinks'), 2000 );
function flush_permalinks( $post_id ) {
  if($post_id == get_option( $custom_page_id )){
    flush_rewrite_rules(false);
  }
}

ただし、ユーザーがページの場所を変更すると、(リストページにリンクが正しく表示されていても)新しく更新されたパーマリンクは404を返します。しかし、もう一度ページを保存しても、問題なく機能します。私はsave_postアクションの優先順位を変更することを試みました(1から2000へ)、しかしそれは変わらないようです。私はまた、ハードとソフトの両方で書き換え規則をフラッシュしようとしましたが、それは2セーブ(最初のセーブは書き換え規則を変更しませんが、2番目は保存します)の動作も変更しません。

私が間違っているかもしれないことについて何か提案はありますか?

3
Eric K

私はこれがすでに答えられていることを知っています、しかし私はそれが実際の解決策が何であるかについて100%本当で明確ではなかったかのように感じました。

これを明確にするための私の答えです。

その通りです... initアクションフックが起動された後にそのアクションフックが起動されるので、save_postの書き換えルールをフラッシュすることはできません。

ご存じのとおり、投稿タイプと分類法はinitフックに登録されています。

TLDR;save_postアクションフックではflush_rewrite_rules();できません。

回避策があります...

save_postアクションフックでオプション値を1に設定する必要があります。次に、そのオプションの値が1であることを確認し、initアクションフックの書き換え規則をフラッシュします。

例:

function mbe_late_init_example() {

    if ( ! $option = get_option( 'my-plugin-flush-rewrite-rules' ) ) {
        return false;
    }

    if ( $option == 1 ) {

        flush_rewrite_rules();
        update_option( 'my-plugin-flush-rewrite-rules', 0 );

    }

    return true;

}

add_action( 'init', 'mbe_late_init_example', 999999 );


function mbe_save_post_example( Int $post_id = null, \WP_Post $post_object = null ) {

    if ( ! $post_id || ! $post_object ) {
        return false;
    }

    # Specific Post Type
    if ( $post_object->post_type != 'my-plugin-settings' ) {
        return false;
    }

    # Specific Post Object (OPTIONAL)
    if ( $post_object->post_name != 'general-settings' ) {
        return false;
    }

    update_option( 'my-plugin-flush-rewrite-rules', 1 );

    return true;

}

add_action( 'save_post', 'mbe_save_post_example', 10, 2 );
3
Michael Ecklund

私はこの問題を解決することができました。 'save_post'アクションは、カスタム投稿タイプを登録しているinitの前に発生します。したがって、投稿タイプの書き換えスラグはflush_rewrite_rulesへのリクエストの前には更新されず、基本的に更新されません。これはまた、投稿タイプが書き換えルールを更新する機会があるため、投稿が2回保存された場合になぜ機能するのかを説明します。

したがって、コードを次のように変更して解決します。

add_action( 'save_post', array(__CLASS__, 'flush_permalinks'));
function flush_permalinks( $post_id ) { 
  if($post_id == get_option( $custom_page_id )){
    update_option( 'unique_page_updated_key', 'true');
  }
}

私はそれから私のregister_post_typeコードのすぐ下に以下を加えました:

if((bool)get_option( 'unique_page_updated_key' )){
  flush_rewrite_rules(); 
  update_option( 'unique_page_updated_key', 'false');
}

これにより、書き換えルールがすべてのinitでフラッシュされるのを防ぎます。

1
Eric K