Gdzie, kiedy i jak prawidłowo przepłukać Przepisz reguły w zakresie wtyczki?


10

Mam trochę dziwny problem z nieprawidłowym opróżnianiem reguł przepisywania.

Próbowałem użyć flush_rewrite_rules();i flush_rewrite_rules(true);.

Próbowałem także globalizacji $wp_rewriteza pomocą $wp_rewrite->flush_rules();i$wp_rewrite->flush_rules(true);

Żaden z nich nie wydaje się poprawnie przepłukiwać reguł przepisywania. Te połączenia rzeczywiście opróżniają reguły przepisywania po wywołaniu. Skąd to wiem? Korzystanie z rozwiązania do debugowania przepłukiwania reguł przepisywania .

Obecnie mam przepisane przepisy dotyczące aktywacji i dezaktywacji wtyczek. Brak problemów.

Mam stronę ustawień administracji wtyczki, aby użytkownicy mogli skonfigurować wtyczkę. Niektóre ustawienia dostosowują strukturę permalink, więc reguły przepisywania muszą być opróżnione na stronie ustawień administracyjnych wtyczki „Zapisz ustawienia”. (Wykorzystuje standard update_option();) do zapisywania ustawień.

Chciałbym zauważyć, że w zależności od określonych ustawień tworzone są niestandardowe typy postów, aby pasowały do ​​ustawień określonych przez użytkownika. Dlatego reguły przepisywania muszą zostać usunięte natychmiast po zapisaniu ustawień. To tutaj rzeczy nie działają poprawnie.

Powyższe rozwiązanie link do debugowania reguł przepisywania dostarczone przez @toschopokazuje, że to spłukuje mnóstwo reguł przepisywania. Jednak podczas odwiedzania pojedynczego elementu niestandardowego typu posta, a nawet archiwum niestandardowego typu postu, każdy zwraca 404 błędów.

Niestandardowy typ postu jest zarejestrowany poprawnie i odpowiednio. Wiem na pewno, że nie o to chodzi.

Natychmiast następuje zapisanie ustawień strony administracyjnej wtyczki. Tworzone są niestandardowe typy postów, dostosowywana jest struktura permalink, a wszystkie reguły przepisywania są usuwane.

Niestandardowe typy postów są następnie ładowane zawsze i ładowane initnormalnie.

Z jakiegoś powodu reguły przepisywania nie są poprawnie opróżniane, ponieważ, jak powiedziałem wcześniej, odwiedzanie pojedynczych lub archiwalnych sekcji niestandardowego typu posta zwraca błędy 404.

Teraz dziwne jest to, że jeśli wszystko, co robię, to po prostu odwiedzam stronę ustawień permalinków administracyjnych, a następnie wracam do interfejsu, aby wyświetlić sekcje pojedyncze lub archiwalne niestandardowego typu postów, działają one magicznie zgodnie z oczekiwaniami.

Co robi ta strona ustawień administracyjnych Permalinks, czego nie robię, co pozwala na prawidłowe przepisywanie reguł przepisywania, a moje nie?

Mam na myśli, że jako rozwiązanie tymczasowe przekierowuję użytkownika na stronę ustawień bezpośrednich linków administracyjnych po zapisaniu strony ustawień administracyjnych wtyczek, ale nie jest to idealne rozwiązanie. Wolałbym, żeby reguły przepisywania były poprawnie umieszczone w kodzie mojej wtyczki.

Czy jest jakiś punkt w WordPress, w którym opróżnianie reguł przepisywania po prostu już nie opróżnia WSZYSTKICH reguł?

admin_menu - Strona ustawień wtyczek została dodana do administracji WordPress.

add_options_page() - Strona ustawień wtyczek została dodana w menu Ustawienia.

Strona ustawień jest renderowana w wywołaniu zwrotnym dla add_options_page(). Tutaj $_POSTprzetwarzane są także ustawienia aktualizacji wtyczek i reguły przepisywania przy przepłukiwaniu.

Ponieważ jest to już długie pytanie, chętnie przedstawię bloki kodu (jeśli to pomoże) w linku zewnętrznym, które pomogą w uzyskaniu prawidłowej odpowiedzi.


