¿Dónde, cuándo y cómo limpiar correctamente las reglas de reescritura dentro del alcance de un complemento?

10

Tengo un problema un poco extraño con las reglas de reescritura que no funcionan correctamente.

He intentado usar flush_rewrite_rules();y flush_rewrite_rules(true);.

También he intentado globalizar $wp_rewriteusando $wp_rewrite->flush_rules();y$wp_rewrite->flush_rules(true);

Ninguno de los cuales parece estar limpiando las reglas de reescritura correctamente. De hecho, esas llamadas están vaciando las reglas de reescritura cuando se llaman. ¿Cómo se esto? Uso de la solución para depurar la regla de reescritura de vaciado .

Actualmente, tengo reglas de reescritura en la activación y desactivación de complementos. No hay problemas allí.

Tengo una página de configuración de administración de complementos para que los usuarios configuren el complemento. Algunas de las configuraciones ajustan la estructura del enlace permanente, por lo que las reglas de reescritura deben ser vaciadas en la página de configuración de administración de complementos "Guardar configuración". (Utiliza el estándar update_option();) para guardar la configuración.

Me gustaría señalar que, según la configuración especificada, se crean tipos de publicación personalizados para que coincidan con la configuración especificada por el usuario. Por lo tanto, las reglas de reescritura deben eliminarse inmediatamente después de guardar la configuración. Aquí es donde las cosas no funcionan adecuadamente.

La solución de enlace anterior para depurar las reglas de reescritura proporcionadas por @toschoestá mostrando que está descargando toneladas de reglas de reescritura. Sin embargo, al visitar el elemento singular de tipo de publicación personalizado, o incluso el archivo de tipo de publicación personalizado para ese asunto, cada uno devuelve como errores 404.

El tipo de publicación personalizada se registra de forma correcta y adecuada. Sé con certeza que ese no es el problema.

Inmediatamente después de guardar la configuración de la página de administración del complemento. Se crean los tipos de publicaciones personalizadas, se ajusta la estructura de enlaces permanentes y se intenta eliminar todas las reglas de reescritura.

Los tipos de publicaciones personalizadas se cargan siempre y se cargan initcomo de costumbre.

Por alguna razón, las reglas de reescritura no se limpian correctamente, porque como dije antes, visitar secciones singulares o de archivo del tipo de publicación personalizada devuelve errores 404.

Ahora la parte extraña, si todo lo que hago es simplemente visitar la página de configuración de enlaces permanentes de administración, y luego volver al frente para ver secciones singulares o archivadas del tipo de publicación personalizada, funcionan mágicamente como se esperaba.

¿Qué hace esa página de configuración de enlaces permanentes de administración que no estoy haciendo que permita que las reglas de reescritura se vacíen adecuadamente y las mías no?

Quiero decir, como solución temporal, estoy redirigiendo al usuario a la página de configuración de enlaces permanentes de administración después de guardar la página de configuración de administración del complemento, pero esta no es una solución ideal. Prefiero que las reglas de reescritura se alineen correctamente dentro del código de mi complemento.

¿Hay algún punto en WordPress en el que el vaciado de las reglas de reescritura ya no borra TODAS las reglas?

admin_menu - La página de configuración del complemento se agrega a la administración de WordPress.

add_options_page() - La página de configuración del complemento se agrega en el menú Configuración.

La página de configuración se representa en la devolución de llamada para add_options_page(). Aquí también $_POSTse procesa para actualizar la configuración de los complementos y eliminar las reglas de reescritura.

Dado que esta es una pregunta larga, estaría dispuesto a proporcionar bloques de código (si ayuda) en un enlace externo para ayudar a producir una respuesta válida.

