W moim functions.phppliku chciałbym usunąć poniższy filtr, ale nie jestem pewien, jak to zrobić, ponieważ jest w klasie. Jak powinien remove_filter()wyglądać
WordPress potrzebuje nazwy filtra. Nie dostarczyliśmy jednego, więc WordPress wywołuje _wp_filter_build_unique_id()i tworzy jeden. Ta nazwa nie jest przewidywalna, ponieważ używa spl_object_hash().
Jeśli prowadzimy var_export()na $GLOBALS['wp_filter'][ 'wp_footer' ]Dostajemy teraz coś takiego:
Aby znaleźć i usunąć naszą złą akcję, musimy przejść przez powiązane filtry przechwytujące (akcja jest po prostu bardzo prostym filtrem), sprawdzić, czy jest to tablica i czy obiekt jest instancją klasy. Następnie bierzemy priorytet i wyjąć filtr, nigdy nie widząc prawdziwego identyfikatora .
Kiedy wywołujemy tę funkcję? Nie ma pewności, kiedy powstanie oryginalny obiekt. Może czasami wcześniej 'plugins_loaded'? Może później?
Używamy tego samego haka, z którym jest powiązany obiekt, i wskakujemy bardzo wcześnie z priorytetem 0. To jedyny sposób, aby być naprawdę pewnym. Oto jak usunęlibyśmy metodę print_message_3():
@MikeSchinkel Powiązany pomysł , jak dotąd nie wypróbowałem go w praktyce.
fuxia
Ciekawy. Uważam twoją odpowiedź za bardzo dobrą, ale twój ostatni wniosek jest dość kiepski. Moim zdaniem instancje klas powinny być generowane natychmiast po załadowaniu wtyczki przez WordPress. Następnie konstruktor instancji klasy nie powinien wykonywać żadnych rzeczywistych akcji, wystarczy dodać akcje i filtry. W ten sposób wtyczki, które chcą usunąć akcje i filtry z instancji klasy, mogą mieć pewność, że zostaną faktycznie dodane po plugins_loadedwywołaniu, co jest właśnie po to plugins_loaded. Oczywiście instancja klasy nadal musi być dostępna, być może poprzez wzorzec singletonu.
engelen
@engelen To jest stara odpowiedź. Obecnie oferowałbym akcję usuwania oddzwaniania. Ale nie Singleton, to anty-wzór z wielu powodów.
fuxia
Ta odpowiedź działa również w przypadku usuwania akcji, takich jakremove_action()
Nick Pyett
0
Nie jestem pewien, ale możesz spróbować użyć singletona.
Musisz zapisać odwołanie do obiektu we właściwości statycznej swojej klasy, a następnie zwrócić tę zmienną statyczną z metody statycznej. Coś takiego:
Tak długo, jak znasz ten obiekt (i używasz PHP 5.2 lub nowszego - aktualna stabilna wersja PHP to 5.5, 5.4 jest nadal obsługiwany, 5.3 to koniec życia), możesz po prostu usunąć go za pomocą remove_filter()metody. Wszystko, co musisz zapamiętać, to obiekt, nazwa metody i priorytet (jeśli jest używany):
Jednak popełniacie mały błąd w kodzie. Nie prefiks $thisze znakiem ampersand &, który był potrzebny w PHP 4 (!), I jest to od dawna spóźnione. Może to sprawić, że radzenie sobie z hakami będzie problematyczne, więc po prostu odsuń się na bok:
&
z&$this
, to jest PHP 4Odpowiedzi:
To bardzo dobre pytanie. Wszystko sprowadza się do mrocznego serca interfejsu API wtyczki i najlepszych praktyk programistycznych.
Dla poniższej odpowiedzi stworzyłem prostą wtyczkę ilustrującą problem z łatwym do odczytania kodem.
Teraz widzimy to:
WordPress potrzebuje nazwy filtra. Nie dostarczyliśmy jednego, więc WordPress wywołuje
_wp_filter_build_unique_id()
i tworzy jeden. Ta nazwa nie jest przewidywalna, ponieważ używaspl_object_hash()
.Jeśli prowadzimy
var_export()
na$GLOBALS['wp_filter'][ 'wp_footer' ]
Dostajemy teraz coś takiego:Aby znaleźć i usunąć naszą złą akcję, musimy przejść przez powiązane filtry przechwytujące (akcja jest po prostu bardzo prostym filtrem), sprawdzić, czy jest to tablica i czy obiekt jest instancją klasy. Następnie bierzemy priorytet i wyjąć filtr, nigdy nie widząc prawdziwego identyfikatora .
Ok, umieśćmy to w funkcji:
Kiedy wywołujemy tę funkcję? Nie ma pewności, kiedy powstanie oryginalny obiekt. Może czasami wcześniej
'plugins_loaded'
? Może później?Używamy tego samego haka, z którym jest powiązany obiekt, i wskakujemy bardzo wcześnie z priorytetem
0
. To jedyny sposób, aby być naprawdę pewnym. Oto jak usunęlibyśmy metodęprint_message_3()
:Wynik:
I to powinno usunąć działanie z twojego pytania (nie przetestowane):
Wniosek
'plugins_loaded'
. Nie tylko wtedy, gdy wtyczka jest wywoływana przez WordPress.źródło
plugins_loaded
wywołaniu, co jest właśnie po toplugins_loaded
. Oczywiście instancja klasy nadal musi być dostępna, być może poprzez wzorzec singletonu.remove_action()
Nie jestem pewien, ale możesz spróbować użyć singletona.
Musisz zapisać odwołanie do obiektu we właściwości statycznej swojej klasy, a następnie zwrócić tę zmienną statyczną z metody statycznej. Coś takiego:
źródło
Tak długo, jak znasz ten obiekt (i używasz PHP 5.2 lub nowszego - aktualna stabilna wersja PHP to 5.5, 5.4 jest nadal obsługiwany, 5.3 to koniec życia), możesz po prostu usunąć go za pomocą
remove_filter()
metody. Wszystko, co musisz zapamiętać, to obiekt, nazwa metody i priorytet (jeśli jest używany):Jednak popełniacie mały błąd w kodzie. Nie prefiks
$this
ze znakiem ampersand&
, który był potrzebny w PHP 4 (!), I jest to od dawna spóźnione. Może to sprawić, że radzenie sobie z hakami będzie problematyczne, więc po prostu odsuń się na bok:I to wszystko.
źródło
$this
z zewnątrz (inna wtyczka / motyw).