1
brzmi to tak, jakbyś źle ułożył kolejność rzeczy, trudno powiedzieć, nie widząc żadnego kodu. strona admin permalinks po prostu wywołuje flush_rewrite_rules, co po prostu usuwa rewrite_rulesopcję i regeneruje ją, możesz otworzyć plik wp-admin/options-permalinks.phpi zobaczyć, gdzie to się dzieje. ponieważ ta operacja po prostu usuwa całą opcję, nie można częściowo opróżnić reguł.
Milo

@Milo Myślę, że masz rację. Mam ładowaną klasę, initktóra rejestruje typy postów. Pomyślałem, że ustawienia strony są zapisywane, a strona przeładuje się ... a następnie initponownie uruchomi hak, aby zarejestrować niezbędne typy postów. Doszedłem więc do wniosku, że typy postów będą już załadowane i wystarczyło zaktualizować opcję, a następnie opróżnić reguły przepisywania ze strony ustawień wtyczek. Wyślę odpowiedź, jak wymyśliłem rozwiązanie.
Michael Ecklund

Tylko ostrzeżenie flush_rewrite_rules () w mojej wtyczce okazało się dla mnie częścią problemu. Usunąłem haka php i skończyłem po prostu ręcznie aktualizować permalinki, a moje błędy CPT 404 zniknęły.
myol,

Odpowiedzi:


5

Najlepszym miejscem do opróżnienia reguł przepisywania jest aktywacja / dezaktywacja wtyczki.

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

Zobacz artykuł o kodeksie

Z góry przepraszam, nie przebrnąłem przez całe twoje pytanie, więc jest to trochę odpowiedź na fałszywe ciasteczka.


1
Dziękuję za twoją sugestię, ale jestem tego świadomy. Problem nie dotyczy aktywacji / dezaktywacji wtyczek. Ma to związek z tym, że użytkownicy zmieniają ustawienia na już aktywną wtyczkę, która dostosowuje reguły przepisywania, tym samym wymagając opróżnienia.
Michael Ecklund

1
Myślałem, że może tak być, ale byłem dość zmęczony, kiedy czytałem twoje pytanie. Rozwiązanie ialocin wygląda obiecująco, mam nadzieję, że się udało.
helgatheviking

4

Trudno powiedzieć, co jest nie tak, nie widząc kodu. Ale po zapisaniu niektórych ustawień warto podłączyć się admin_inittak, jak pokazano poniżej, aby opróżnić reguły przepisywania.

Kod:

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


Musisz ustawić opcję gdzieś na stronie ustawień lub dokładnie gdzieś w trakcie zapisywania ustawień. Robienie tego bez opcji jest złe, ponieważ nie chcesz za każdym razem opróżniać reguł.


Uwaga: niesprawdzone


2
A może mógłbyś użyć przejściowego? Ale zdecydowanie +1 za nie opróżnianie reguł na każdym admin_init.
helgatheviking

Masz oczywiście rację, jeśli chodzi o przejściowe, chyba wybrałem to ze *_option()względu na stronę ustawień. @helgatheviking
Nicolai

To było bardzo pomocne. Miałem sytuację podobną do Michaela. Skończyło się na tym, że dołączyłem sugestię helgi dotyczącą używania stanu przejściowego i ustawiłem ją w funkcji sprawdzania poprawności ustawień. Skończyło się na tym, że musiałem ustawić transient na false po opróżnieniu, w przeciwnym razie po prostu ładowałam się przy każdym ładowaniu strony administratora, dopóki transient nie wygasł. Funkcjonalne użycie opcji lub stanu przejściowego było takie samo. Sądzę, że przemijanie może być miłe, aby utrzymać trochę czystszą tabelę opcji. Ale drobna uwaga.
MatthewLee

Różnica jest rzeczywiście niewielka, szczególnie jeśli transjenty są trwałe, nie wygasają, ale oczywiście transjenty mają inne możliwości, korzyści, które są miłe. @MatthewLee
Nicolai

3

Miałem plik klasy typów postów, który był odpowiedzialny za czytanie ustawień opcji wtyczki i tworzenie niezbędnych niestandardowych typów postów na podstawie ustawień określonych przez użytkownika.