Michael Ecklund
fuente
1
Parece que tal vez tienes el orden de las cosas mal, es difícil de decir sin ver algún código. la página de administración de enlaces permanentes solo llama flush_rewrite_rules, que simplemente elimina la rewrite_rulesopción y la regenera, puede abrir el archivo wp-admin/options-permalinks.phpy ver dónde sucede. Como esta operación solo elimina la opción completa, no es posible eliminar parcialmente las reglas.
Milo
@Milo, creo que tienes razón. Tengo una clase cargada en la initque se registran los tipos de publicación. Me imaginé que la configuración de la página se estaba guardando y la página se volvería a cargar ... luego dispararía el initgancho nuevamente para registrar los tipos de publicaciones necesarias. Así que pensé que los tipos de publicaciones ya estarían cargados, y todo lo que tenía que hacer era actualizar la opción, luego eliminar las reglas de reescritura de mi página de configuración de complementos. Publicaré una respuesta de cómo descubrí una solución.
Michael Ecklund
Solo una advertencia flush_rewrite_rules () en mi complemento terminó siendo parte del problema para mí. Eliminé el enlace de PHP y terminé actualizando los enlaces permanentes manualmente y mis errores de CPT 404 desaparecieron.
myol

Respuestas:

4

El mejor lugar para eliminar las reglas de reescritura es la activación / desactivación de complementos.

function myplugin_activate() {
    // register taxonomies/post types here
    flush_rewrite_rules();
}

register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_deactivate() {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'myplugin_deactivate' );

Ver el artículo del codex

Disculpas de antemano, no lo hice todo el camino a través de su pregunta, por lo que esta es una respuesta un poco cortante de galletas.

helgatheviking
fuente
1
Gracias por su sugerencia, pero soy consciente de esto. El problema no se trata de la activación / desactivación de complementos. Tiene que ver con que los usuarios cambien la configuración al complemento ya activo, que ajusta las reglas de reescritura, lo que requiere una descarga.
Michael Ecklund
1
Pensé que ese podría ser el caso, pero estaba bastante cansado cuando leí tu pregunta. La solución de ialocin parece prometedora, espero que la hayas resuelto.
helgatheviking
4

Es difícil saber qué pasa, sin ver su código. Pero después de guardar algunas configuraciones, es práctico conectarlo admin_initcomo se muestra a continuación para enjuagar sus reglas de reescritura.

Código:

add_action('admin_init', 'wpse_123401_plugin_settings_flush_rewrite');
function wpse_123401_plugin_settings_flush_rewrite() {
    if ( get_option('plugin_settings_have_changed') == true ) {
        flush_rewrite_rules();
        update_option('plugin_settings_have_changed', false);
    }
}


Debe establecer la opción en algún lugar de su página de configuración o para ser exacto en algún lugar del proceso de guardar la configuración. Hacerlo sin la opción es malo, porque no desea eliminar las reglas cada vez.


Nota: no probado

Nicolai
fuente
2
¿O podrías usar un transitorio tal vez? Pero definitivamente +1 por no vaciar las reglas en cada admin_init.
helgatheviking
Por supuesto, tienes razón sobre transitorios, supongo que opté por la *_option()página de configuración. @helgatheviking
Nicolai
Esto fue muy útil. Tuve una situación similar a la de Michael. Terminé incorporando la sugerencia de helga sobre el uso de un transitorio y lo configuré en la función de validación para la configuración. Terminé necesitando configurar el transitorio en falso después del enjuague o, de lo contrario, siguió enjuagando en cada carga de la página de administración hasta que expiró el transitorio. Entonces, funcionalmente, usar una opción o un transitorio era lo mismo. Supongo que transitorio podría ser bueno solo para mantener la tabla de opciones un poco más limpia. Pero un punto menor.
MatthewLee
La diferencia es menor, especialmente si los transitorios son permanentes, no caducan, pero por supuesto los transitorios tienen otras capacidades, beneficios que es bueno tener. @MatthewLee
Nicolai
3

Tenía un archivo de clase de tipo de publicación que se encargaba de leer la configuración de opciones del complemento y de crear los tipos de publicación personalizados necesarios según la configuración especificada por el usuario.

Este archivo de clase de tipos de publicación se cargó en el gancho init.

Pensé que todo lo que tenía que hacer era actualizar la configuración del complemento y luego eliminar las reglas de reescritura. Dado que la clase de tipos de publicación ya se cargó según la configuración del complemento. Pero con las páginas de administración, se cargan DESPUÉS del initgancho.

Los tipos de publicación nunca se registraron realmente, porque la configuración aún no se había establecido. La clase de registro de tipos de publicación terminó antes de tiempo sin ningún tipo de publicación registrada.

La solución fue:

  1. Actualice la configuración del complemento.
  2. Cargue el archivo de clase de tipos de publicación SOLO una vez aquí para que se creen las nuevas reglas de reescritura.
  3. Vaciar las reglas de reescritura.

