it-swarm.com.de

Wo, wann und wie werden Rewrite-Regeln im Rahmen eines Plugins ordnungsgemäß gelöscht?

Ich habe ein seltsames Problem mit Umschreiberegeln, die nicht richtig geleert werden.

Ich habe versucht, flush_rewrite_rules(); und flush_rewrite_rules(true); zu verwenden.

Ich habe auch versucht, $wp_rewrite mit $wp_rewrite->flush_rules(); und $wp_rewrite->flush_rules(true); zu globalisieren.

Keiner von beiden scheint die Umschreiberegeln korrekt zu löschen. Diese Aufrufe löschen tatsächlich die Umschreiberegeln, wenn sie aufgerufen werden. Woher weiß ich das? Verwenden der Lösung zum Debuggen von Rewrite Rule Flushing .

Derzeit habe ich die Regeln für die Aktivierung und Deaktivierung von Plugins überarbeitet. Keine Probleme da.

Ich habe eine Plugin-Administrationseinstellungsseite, auf der Benutzer das Plugin konfigurieren können. Einige der Einstellungen passen die Permalink-Struktur an, sodass die Umschreiberegeln auf der Seite "Einstellungen speichern" der Plugin-Administrationseinstellungen gelöscht werden müssen. (Verwendet den Standard update_option();) zum Speichern von Einstellungen.

Ich möchte darauf hinweisen, dass in Abhängigkeit von den angegebenen Einstellungen benutzerdefinierte Beitragstypen erstellt werden, die den benutzerdefinierten Einstellungen entsprechen. Daher müssen die Umschreiberegeln sofort nach dem Speichern der Einstellungen gelöscht werden. Hier funktionieren die Dinge nicht richtig.

Die obige Link-Lösung zum Debuggen von Umschreiberegeln, die von @toscho bereitgestellt wird, zeigt an, dass Tonnen von Umschreiberegeln gelöscht werden. Wenn Sie jedoch ein einzelnes Element mit benutzerdefiniertem Post-Typ oder sogar ein Archiv mit benutzerdefiniertem Post-Typ besuchen, wird jeder Fehler als 404 zurückgegeben.

Der benutzerdefinierte Post-Typ ist korrekt und richtig registriert. Ich weiß mit Sicherheit, dass das nicht das Problem ist.

Sofort danach mit dem Plugin die Einstellungen der Administrationsseite speichern. Die benutzerdefinierten Beitragstypen werden erstellt, die Permalink-Struktur wird angepasst und es wird versucht, alle Umschreiberegeln zu löschen.

Die benutzerdefinierten Beitragstypen werden dann immer und wie gewohnt in init geladen.

Aus irgendeinem Grund werden die Umschreiberegeln nicht richtig gelöscht, weil, wie ich bereits sagte, der Besuch einzelner oder Archivabschnitte des benutzerdefinierten Beitragstyps 404-Fehler zurückgibt.

Nun, der seltsame Teil, wenn ich nur die Einstellungsseite für Administrations-Permalinks besuche und dann zum Frontend zurück gehe, um entweder einzelne oder Archivabschnitte des benutzerdefinierten Beitragstyps anzuzeigen, funktionieren sie auf magische Weise wie erwartet.

Was bewirkt die Seite mit den Einstellungen für Administrationspermalinks, die ich nicht tue, damit die Umschreiberegeln ordnungsgemäß gelöscht werden und meine nicht?

Ich meine, als vorübergehende Lösung leite ich den Benutzer nach dem Speichern der Seite mit den Einstellungen für die Administration von Permalinks auf die Seite mit den Einstellungen für die Administration von Plugins um, aber dies ist keine ideale Lösung. Ich würde es vorziehen, wenn die Umschreiberegeln nur richtig in den Code meines Plugins geschrieben werden.

Gibt es einen bestimmten Punkt in WordPress, an dem das Löschen der Umschreiberegeln nicht mehr ALLE Regeln löscht?

admin_menu - Die Plugin-Einstellungsseite wurde der WordPress-Administration hinzugefügt.

add_options_page() - Die Plugin-Einstellungsseite wird im Einstellungsmenü hinzugefügt.

Die Einstellungsseite wird im Rückruf für add_options_page() gerendert. Hier wird auch $_POST verarbeitet, um die Plugin-Einstellungen zu aktualisieren und die Umschreiberegeln zu löschen.

Da dies bereits eine lange Frage ist, wäre ich bereit, Codeblöcke (sofern dies hilfreich ist) in einem externen Link bereitzustellen, um die Erstellung einer gültigen Antwort zu unterstützen.

10
Michael Ecklund

Der beste Ort zum Löschen von Überschreibregeln ist die Aktivierung/Deaktivierung des Plugins.

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

Siehe den Kodex Artikel

Entschuldigung im Voraus, ich habe Ihre Frage nicht vollständig durchgearbeitet, daher handelt es sich hier um eine Art Cookie-Cutter-Antwort.

4
helgatheviking

Schwer zu sagen, was falsch ist, ohne Ihren Code zu sehen. Nach dem Speichern einiger Einstellungen ist es jedoch praktisch, sich wie unten gezeigt in admin_init einzuklinken, um Ihre Umschreiberegeln zu löschen.

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


