Comment vider de manière fiable les règles de réécriture sur plusieurs sites?

20

Disons que vous avez un plugin qui doit vider les règles de réécriture. Vous faites tout cela correctement avec le crochet d'activation et l'ajout de rinçage tardif, donc tout est lisse et compatible.

Et puis un beau jour, quelqu'un essaie de l'exécuter sur plusieurs sites.

Au lieu d'un simple scénario comme:

  1. Le site WordPress est créé
  2. Le plugin est installé et activé

Vous avez maintenant des scénarios de cauchemar comme:

  1. Le plugin est installé et activé par le réseau
  2. Un nouveau site WordPress (ou une centaine) en multisite est créé

En théorie, cela devrait simplement fonctionner, non? Dans la pratique, cela se passe de manière spectaculaire:

  • $wp_rewrite l'état peut provenir du mauvais site
  • switch_to_blog() ne suit pas non plus l'état de réécriture
  • la partie «plus tard» pourrait se produire entièrement dans un blog différent
  • tous ces autres plugins, avec lesquels vous êtes censé jouer bien, pourraient ne pas être activés de manière cohérente sur différents sites

Par exemple, vous pouvez voir ce problème comment essayer de le faire correctement supprime les permaliens sur le site principal chaque fois qu'un nouveau site est créé .

Alors, comment le plugin pourrait-il vider les règles de réécriture de manière fiable dans le multisite :

  1. Quand un nouveau site est créé, pour le site?
  2. Lorsque le site existant est activé de inactif, pour le site?
  3. Lorsque le plugin est activé sur le réseau, pour chaque site?
  4. Lorsque le plugin est désactivé sur le réseau, pour chaque site?
  5. Peut-être dans d'autres scénarios, impliquant une réécriture du contexte global changé?
Rarst
la source

Réponses:

11

Remarque: il s'agit d'une réponse incomplète qui sera développée progressivement


Le seul moyen fiable de vider les règles de réécriture dans plusieurs sites, sans potentiellement détruire la structure de permalien du contexte principal et / ou de tout autre contexte de blog (selon la façon dont vous basculez vers et depuis), est de vider les règles de réécriture dans un contexte donné comme celui-ci. :

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

Ce qui précède garantit que la structure de permalien correcte pour le contexte donné est récupérée et définie avant de construire les règles de réécriture et de valider les modifications dans la base de données.

Cela ne s'applique pas à un seul site où le contexte n'a pas d'importance, car il n'y a qu'un seul contexte.

flush_rewrite_rules()à mon avis, est erroné dans la prémisse qu'il suppose le contexte correct, mais ne prend pas en compte notre utilisation de switch_to_blogce qui change complètement le contexte et nous laisse en territoire dangereux si nous essayons de renverser les règles, potentiellement.

Voici à quoi flush_rewrite_rules()ressemblent les internes de :

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

Je ne peux pas penser à une raison pour laquelle cela ne devrait pas ressembler à ceci:

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

... surtout quand on considère que le constructeur de WP_Rewritequoi fait quoi? Il fait ça ...

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

Touchant votre premier point de préoccupation pour approfondir cette ligne de pensée,

Alors, comment le plugin procéderait-il au vidage fiable des règles de réécriture dans le multisite :

  • Quand un nouveau site est créé, pour le site?

Voyons ce que WordPress Core appellera notamment au cours de ce processus:

  • premier wpmu_create_blog()
  • qui appelle alors install_blog()qui à son tour appellepopulate_options()
  • populate_options()définit ensuite la structure de permalien par défaut dans le tableau des options
  • après install_blog()a couru, wp_install_defaults()puis est appelé
  • wp_install_defaults()vide ensuite les règles de réécriture du site nouvellement créé avant de revenir finalement au blog actuel via restore_current_blog().

Il est important de noter que cela wp_install_defaults()efface les règles exactement comme je l'ai suggéré ci-dessus:

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

... car c'est le seul moyen de s'assurer que les permalink_structurerègles correctes et sont établies pour le contexte actuel.

Également dans le problème mis en évidence dans le problème Github , la raison pour laquelle l'utilisateur a rencontré le comportement suivant:

Lorsqu'un nouveau site est créé, il rompt les permaliens de niveau post uniquement sur le site de niveau supérieur - dans la plupart des configurations de permaliens mais pas toutes:

Ces 2 formats fonctionnent correctement.

Par défaut - Fonctionne comme prévu

Jour et nom - Fonctionne comme prévu

... parce que si le blog principal a une structure de permalien Day & Name /%year%/%monthnum%/%day%/%postname%/, quand un nouveau site est créé, il a aussi une structure de permalink Day & Name /%year%/%monthnum%/%day%/%postname%/par défaut, c'est pourquoi aucun problème notable ne se présente lorsque le plugin Yoast SEO flushes réécrit règles sur le shutdowncrochet.

Adam
la source
Parait à peu près juste. La chose ennuyeuse avec l'installation d'un nouveau site est que vous ne pouvez pas vous accrocher pendant le processus, seulement après qu'il a déjà été terminé. Pour cette raison, les règles seront vidées deux fois.
Anton Timmermans
Le temps des primes est écoulé, alors des points pour tomber sur l'épée ici. :) Encore beaucoup à comprendre. :(
Rarst
N'est-il pas possible de définir manuellement le contexte de $wp_rewriteafin de pouvoir parcourir et réinitialiser chaque site réseau? J'ai un grand site réseau qui souffre de quelques problèmes de permalien sur les plugins personnalisés. Faire un plugin qui ajoute un cron semble exagéré car il serait toujours de les réinitialiser. Les boucler avec une URL personnalisée serait idéal mais je ne sais pas comment le faire pour tous les sites.
Adam Patterson