web-dev-qa-db-ja.com

マルチサイトの書き換え規則を確実にフラッシュする方法

書き換え規則をフラッシュする必要があるプラグインがあるとしましょう。あなたはアクティベーションフックとフラッシュを追加することでそれをすべてきちんとします、従ってすべては滑らかで互換性があります。

それからある日、誰かがそれをマルチサイトで実行しようとします。

次のような単純なシナリオではなく

  1. WordPressサイトが作成されました
  2. プラグインがインストールされ有効化されている

悪夢のようなシナリオがあります。

  1. プラグインがインストールされ、ネットワークがアクティブになりました
  2. マルチサイトで新しいWordPressサイト(または100)が作成されます

理論的にはうまくいくはずですよね?実際にはそれは見事な方法でうまくいかない:

  • $wp_rewrite状態は間違ったサイトからのものである可能性があります
  • switch_to_blog()は書き換え状態も追跡しません
  • 「後の」部分は別のブログで完全に発生する可能性があります
  • これらすべてのotherプラグインは、あなたが一緒に遊べるはずですが、さまざまなサイトで一貫して有効になっているとは限りません。

例えば、あなたがこの問題を正しくやろうとすると、 新しいサイトが作成されるたびにメインサイトのパーマリンクを消し去る ということがわかります。

では、どうやってプラグインは 確実に /書き換え規則をフラッシュする マルチサイトで のようになるでしょう:

  1. 新しいサイトが作成されると、そのサイトはどうなりますか?
  2. 既存のサイトが非アクティブからアクティブになったとき、そのサイトでは?
  3. サイトごとにプラグインがネットワーク有効化されている場合
  4. サイトごとにプラグインがネットワーク非アクティブ化された場合
  5. 他のシナリオでは、グローバルコンテキストの書き換えが変更される可能性がありますか。
20
Rarst

注:これは不完全な答えで、徐々に拡張されます


プライマリサイトやその他のブログコンテキストのパーマリンク構造を破壊することなく、マルチサイトで書き換えルールをフラッシュする唯一の信頼性の高い方法は、そのように特定のコンテキストで書き換えルールをフラッシュすることです。 :

global $wp_rewrite;
$wp_rewrite->init(); //important...
$wp_rewrite->flush_rules();

上記は、書き換えルールを構築してデータベースへの変更をコミットする前に、指定されたコンテキストの正しいパーマリンク構造が取得および設定されることを保証します。

コンテキストが1つしかないため、コンテキストが重要でない単一サイトには適用されません。

私の意見では、flush_rewrite_rules()は正しい文脈を想定しているという前提に欠陥がありますが、switch_to_blogの使用は文脈を完全に変えないので、ルールをフラッシュしようとすると危険な領域に置かれる可能性があります。

これはflush_rewrite_rules()の内部がどのように見えるかです:

function flush_rewrite_rules( $hard = true ) {
    global $wp_rewrite;
    $wp_rewrite->flush_rules( $hard );
}

私はそれがこのように見えるべきでない理由を考えることはできません:

function flush_rewrite_rules( $hard = true ) {
    global $wp_rewrite;
    $wp_rewrite->init(); //hello....
    $wp_rewrite->flush_rules( $hard );
}

...特にWP_Rewriteのコンストラクタが何をしていると考えるとき?これは….

public function __construct() {
    $this->init();
}

あなたの最初の関心事に触れて、この行をさらに進めるには、

それでは、プラグインは multisite の書き換え規則を確実にフラッシュする方法を考えてみましょう。

  • 新しいサイトが作成されると、そのサイトはどうなりますか?

このプロセスの間にWordPressコアが特に呼び出すものを見てみましょう。

  • 最初のwpmu_create_blog()
  • それからinstall_blog()が呼び出され、次にpopulate_options()が呼び出されます。
  • populate_options()はオプションテーブルにデフォルトのパーマリンク構造を設定します
  • install_blog()が実行された後、wp_install_defaults()が呼び出されます
  • wp_install_defaults()は、新しく作成されたサイトの書き換えルールをフラッシュしてから、最後にrestore_current_blog()経由で現在のブログに戻ります。

注意すべき重要な点は、 wp_install_defaults() が上記で提案したとおりにルールをフラッシュすることです。

$wp_rewrite->init();
$wp_rewrite->flush_rules();

これは、現在のコンテキストに対して正しいpermalink_structureとルールが確実に構築される唯一の方法だからです。

Github issue 内で証明されている問題においても、ユーザーが以下のような動作を経験した理由です。

新しいサイトが作成されると、トップレベルサイトでのみポストレベルのパーマリンクを解除します - ほとんどのパーマリンク設定では全部ではありません:

これら2つのフォーマットは正しく機能します。

デフォルト - 期待通りに動作

曜日と名前 - 予想通りに動作します

これは、メインのブログがDay&Nameパーマリンク構造/%year%/%monthnum%/%day%/%postname%/を持っている場合、新しいサイトが作成されたときにもデフォルトでDay&Nameパーマリンク構造/%year%/%monthnum%/%day%/%postname%/を持っているためです。 shutdownフックの書き換え規則をフラッシュします。

11
userabuser