Wie können Sie in einer Situation, in der ein Plugin seine Methoden in einer Klasse gekapselt und dann einen Filter oder eine Aktion für eine dieser Methoden registriert hat, die Aktion oder den Filter entfernen, wenn Sie keinen Zugriff mehr auf die Instanz dieser Klasse haben?
Angenommen, Sie haben ein Plugin, das dies ausführt:
class MyClass {
function __construct() {
add_action( "plugins_loaded", array( $this, 'my_action' ) );
}
function my_action() {
// do stuff...
}
}
new MyClass();
Wie kann ich die Registrierung der Klasse aufheben, da ich jetzt keine Möglichkeit mehr habe, auf die Instanz zuzugreifen? Dies remove_action( "plugins_loaded", array( MyClass, 'my_action' ) );
scheint nicht der richtige Ansatz zu sein - zumindest schien es in meinem Fall nicht zu funktionieren.
Antworten:
Am besten verwenden Sie hier eine statische Klasse. Der folgende Code sollte anweisend sein:
Wenn Sie diesen Code von einem Plugin ausführen, sollten Sie beachten, dass die Methode der StaticClass sowie die Funktion von wp_footer entfernt werden.
quelle
remove_action
Funktion verwenden, sonst funktioniert es nicht. Deshalb musste ich meine eigene Funktion schreiben, um damit umzugehen, wenn es keine statische Klasse ist. Diese Antwort ist nur dann am besten, wenn Ihre Frage Ihren eigenen CodeJedes Mal, wenn ein Plugin ein erstellt
new MyClass();
, sollte es einer eindeutig benannten Variablen zugewiesen werden. Auf diese Weise kann auf die Instanz der Klasse zugegriffen werden.Wenn er es also tun würde
$myclass = new MyClass();
, dann könnten Sie dies tun:Dies funktioniert, weil Plugins im globalen Namespace enthalten sind, sodass implizite Variablendeklarationen im Hauptteil eines Plugins globale Variablen sind.
Wenn das Plugin den Bezeichner der neuen Klasse nicht irgendwo speichert , ist das technisch gesehen ein Fehler. Eines der allgemeinen Prinzipien der objektorientierten Programmierung ist, dass Objekte, auf die von keiner Variablen irgendwo verwiesen wird, bereinigt oder beseitigt werden müssen.
Insbesondere PHP tut dies nicht wie Java, da PHP eine halbherzige OOP-Implementierung ist. Die Instanzvariablen sind nur Strings mit eindeutigen Objektnamen. Sie funktionieren nur aufgrund der Art und Weise, wie die Interaktion mit dem Variablenfunktionsnamen mit dem
->
Operator funktioniert . So einfach zu machennew class()
kann in der Tat perfekt funktionieren, nur dumm. :)Unterm Strich also niemals
new class();
. Machen Sie$var = new class();
das $ var auf irgendeine Weise zugänglich, damit andere Bits darauf verweisen können.Edit: Jahre später
Eine Sache, die ich bei vielen Plugins gesehen habe, ist die Verwendung eines ähnlichen Musters wie "Singleton". Sie erstellen eine getInstance () -Methode, um die einzelne Instanz der Klasse abzurufen. Dies ist wahrscheinlich die beste Lösung, die ich gesehen habe. Beispiel Plugin:
Beim ersten Aufruf von getInstance () wird die Klasse instanziiert und der Zeiger gespeichert. Damit können Sie Aktionen einbinden.
Ein Problem dabei ist, dass Sie getInstance () nicht im Konstruktor verwenden können, wenn Sie so etwas verwenden. Dies liegt daran, dass der Konstruktor von new vor dem Festlegen der $ -Instanz aufgerufen wird. Daher führt der Aufruf von getInstance () aus dem Konstruktor zu einer Endlosschleife und unterbricht alles.
Eine Problemumgehung besteht darin, den Konstruktor nicht zu verwenden (oder zumindest getInstance () darin nicht zu verwenden), sondern explizit eine "init" -Funktion in der Klasse zu haben, um Ihre Aktionen und dergleichen einzurichten. So was:
Mit so etwas wird am Ende der Datei, nachdem alle Klassen definiert wurden, das Instanziieren des Plugins so einfach wie folgt:
Init fügt Ihre Aktionen hinzu und ruft dabei getInstance () auf, das die Klasse instanziiert und sicherstellt, dass nur eine von ihnen existiert. Wenn Sie keine init-Funktion haben, würden Sie dies tun, um die Klasse stattdessen zunächst zu instanziieren:
Um die ursprüngliche Frage zu beantworten, können Sie diesen Aktionshaken von außen (auch bekannt als in einem anderen Plugin) folgendermaßen entfernen:
Setzen Sie das in etwas ein, das an den
plugins_loaded
Aktionshaken angehängt ist, und es macht die Aktion rückgängig, die vom ursprünglichen Plugin angehängt wird.quelle
wp_loaded
nicht anschließenplugins_loaded
, was möglicherweise zu früh aufgerufen wird.plugins_loaded
wäre der richtige Ort. Diewp_loaded
Aktion findet nach derinit
Aktion statt. Wenn Ihr Plugin also Aktionen ausführtinit
(und die meisten ausführen ), möchten Sie das Plugin initialisieren und davor einrichten. Derplugins_loaded
Haken ist der richtige Ort für diese Bauphase.2 kleine PHP-Funktionen zum Entfernen von Filtern / Aktionen mit "anonymer" Klasse: https://github.com/herewithme/wp-filters-extras/
quelle
Hier ist eine ausführlich dokumentierte Funktion, die ich zum Entfernen von Filtern erstellt habe, wenn Sie keinen Zugriff auf das Klassenobjekt haben (funktioniert mit WordPress 1.2+, einschließlich 4.7+):
https://gist.github.com/tripflex/c6518efc1753cf2392559866b4bd1a53
quelle
Die obigen Lösungen sehen aus wie veraltet, mussten meine eigenen schreiben ...
quelle
Diese Funktion basiert auf @ Digerkam Antwort. Compare if
$def['function'][0]
is string hinzugefügt und es hat endlich für mich funktioniert.Auch mit
$wp_filter[$tag]->remove_filter()
sollte es stabiler machen.Anwendungsbeispiel:
Genaue Übereinstimmung
Beliebige Priorität
Jede Klasse und jede Priorität
quelle
Dies ist keine generische Antwort, sondern eine für das Avada-Thema und WooCommerce spezifische Antwort, die meines Erachtens für andere hilfreich sein kann:
quelle