Как надежно сбросить правила перезаписи на мультисайтах?

20

Допустим, у вас есть плагин, который должен сбрасывать правила перезаписи. Вы делаете все правильно с помощью ловушки активации и добавления флеша поздно, так что все гладко и совместимо.

И тогда в один прекрасный день кто-то пытается запустить его на мультисайте.

Вместо простых сценариев, таких как:

  1. Сайт WordPress создан
  2. Плагин установлен и активирован

Теперь у вас есть кошмарные сценарии, такие как:

  1. Плагин установлен и сеть активирована
  2. Создан новый сайт WordPress (или сотня) в мультисайтах

По идее все должно работать, верно? На практике все идет не так, как надо:

  • $wp_rewrite состояние может быть не с того сайта
  • switch_to_blog() также не отслеживает состояние перезаписи
  • «поздняя» часть может произойти полностью в другом блоге
  • все остальные плагины, с которыми вы должны играть хорошо, могут быть не всегда включены на разных сайтах

Например, вы можете увидеть эту проблему, как попытка сделать это правильно сносит постоянные ссылки на основной сайт каждый раз, когда создается новый сайт .

Итак, как бы плагин работал над надежной очисткой правил перезаписи в мультисайтах :

  1. Когда создается новый сайт, для сайта?
  2. Когда существующий сайт активируется из неактивного, для сайта?
  3. Когда плагин активируется по сети, для каждого сайта?
  4. Когда плагин отключается от сети, для каждого сайта?
  5. Возможно, в других сценариях, включая изменение глобального контекста переписывания?
Rarst
источник

Ответы:

11

Примечание: это неполный ответ, который будет расширен постепенно


Единственный надежный способ сбрасывать правила перезаписи в мультисайтах, не разрушая при этом структуру постоянных ссылок основного и / или любого другого контекста блога (в зависимости от того, как и на что вы переключаетесь), это сбрасывать правила перезаписи в заданном контексте следующим образом. :

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

Вышеприведенное гарантирует, что правильная структура постоянных ссылок для данного контекста извлекается и устанавливается до создания правил перезаписи и фиксации изменений в базе данных.

Это не относится к одному сайту, где контекст не имеет значения, потому что существует только один контекст.

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

Касаясь вашей первой проблемы, чтобы продолжить эту линию, хотя,

Итак, как бы плагин работал над надежной очисткой правил перезаписи в мультисайтах :

  • Когда создается новый сайт, для сайта?

Давайте посмотрим, что ядро ​​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 , причина, по которой пользователь испытал следующее поведение:

Когда создается новый сайт, он нарушает постоянные ссылки уровня поста только на сайте верхнего уровня - в большинстве конфигураций постоянных ссылок, но не во всех:

Эти 2 формата работают правильно.

По умолчанию - работает как положено

Day & Name - работает как положено

... потому что если основной блог имеет структуру постоянных ссылок Day & Name /%year%/%monthnum%/%day%/%postname%/, то при создании нового сайта он также имеет структуру постоянных ссылок Day & Name, /%year%/%monthnum%/%day%/%postname%/поэтому никакой заметной проблемы не возникает, когда плагин Yoast SEO сбрасывает перезапись. правила на shutdownкрючке.

Адам
источник
Звучит правильно. При установке нового сайта раздражает то, что вы не можете подключиться во время процесса, только после того, как он уже завершен. Из-за этого правила будут сброшены дважды.
Антон Тиммерманс
Время щедрости истекло, поэтому очки за попадание на меч здесь. :) Хотя многое еще предстоит выяснить. :(
Rarst
Разве нельзя вручную установить контекст, $wp_rewriteчтобы можно было перебирать и сбрасывать каждый сетевой сайт? У меня есть большой сетевой сайт, который страдает от некоторых проблем с постоянными ссылками на пользовательские плагины. Создание плагина, который добавляет cron, кажется излишним, так как он всегда сбрасывает их. Цикл их с пользовательским URL был бы идеальным, но я не знаю, как это сделать для всех сайтов.
Адам Паттерсон