Où, quand et comment vider correctement les règles de réécriture dans le cadre d'un plugin?

10

J'ai un petit problème étrange avec les règles de réécriture qui ne sont pas correctement vidées.

J'ai essayé d'utiliser flush_rewrite_rules();et flush_rewrite_rules(true);.

J'ai aussi essayé de mondialiser en $wp_rewriteutilisant $wp_rewrite->flush_rules();et$wp_rewrite->flush_rules(true);

Aucun des deux ne semble vider correctement les règles de réécriture. Ces appels vident en effet les règles de réécriture lorsqu'ils sont appelés. Comment le sais-je? Utilisation de la solution de débogage du rinçage des règles de réécriture .

Actuellement, j'ai des règles de réécriture vidées sur l'activation et la désactivation du plugin. Aucun problème là-bas.

J'ai une page de paramètres d'administration du plugin pour que les utilisateurs puissent configurer le plugin. Certains paramètres ajustent la structure du permalien, de sorte que les règles de réécriture doivent être effacées sur la page des paramètres d'administration du plugin "Enregistrer les paramètres". (Utilise la norme update_option();) pour enregistrer les paramètres.

Je voudrais noter qu'en fonction des paramètres spécifiés, des types de publication personnalisés sont créés pour correspondre aux paramètres spécifiés par l'utilisateur. Les règles de réécriture doivent donc être vidées immédiatement après l'enregistrement des paramètres. C'est là que les choses ne fonctionnent pas correctement.

La solution de lien ci-dessus pour le débogage des règles de réécriture fournie par @toschoaffiche qu'elle vide des tonnes de règles de réécriture. Cependant, lors de la visite de l'élément singulier de type de publication personnalisé, ou même de l'archive de type de publication personnalisée, chacun renvoie des erreurs 404.

Le type de publication personnalisé est enregistré correctement et de manière appropriée. Je sais avec certitude que ce n'est pas le problème.

Immédiatement après l'enregistrement des paramètres de la page d'administration du plugin. Les types de publication personnalisés sont créés, la structure du lien permanent est ajustée et toutes les règles de réécriture sont tentées d'être vidées.

Les types de publication personnalisés sont ensuite toujours chargés et chargés initcomme d'habitude.

Pour une raison quelconque, les règles de réécriture ne sont pas vidées correctement, car comme je l'ai déjà dit, la visite des sections singulières ou d'archivage du type de message personnalisé renvoie des erreurs 404.

Maintenant, la partie étrange, si tout ce que je fais, c'est simplement visiter la page des paramètres de permaliens d'administration, puis revenir à la partie frontale pour afficher les sections singulières ou d'archivage du type de publication personnalisé, elles fonctionnent comme par magie.

Que fait cette page de paramètres de permaliens d'administration que je ne fais pas pour permettre aux règles de réécriture de vider correctement et la mienne non?

Je veux dire, en tant que solution temporaire, je redirige l'utilisateur vers la page des paramètres d'administration des permaliens après avoir enregistré la page des paramètres d'administration du plugin, mais ce n'est pas une solution idéale. Je préférerais que les règles de réécriture soient juste correctement vidées dans le code de mon plugin.

Y a-t-il un certain point dans WordPress où le rinçage des règles de réécriture ne vide tout simplement plus TOUTES les règles?

admin_menu - La page des paramètres du plugin est ajoutée à l'administration WordPress.

add_options_page() - La page des paramètres du plugin est ajoutée dans le menu Paramètres.

La page des paramètres est rendue dans le rappel de add_options_page(). C'est également là où $_POSTest traité la mise à jour des paramètres du plugin et le vidage des règles de réécriture.

Puisque c'est déjà une longue question, je serais prêt à fournir des blocs de code (si cela aide) dans un lien hors site pour aider à produire une réponse valide.

