Welche Klassen sind in Magento 2 abfang- / pluginfähig?

17

Datum: 30. Mai 2015 (angesichts der sich ändernden Art von Magento 2).

Magento 2 führte ein Plugin-Konzept ein , das über ein Interceptor-Pattern implementiert wurde .

Was in den Dokumenten nicht klar ist: Welche Klassen und Objekte in Magento können abgefangen werden? Das heißt, Sie konfigurieren ein Plugin mit XML, das wie folgt aussieht

<config>
    <type name="{ObservedType}">
        <plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="true"/>
    </type>
</config>

Es ist jedoch nicht klar, welche Klassen als gültig sind ObservedType. Dieser ältere Wiki-Artikel bietet einige Hinweise, wenn es heißt

Bitte beachten Sie, dass die Plug-in-Funktion nicht für Klassen gilt, die ohne Abhängigkeitsinjektion erstellt wurden, dh mit dem Operator new direkt erstellt wurden. -Final-Methoden, -Final-Klassen

Ist ein Objekt, das über die Abhängigkeitsinjektion erstellt wurde, zum Abfangen verfügbar? Muss das ObservedTypeder Typ-Hinweis sein, der in der a- __constructMethode bereitgestellt wird, oder kann es (sollte es sein?) Etwas anderes sein?

Ich versuche vor allem, mich mit dem zu beschäftigen, was mit einem Magento 2-Interceptor möglich und nicht möglich ist, bevor ich sie verwende.

Alan Storm
quelle

Antworten:

10

Jede Klasse eines Magento-Moduls ist untereinander kompatibel.

Wie im aktuellen Wiki beschrieben, ist es durch endgültige Methoden und Klassen begrenzt

Nicht validiert, aber Klassen von Bibliotheken (lib-Verzeichnis) dürfen (/ sollten) nicht abgefangen werden.

Die Einschränkung, wie das Objekt erstellt wurde, ist meines Erachtens nicht mehr wahr, zumindest wenn der Autoloader richtig konfiguriert ist. Und sollte keine Rolle spielen, da sie nicht im laufenden Betrieb erstellt werden, sondern wenn der Generator ausgeführt wurde. (so ist es nur eine Frage von, der Magento Autoloader sollte der erste sein)

Flyingmana
quelle
2
Wir haben keine Einschränkung für das Abfangen von Bibliotheksklassen. Damit ein Objekt abgefangen werden kann, muss es mit ObjectManager (Konstruktorinjektion) erstellt werden.
Anton Kril
1
Es sollte beachtet werden, dass magische Methoden (die aber mit phpdoc deklariert wurden) nicht abgefangen werden können. Meiner Ansicht nach. Der Varien_Object-Stil ist an einigen Stellen noch vorhanden.
Mittwoch,
11

Wir arbeiten an "@api" -Anmerkungen, um empfohlene Methoden zu kommentieren , die über Releases hinweg stabiler sind. Wenn Sie sich über Aufrüstbarkeit kümmern, zusätzlich zu dem, was kann ein Plugin definiert haben, sollten Sie auch überlegen , was sollte ein Plugin definiert haben. Wir empfehlen, keine non-@ api-Methoden abzufangen, aber manchmal wissen wir, dass dies die beste Option sein kann. (Das überlassen wir dem Entwickler.)

Offiziell können Sie öffentliche Methoden abfangen, die nicht endgültig sind. Private Methoden funktionieren definitiv nicht. Beim Abfangen aus dem Speicher wird derzeit eine abgeleitete Klasse erstellt, die die reale Klasse erbt (das Abhängigkeitsinjektionsframework erstellt Instanzen der generierten Klasse, wenn Sie nach einer neuen Instanz der realen Klasse fragen). Alles, was es ermöglicht, eine Unterklasse zu erstellen und die ursprüngliche Methode zu überschreiben, wird wahrscheinlich funktionieren. Es werden jedoch öffentliche Methoden empfohlen, die uns die Flexibilität geben, in Zukunft eine andere clevere Implementierung zu verwenden (die ohne guten Grund niemals realistisch sein würde). .

Alan Kent
quelle
5

Ich weiß, das hat schon eine Antwort, aber es ist von vor 2 Jahren. Vielleicht hat sich in der Zwischenzeit einiges geändert.

Folgendes habe ich bisher gefunden.
Von der offiziellen Dokumentation und vom Eingraben in den Abfangprozess.

Ich werde andersherum antworten.
Was KANN NICHT 2. in Magento abgefangen
Aus dem offiziellen doc

  • Objekte, die vor dem Bootstrapping von Magento \ Framework \ Interception instanziiert wurden (nicht sicher, wo sich dieser Punkt befindet)
  • Endgültige Methoden
  • Jede Methode aus finalen Klassen (da die generierte Interceptor-Klasse die ursprüngliche Klasse erweitern muss)
  • Jede Klasse, die mindestens eine letzte öffentliche Methode enthält
  • Nicht öffentliche Methoden (es könnte für geschützte Methoden funktionieren, aber dies ist nicht "ethisch", da es nicht öffentliche Methoden außerhalb der Klasse verfügbar macht)
  • statische Methoden
  • __konstruieren
  • Virtuelle Typen

Vom Herumgraben

  • Methoden in Klassen, die nicht über den Objektmanager instanziiert werden. (Beispiel \Magento\Framework\Phrase)
  • Klassen implementieren \Magento\Framework\ObjectManager\NoninterceptableInterface. (Zum Beispiel \Magento\Framework\App\Cache\Proxyund alle anderen automatisch generierten Proxys)
Marius
quelle