(Anteriormente ... faltaba el paso 2 - Como se mencionó anteriormente ...)

A partir de ahora, los tipos de publicaciones se cargarán en el initgancho y ya tendrán configuraciones especificadas, lo que permitirá que los tipos de publicaciones se creen y emparejen con las reglas de reescritura apropiadas.

Por alguna razón, tuve que agregar una llamada de JavaScript para redirigir a la página actual, después de realizar los tres pasos anteriores.

También tuve que agregar una llamada flush_rewrite_rules();en la página de configuración de administración del complemento.

Entonces, en aras de garantizar que todo esté enjuagado ...

Paso 1) Navega a la página de configuración de administración del complemento. - Descarga inicial.

Paso 2) Actualiza la configuración del complemento. - Segunda descarga.

Paso 3) La página redirige a la página de configuración del complemento. Causando la ... Tercera y última descarga (igual que la descarga inicial: se realiza automáticamente cuando se visita la página de configuración del complemento)

No digo que sea una solución práctica, pero funcionó para mí. Problema muy extraño y muy probablemente tenga que ver con mi infraestructura de codificación.

Michael Ecklund
fuente
1

@ tazo-todua esto también funcionó para mí cuando uso multisitio.

add_action( 'wpmu_new_blog', 'set_my_permalink_structure', 11, 2 );

function set_my_permalink_structure( $blog_id ) {

    switch_to_blog( $blog_id );

    global $wp_rewrite;
    $wp_rewrite->set_permalink_structure( '/%postname%/' );
    $wp_rewrite->flush_rules();
    $wp_rewrite->init();

    restore_current_blog();
}
Stillatmylinux
fuente
0

MI SOLUCIÓN encontrada fue:

global $wp_rewrite; $wp_rewrite->flush_rules(); $wp_rewrite->init();
T.Todua
fuente
0

Estaba teniendo exactamente el mismo problema. En mi plugin, tengo tipos de publicaciones que se crean dinámicamente. Por lo tanto, no se pueden registrar a través register_post_type()de un método estático durante activation_hooky, por lo tanto, aún no están activos cuando flush_rewrite_rules()se ejecuta durante este enlace (que normalmente es la forma recomendada de enjuagar las reglas de reescritura).

La solución más limpia que se me ocurrió al final fue eliminar las reglas de reescritura después del registro de los tipos de publicación, pero, por supuesto, solo si ese enjuague era realmente necesario (porque la operación es lenta). En mi caso, en realidad tengo varios tipos de publicaciones personalizadas que heredan de una sola clase base, por lo que era deseable implementar el código que hace el vaciado allí.

Se puede decidir si es necesario enjuagar mirando la salida de get_option( 'rewrite_rules' ):

class MyPostTypeClass {

public final function register_as_custom_post_type() {
    ...   //do all the setup of your post type here     
    $args = array(
                  ... //populate the other arguments as you see fit
                  'rewrite' => array('slug' => 'slug-of-your-post-type')
                 );
    register_post_type('post-type-name-of-your-post-type', $args );

    $rewrite_rules_must_be_fluhed = true;
    foreach( get_option( 'rewrite_rules' ) as $key => $rule)
        if(strpos($key, $args['rewrite']['slug'] ) === 0)
        {
            $rewrite_rules_must_be_fluhed = false;
            break;
        }
    if($rewrite_rules_must_be_fluhed)
        flush_rewrite_rules(true);
}
}

Inconvenientes:

  • Depende en cierta medida de las reglas exactas de reescritura que genera WP register_post_type().
  • La comprobación de si es necesario enjuagar durante la carga de cada página también crea algo de sobrecarga.

Ventajas:

  • Completamente encapsulado en la clase que representa el tipo de publicación.
  • Solo elimina las reglas de reescritura si es realmente necesario.

Solo use esto si no puede registrar su tipo de publicación en una función estática que puede llamar durante ambos inity el activation_hook!

La dependencia de cómo se register_post_type()ven las reglas de reescritura generadas durante el proceso puede mitigarse reemplazando la prueba if(strpos($key, $args['rewrite']['slug'] ) === 0)con algo más elaborado, es decir, una expresión regular.

cgogolin
fuente