Michael Ecklund
la source
1
on dirait que vous avez peut-être mal l'ordre des choses, c'est difficile à dire sans voir du code. la page d'administration des permaliens ne fait qu'appeler flush_rewrite_rules, ce qui supprime simplement l' rewrite_rulesoption et la régénère, vous pouvez ouvrir le fichier wp-admin/options-permalinks.phpet voir où cela se produit. puisque cette opération supprime simplement l'option entière, il n'est pas possible de vider partiellement les règles.
Milo
@Milo, je pense que tu as raison. J'ai une classe qui est chargée sur initlaquelle s'inscrit les types de messages. Je me suis dit que les paramètres de la page étaient enregistrés et que la page se rechargeait ... puis tirait à initnouveau le crochet pour enregistrer les types de messages nécessaires. J'ai donc pensé que les types de messages seraient déjà chargés, et tout ce que je devais faire était de mettre à jour l'option, puis de vider les règles de réécriture de ma page de paramètres de plugin. Je posterai une réponse sur la façon dont j'ai trouvé une solution.
Michael Ecklund
Juste un avertissement flush_rewrite_rules () dans mon plugin a fini par faire partie du problème pour moi. J'ai supprimé le crochet php et j'ai fini par mettre à jour les permaliens manuellement et mes erreurs CPT 404 ont disparu.
myol

Réponses:

4

Le meilleur endroit pour vider les règles de réécriture est l'activation / désactivation du plugin.

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' );

Voir l'article du codex

Toutes mes excuses à l'avance, je n'ai pas répondu à votre question, c'est donc un peu une réponse à l'emporte-pièce.

helgatheviking
la source
1
Merci pour votre suggestion, mais j'en suis conscient. Le problème ne concerne pas l'activation / la désactivation du plugin. Cela concerne les utilisateurs qui modifient les paramètres du plugin déjà actif, qui ajustent les règles de réécriture, nécessitant ainsi un vidage.
Michael Ecklund
1
J'ai pensé que cela pourrait être le cas, mais j'étais assez fatigué lorsque j'ai lu votre question. La solution d'ialocin semble prometteuse, j'espère que vous l'avez trouvée.
helgatheviking
4

Difficile de dire ce qui ne va pas, sans voir votre code. Mais après avoir enregistré certains paramètres, il est pratique de s'y connecter admin_initcomme indiqué ci-dessous pour vider vos règles de réécriture.

Code:

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


Vous devez définir l'option quelque part sur votre page de paramètres ou pour être exact quelque part dans le processus d'enregistrement des paramètres. Le faire sans l'option est mauvais, car vous ne voulez pas vider les règles à chaque fois.


Remarque: non testé

Nicolai
la source
2
Ou vous pourriez peut-être utiliser un transitoire? Mais définitivement +1 pour ne pas avoir effacé les règles sur chaque admin_init.
helgatheviking
Vous avez bien sûr raison sur les transitoires, je suppose que j'ai opté pour la *_option()page des paramètres. @helgatheviking
Nicolai
Ce fut très utile. J'avais une situation similaire à Michael. J'ai fini par incorporer la suggestion d'Helga sur l'utilisation d'un transitoire et je l'ai mis dans la fonction de validation des paramètres. J'ai fini par avoir besoin de définir le transitoire sur faux après le rinçage, sinon il continuait à vider à chaque chargement de page d'administration jusqu'à ce que le transitoire expire. Donc, utiliser fonctionnellement une option ou un transitoire était le même. Je suppose que transitoire pourrait être bien juste pour garder la table des options un peu plus propre. Mais un point mineur.
MatthewLee
La différence est mineure en effet, surtout si les transitoires sont permanents, non expirants, mais bien sûr les transitoires ont d'autres capacités, des avantages qui sont agréables à avoir. @MatthewLee
Nicolai
3

J'avais un fichier de classe de types de publication qui était responsable de la lecture des paramètres d'options du plugin et de la création des types de publication personnalisés nécessaires en fonction des paramètres spécifiés par l'utilisateur.