Ten plik klasy typów postów został załadowany na haku init.

Uznałem, że wszystko, co muszę zrobić, to zaktualizować ustawienia wtyczki, a następnie opróżnić reguły przepisywania. Ponieważ klasa typów postów została już załadowana na podstawie ustawień wtyczki. Ale strony administracyjne są ładowane PO inithaku.

Typy postów nigdy nie zostały zarejestrowane, ponieważ ustawienia nie zostały jeszcze ustawione. Klasa rejestracji typów postów zakończyła się przedwcześnie bez zarejestrowanych typów postów.

Rozwiązaniem było:

  1. Zaktualizuj ustawienia wtyczki.
  2. Załaduj plik klasy typów postów TYLKO jeden raz, aby zostały utworzone nowe reguły przepisywania.
  3. Opróżnij reguły przepisywania.

(Wcześniej ... brakowało kroku 2 - jak wspomniano powyżej ...)

Od tej pory typy postów będą ładowane na inithaku i będą miały określone ustawienia, pozwalając na tworzenie i łączenie typów postów z odpowiednimi regułami przepisywania.

Z jakiegokolwiek powodu musiałem dodać wywołanie JavaScript, aby przekierować na bieżącą stronę, po wykonaniu powyższych trzech kroków.

Musiałem także dodać wywołanie flush_rewrite_rules();na stronie ustawień administracyjnych wtyczki.

Więc w celu zapewnienia, że ​​wszystko jest opróżnione ...

Krok 1) Przejdź do strony ustawień administracyjnych wtyczki. - Wstępne spłukiwanie.

Krok 2) Zaktualizuj ustawienia wtyczek. - Drugie spłukanie.

Krok 3) Strona przekierowuje na stronę ustawień wtyczki. Powodowanie ... Trzeciego i ostatniego spłukiwania (tak samo jak wstępne spłukiwanie - Wykonane automatycznie, gdy strona ustawień wtyczki zostanie odwiedzona)

Nie twierdzę, że to praktyczne rozwiązanie, ale zadziałało dla mnie. Bardzo dziwny problem i najprawdopodobniej dotyczy mojej infrastruktury kodowania.


1

@ tazo-todua to również działało dla mnie podczas korzystania z wielu witryn.

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

0

MOJE znalezione ROZWIĄZANIE BYŁO:

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

0

Miałem dokładnie ten sam problem. W mojej wtyczce mam typy postów tworzone dynamicznie. Dlatego nie można ich zarejestrować za register_post_type()pomocą metody statycznej podczas activation_hooki dlatego nie są jeszcze aktywne, gdy flush_rewrite_rules()są uruchamiane podczas tego przechwytywania (co jest zwykle zalecanym sposobem przepłukiwania reguł przepisywania).

Najczystszym rozwiązaniem, jakie udało mi się w końcu wymyślić, było opróżnienie reguł przepisywania po rejestracji typów postów, ale oczywiście tylko wtedy, gdy takie opróżnianie było faktycznie konieczne (ponieważ operacja jest powolna). W moim przypadku mam kilka niestandardowych typów postów, które dziedziczą po jednej klasie bazowej, dlatego pożądane było zaimplementowanie tam kodu, który tam opróżnia.

O tym, czy konieczne jest płukanie, można zdecydować, patrząc na wynik 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);
}
}

Wady:

  • W pewnym stopniu opiera się na dokładnych regułach przepisywania generowanych przez WP register_post_type().
  • Sprawdzanie, czy płukanie jest konieczne podczas każdego ładowania strony, również powoduje pewne obciążenie.

Zalety:

  • Całkowicie zamknięty w klasie reprezentującej typ postu.
  • Opróżnia reguły przepisywania tylko wtedy, gdy jest to naprawdę konieczne.

Używaj tego tylko, jeśli nie możesz zarejestrować swojego typu posta w funkcji statycznej, która może być wywoływana zarówno podczas, jak initi activation_hook!

Zależność od tego, jak reguły przepisywania generowane podczas register_post_type()wyglądania można złagodzić, zastępując test if(strpos($key, $args['rewrite']['slug'] ) === 0)bardziej rozbudowanym, np. Wyrażeniem regularnym.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.