Como liberar regras de reescrita de forma confiável em vários sites?

20

Digamos que você tenha um plugin que precise liberar regras de reescrita. Você faz tudo corretamente com o gancho de ativação e a adição de descarga tarde, para que tudo seja suave e compatível.

E então, um belo dia, alguém tenta executá-lo em vários sites.

Em vez de cenários simples como:

  1. Site WordPress criado
  2. O plug-in está instalado e ativado

Agora você tem cenários de pesadelo como:

  1. O plug-in está instalado e a rede ativada
  2. Novo site WordPress (ou cem) no multisite é criado

Em teoria, deveria funcionar, certo? Na prática, dá errado de maneiras espetaculares:

  • $wp_rewrite O estado pode ser do site errado
  • switch_to_blog() também não controla o estado de reescrita
  • a parte "posterior" pode acontecer inteiramente em um blog diferente
  • todos os outros plugins, com os quais você deve se divertir, podem não estar ativados de maneira consistente em sites diferentes

Por exemplo, você pode ver esse problema de como tentar fazê-lo desaparece permalinks no site principal toda vez que um novo site é criado .

Então, como o plugin executaria a descarga confiável de regras de reescrita em vários sites :

  1. Quando um novo site é criado, para o site?
  2. Quando o site existente é ativado a partir de inativo, para o site?
  3. Quando o plug-in está ativado em rede, para cada site?
  4. Quando o plug-in é desativado na rede, para cada site?
  5. Possivelmente em outros cenários, envolvendo reescrever o contexto global sendo alterado?
Rarst
fonte

Respostas:

11

Nota: esta é uma resposta incompleta que será expandida gradualmente


A única maneira confiável de liberar regras de reescrita em vários sites, sem destruir potencialmente a estrutura de links permanentes do contexto primário e / ou qualquer outro contexto de blog (dependendo de como e para o que você está mudando) é liberar regras de reescrita em um determinado contexto como esse :

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

O procedimento acima garante que a estrutura correta do link permanente para o contexto fornecido seja recuperada e definida antes da construção das regras de reescrita e do comprometimento das alterações no banco de dados.

Isso não se aplica ao site único em que o contexto não importa, porque existe apenas um contexto.

flush_rewrite_rules()na minha opinião, é defeituoso na premissa de que ele assume o contexto correto, mas não leva em conta nosso uso switch_to_blogpara o qual muda completamente o contexto e nos deixa em território perigoso se tentarmos liberar regras, potencialmente.

É assim que são os elementos internos flush_rewrite_rules():

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

Não consigo pensar em uma razão pela qual não deveria ser assim:

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

... especialmente quando você considera que o construtor de WP_Rewritefaz o quê? Faz isso ...

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

Tocando em seu primeiro ponto de preocupação para aprofundar essa linha,

Então, como o plugin executaria a descarga confiável de regras de reescrita em vários sites :

  • Quando um novo site é criado, para o site?

Vejamos o que o núcleo do WordPress chamará notavelmente durante esse processo:

  • primeiro wpmu_create_blog()
  • que então chama install_blog()que por sua vez chamapopulate_options()
  • depois populate_options()define a estrutura permalink padrão na tabela de opções
  • depois da install_blog()execução, wp_install_defaults()é chamado
  • depois, wp_install_defaults()libera as regras de reescrita para o site recém-criado antes de finalmente voltar para o blog atual via restore_current_blog().

É importante notar que as wp_install_defaults()regras de descarga são exatamente como sugeri acima:

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

... porque essa é a única maneira de garantir que as permalink_structureregras e corretas sejam criadas para o contexto atual.

Também no problema evidenciado no problema do Github , o motivo pelo qual o usuário experimentou o seguinte comportamento:

Quando um novo site é criado, ele quebra os links permanentes de nível de postagem apenas no site de nível superior - na maioria das configurações de link permanente, mas não em todos:

Esses 2 formatos funcionam corretamente.

Padrão - funciona como esperado

Dia e nome - funciona conforme o esperado

... é porque, se o blog principal tiver uma estrutura de link permanente Day & Name /%year%/%monthnum%/%day%/%postname%/, quando um novo site for criado, ele também /%year%/%monthnum%/%day%/%postname%/terá uma estrutura de link permanente Day & Name por padrão, e é por isso que nenhum problema notável se apresentará quando o plugin Yoast SEO liberar a reescrita regras no shutdowngancho.

Adão
fonte
Parece correto. A coisa chata com a instalação de um novo site é que você não pode se conectar durante o processo, somente depois que ele já foi concluído. Por esse motivo, as regras serão liberadas duas vezes.
Anton Timmermans
O tempo de recompensa acaba, então, pontos por cair na espada aqui. :) Ainda há muito a descobrir. :(
Rarst
Não é possível definir manualmente o contexto $wp_rewritepara que você possa percorrer e redefinir cada site de rede? Eu tenho um site de rede grande que está sofrendo de alguns problemas de link permanente em plugins personalizados. Criar um plug-in que adicione um cron parece um exagero, pois sempre os redefiniria. Fazer um loop com um URL personalizado seria o ideal, mas não sei como fazer isso em todos os sites.
Adam Patterson