Ce fichier de classe de types de publication a été chargé sur le crochet init.

J'ai pensé que tout ce que je devais faire était de mettre à jour les paramètres du plugin, puis de vider les règles de réécriture. Étant donné que la classe des types de publication était déjà chargée en fonction des paramètres du plugin. Mais avec les pages d'administration, elles sont chargées APRÈS le initcrochet.

Les types de publication n'ont jamais été réellement enregistrés, car les paramètres n'étaient pas encore définis. La classe d'enregistrement des types de publication s'est terminée prématurément sans aucun type de publication enregistré.

La solution était:

  1. Mettez à jour les paramètres du plugin.
  2. Chargez le fichier de classe des types de publication UNIQUEMENT une fois ici afin que les nouvelles règles de réécriture soient créées.
  3. Rincez les règles de réécriture.

(Auparavant ... l'étape 2 manquait - Comme mentionné ci-dessus ...)

À partir de maintenant, les types de publication seront chargés sur le initcrochet et auront déjà des paramètres spécifiés, permettant aux types de publication d'être créés et associés aux règles de réécriture appropriées.

Pour une raison quelconque, j'ai dû ajouter un appel JavaScript pour rediriger vers la page actuelle, après avoir effectué les trois étapes ci-dessus.

J'ai également dû ajouter un appel à flush_rewrite_rules();sur la page des paramètres d'administration du plugin.

Donc, pour s'assurer que tout est rincé ...

Étape 1) Accédez à la page des paramètres d'administration du plugin. - Rinçage initial.

Étape 2) Mettez à jour les paramètres du plugin. - Deuxième chasse.

Étape 3) La page redirige vers la page des paramètres du plugin. Causant le ... Troisième et dernier rinçage (identique au rinçage initial - Fait automatiquement lorsque la page des paramètres du plugin est visitée)

Je ne dis pas que c'est une solution pratique, mais cela a fonctionné pour moi. Problème très étrange et probablement lié à mon infrastructure de codage.

Michael Ecklund
la source
1

@ tazo-todua, cela a également fonctionné pour moi lors de l'utilisation de plusieurs sites.

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
la source
0

MA SOLUTION trouvée était:

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

J'avais exactement le même problème. Dans mon plugin, j'ai des types de messages qui sont créés dynamiquement. Ils ne peuvent donc pas être enregistrés via register_post_type()une méthode statique pendant le activation_hooket ne sont donc pas encore actifs lorsqu'ils flush_rewrite_rules()sont exécutés pendant ce hook (qui est normalement la méthode recommandée pour vider les règles de réécriture).

La solution la plus propre que j'ai pu trouver à la fin était de vider les règles de réécriture après l'enregistrement des types de publication, mais bien sûr uniquement si une telle vidange était réellement nécessaire (car l'opération est lente). Dans mon cas, j'ai en fait plusieurs types de messages personnalisés qui héritent d'une seule classe de base et il était donc souhaitable d'implémenter le code qui effectue le vidage là-bas.

La nécessité d'un rinçage peut être décidée en examinant les résultats 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);
}
}

Désavantages:

  • Dépend dans une certaine mesure des règles de réécriture exactes générées par WP register_post_type().
  • Vérifier si le vidage est nécessaire lors de chaque chargement de page crée également des frais généraux.

Avantages:

  • Entièrement encapsulé dans la classe représentant le type de message.
  • Ne vide les règles de réécriture que si cela est vraiment nécessaire.

N'utilisez ceci que si vous ne pouvez pas enregistrer votre type de message dans une fonction statique qui peut appeler pendant les deux initet le activation_hook!

La dépendance sur la façon dont les règles de réécriture générées pendant l' register_post_type()apparence peuvent être atténuées en remplaçant le test if(strpos($key, $args['rewrite']['slug'] ) === 0)par quelque chose de plus élaboré, c'est-à-dire une expression régulière.

cgogolin
la source