Sie müssen die Option auf Ihrer Einstellungsseite einstellen oder genau festlegen, wo die Einstellungen gespeichert werden sollen. Es ist schlecht, es ohne die Option zu tun, da Sie die Regeln nicht jedes Mal löschen möchten.


Hinweis: ungetestet

4
Nicolai

Ich hatte eine Klassendatei für Beitragstypen, die dafür verantwortlich war, die Optionseinstellungen des Plugins zu lesen und die erforderlichen benutzerdefinierten Beitragstypen basierend auf den benutzerdefinierten Einstellungen zu erstellen.

Diese Klassendatei für Beitragstypen wurde in den Hook init geladen.

Ich dachte, alles, was ich tun müsste, wäre, die Plugin-Einstellungen zu aktualisieren und dann die Umschreiberegeln zu löschen. Da die Beitragstypenklasse bereits anhand der Plugin-Einstellungen geladen wurde. Bei Verwaltungsseiten werden sie jedoch NACH dem Hook init geladen.

Die Beitragstypen wurden nie registriert, da die Einstellungen noch nicht vorgenommen wurden. Die Registrierungsklasse für Beitragstypen wurde vorzeitig beendet, ohne dass Beitragstypen registriert wurden.

Die Lösung war:

  1. Aktualisieren Sie die Plugin-Einstellungen.
  2. Laden Sie die Klassendatei für Beitragstypen NUR einmal hierher, damit die neuen Umschreiberegeln erstellt werden.
  3. Flush die Rewrite-Regeln.

(Bisher fehlte ... Schritt 2 - Wie oben erwähnt ...)

Von nun an werden Beitragstypen in den Hook init geladen und es werden bereits Einstellungen festgelegt, mit denen Beitragstypen erstellt und mit den entsprechenden Umschreiberegeln verknüpft werden können.

Aus irgendeinem Grund musste ich einen JavaScript-Aufruf hinzufügen, um zur aktuellen Seite umzuleiten, nachdem ich die obigen drei Schritte ausgeführt hatte.

Ich musste auch einen Aufruf an flush_rewrite_rules(); auf der Seite mit den Verwaltungseinstellungen des Plugins hinzufügen.

Also, um sicherzustellen, dass alles gespült wird ...

Schritt 1) ​​Navigieren Sie zur Seite mit den Administrationseinstellungen des Plugins. - Erstes Spülen.

Schritt 2) Aktualisieren Sie die Plugin-Einstellungen. - Zweite Spülung.

Schritt 3) Seite leitet zur Einstellungsseite des Plugins weiter. Causing the ... Third und Final Flush (wie Initial Flush - Wird automatisch ausgeführt, wenn die Einstellungsseite des Plugins aufgerufen wird)

Ich sage nicht, dass dies eine praktische Lösung ist, aber es hat bei mir funktioniert. Sehr seltsames Problem und hat höchstwahrscheinlich mit meiner Codierungsinfrastruktur zu tun.

3
Michael Ecklund

@ tazo-todua das hat auch bei mir bei der Verwendung von Multisite geklappt.

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();
}
1
stillatmylinux

Meine gefundene Lösung war:

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

Ich hatte genau das gleiche Problem. In meinem Plugin habe ich Post-Typen, die dynamisch erstellt werden. Sie können daher nicht über register_post_type() in einer statischen Methode während des activation_hook registriert werden und sind daher noch nicht aktiv, wenn flush_rewrite_rules() während dieses Hooks ausgeführt wird (dies ist normalerweise die empfohlene Methode für das Löschen von Umschreibregeln).

Die sauberste Lösung, die ich am Ende finden konnte, bestand darin, die Umschreiberegeln nach der Registrierung der Beitragstypen zu leeren, aber natürlich nur, wenn ein solches Löschen tatsächlich notwendig war (weil der Vorgang langsam ist). In meinem Fall habe ich tatsächlich mehrere benutzerdefinierte Beitragstypen, die von einer einzelnen Basisklasse erben, und daher war es wünschenswert, den Code zu implementieren, der das Leeren dort ausführt.

Ob eine Spülung erforderlich ist, kann anhand der Ausgabe von get_option( 'rewrite_rules' ) entschieden werden:

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

Nachteile:

  • Beruht in gewissem Maße darauf, welche genauen Umschreibregeln WP während register_post_type() generiert werden.
  • Wenn Sie bei jedem Laden der Seite überprüfen, ob eine Spülung erforderlich ist, entsteht ein gewisser Overhead.

Vorteile:

  • Vollständig gekapselt in der Klasse, die den Beitragstyp darstellt.
  • Löscht die Umschreiberegeln nur, wenn dies wirklich notwendig ist.

Verwenden Sie dies nur, wenn Sie Ihren Beitragstyp nicht in einer statischen Funktion registrieren können, die sowohl init als auch den activation_hook aufrufen kann!

Die Abhängigkeit davon, wie die während register_post_type() erzeugten Umschreiberegeln aussehen, kann verringert werden, indem der Test if(strpos($key, $args['rewrite']['slug'] ) === 0) durch etwas Ausführlicheres, d. H. Einen regulären Ausdruck, ersetzt wird.

0
cgogolin