¿Cómo vaciar de forma confiable las reglas de reescritura en varios sitios?

20

Digamos que tiene un complemento que necesita vaciar las reglas de reescritura. Lo haces todo correctamente con el gancho de activación y agregando descarga tarde, para que todo sea suave y compatible.

Y luego, un buen día, alguien intenta ejecutarlo en varios sitios.

En lugar de escenarios simples como:

  1. Se crea el sitio de WordPress
  2. El complemento está instalado y activado

Ahora tienes escenarios de pesadilla como:

  1. El complemento está instalado y la red activada
  2. Se crea un nuevo sitio de WordPress (o cien) en multisitio

En teoría debería funcionar, ¿verdad? En la práctica, sale mal de maneras espectaculares:

  • $wp_rewrite estado puede ser del sitio equivocado
  • switch_to_blog() tampoco rastrea el estado de reescritura
  • la parte "posterior" podría suceder en un blog completamente diferente
  • todos esos otros complementos, con los que se supone que debes jugar bien, podrían no estar habilitados de manera consistente en diferentes sitios

Por ejemplo, puede ver este problema de cómo tratar de hacerlo bien elimina los enlaces permanentes en el sitio principal cada vez que se crea un sitio nuevo .

Entonces, ¿cómo funcionaría el complemento para enjuagar de manera confiable las reglas de reescritura en varios sitios :

  1. Cuando se crea un nuevo sitio, ¿para el sitio?
  2. Cuando el sitio existente se activa desde inactivo, ¿para el sitio?
  3. Cuando el complemento está activado en la red, para cada sitio?
  4. Cuando el complemento está desactivado en la red, ¿para cada sitio?
  5. ¿Posiblemente en otros escenarios, que implican reescribir el contexto global para cambiar?
Rarst
fuente

Respuestas:

11

Nota: esta es una respuesta incompleta que se ampliará gradualmente


La única forma confiable de eliminar las reglas de reescritura en varios sitios, sin destruir potencialmente la estructura de enlace permanente del contexto primario y / o de cualquier otro contexto del blog (dependiendo de cómo y de qué se cambie), es eliminar las reglas de reescritura en un contexto dado. :

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

Lo anterior garantiza que se recupere y establezca la estructura de enlace permanente correcta para el contexto dado antes de construir las reglas de reescritura y confirmar los cambios en la base de datos.

Esto no se aplica a un solo sitio donde el contexto no importa, porque solo hay un contexto.

flush_rewrite_rules()En mi opinión, es erróneo en la premisa de que asume el contexto correcto, pero no tiene en cuenta nuestro uso de lo switch_to_blogque cambia completamente el contexto y nos deja en un territorio peligroso si intentamos eliminar las reglas, potencialmente.

Así es flush_rewrite_rules()como se ve el interior de :

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

No puedo pensar en una razón por la que no debería verse así:

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

... especialmente cuando consideras que el constructor de WP_Rewritehace qué? Hace esto ...

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

Sin embargo, tocando tu primer punto de preocupación para avanzar en esta línea,

Entonces, ¿cómo funcionaría el plugin para enjuagar de manera confiable las reglas de reescritura en múltiples sitios :

  • Cuando se crea un nuevo sitio, ¿para el sitio?

Veamos qué llamará el núcleo de WordPress durante este proceso:

  • primero wpmu_create_blog()
  • que luego llama install_blog()que a su vez llamapopulate_options()
  • luego populate_options()establece la estructura de enlace permanente predeterminada en la tabla de opciones
  • después de install_blog()haber corrido, wp_install_defaults()luego se llama
  • luego wp_install_defaults()elimina las reglas de reescritura para el sitio recién creado antes de finalmente volver al blog actual a través de restore_current_blog().

Es importante tener en cuenta que wp_install_defaults()elimina las reglas exactamente como he sugerido anteriormente:

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

... porque esa es la única manera de asegurarse de que las permalink_structurereglas y reglas correctas se construyan para el contexto actual.

También en el problema evidenciado dentro del problema de Github , la razón por la cual el usuario experimentó el siguiente comportamiento:

Cuando se crea un nuevo sitio, rompe los enlaces permanentes de nivel de publicación solo en el sitio de nivel superior, en la mayoría de las configuraciones de enlace permanente, pero no en todas:

Estos 2 formatos funcionan correctamente.

Predeterminado: funciona como se esperaba

Día y nombre: funciona como se esperaba

... es porque si el blog principal tiene una estructura de enlace permanente Day & Name /%year%/%monthnum%/%day%/%postname%/, cuando se crea un nuevo sitio, también tiene una estructura de enlace permanente Day & Name /%year%/%monthnum%/%day%/%postname%/por defecto, razón por la cual no se presenta ningún problema notable cuando el plugin Yoast SEO va a reescribir reglas en el shutdownanzuelo.

Adán
fuente
Suena bien. Una cosa molesta con la instalación de un nuevo sitio es que no se puede conectar durante el proceso, solo después de que ya se haya completado. Debido a eso, las reglas se eliminarán dos veces.
Anton Timmermans
Se acabó el tiempo de recompensa, así que puntos por caer sobre la espada aquí. :) Sin embargo, aún queda mucho por descubrir. :(
Rarst
¿No es posible establecer manualmente el contexto de $wp_rewritemodo que pueda recorrer y restablecer cada sitio de red? Tengo un sitio de red grande que sufre algunos problemas de enlaces permanentes en complementos personalizados. Hacer un complemento que agregue un cron parece excesivo, ya que siempre los restablecería. Looping con una URL personalizada sería ideal, pero no sé cómo hacerlo para todos los sitios.
Adam Patterson