Magento2 Plugins

von Roman Hutterer, 28. Dezember 2015
Magento2 Plugin
Magento2 wurde am 17.November 2015 veröffentlicht, und aus technischer Sicht gibt es einige neue Features mit an Bord. Diese haben wir in unserem Beitrag Magento2 Features schon erwähnt.

Ein neues Feature in Magento2 sind Plugins!

Wieso Magento2 Plugins? Die gab es doch auch in Magento 1?

Naja nicht ganz. In Magento 1 wurde eine Erweiterungen an sich auch gerne Plugin genannt, da es ein gebräuchlicher Ausdruck in der Welt der Software ist, wenn ein Programm das Hauptprogramm erweitert.

Wikipedia erklärt ein Plugin folgendermaßen:

Ein Plug-in [ˈplʌgɪn] (häufig auch Plugin; von engl. to plug in, „einstöpseln, anschließen“, deutsch etwa „Erweiterungsmodul“) ist ein optionales Modul, das von einer Anwendung während ihrer Laufzeit entdeckt und eingebunden werden kann, um deren Funktionalität zu erweitern. Der Begriff wird teilweise auch als Synonym zu Add-on benutzt. ¹

In Magento2 ist ein Plugin eine gewisse Art eine Funktionalität zu erweitern und keine Erweiterung. In einer Magento2 Erweiterung selbst können mehrere Plugins vorhanden sein.

 

Magento selbst beschreibt Plugins so:

Magento enables you to change, or extend, the behavior of any original, public method in any Magento class. You can change the behavior of an original method by creating an extension. These extensions use the Plugin class and are therefore referred to as plug-ins.²

Und warum gibt es in Magento2 diese neue Form der Erweiterung?

Um diese Frage zu beantworten möchte ich vorher noch kurz ein Problem aus Magento1 schildern:

Um eine Funktion in Magento 1 zu erweitern musste man entweder die Klasse ableiten oder hoffen dass es ein passendes Event gab auf das man hören konnte. Man musste also des öfteren eine Magento Klasse überschreiben und bei großen Projekten (Anmerkung: groß bedeutet in diesem Fall eine große Anzahl an Erweiterungen) kam es des öfteren zu “Überschreibungskonflikten”. Ein Überschreibungskonflikt trat dann auf wenn mehrere Module die selben Klassen überschreiben möchten. In Magento 1 entschied bisher die Reihenfolge (eine interne Reihenfolge + alphabetischer Modulname) der Module darüber welches Klasse zum Einsatz kam.

 

In Magento 2 hat man dieses Problem mit Hilfe von Plugins gelöst.

Was macht also jetzt dieses Plugin?

Kurz gesagt es löst eigentlich genau das oben beschriebene Problem. Ein Plugin ermöglicht es die Funktionalität in einer Klasse abzuändern ohne dass man diese Klasse ableiten, uns somit überschreiben, muss. Bei Plugins wird mit Hilfe der Codegenerierung (ebenfalls mit Magento 2 neu eingeführte) eine neue Klasse automatisch erzeugt und Magento 2 kümmert sich um eventuelle Überschneidungen mit anderen Erweiterungen.

Dabei kann man entscheiden ob die Methode des Plugins (also die Funktion)  davor, danach oder “davor und danach” einer bestimmten Methode ausgeführt wird.

Genug der Einleitung, jetzt zu etwas verständlichem… Code!

Ich werde hier am Beispiel unseres Plugins “Magento 2 UID Validierung für EU” zeigen wie es in Magento2 sehr einfach möglich ist eine bestehende Funktion zu erweitern. Eines noch, das ist keine Anleitung wie man eine Erweiterung für Magento2 erstellt, der Fokus liegt auf der Beschreibung des Plugins und wie es funktioniert.

 

Zuerst muss die Erweiterung in Magento2 registriert werden.

Dies geschieht mit der Datei ‘module.xml’ und ‘registration.php’

 

Damit ist die Erweiterung auch schon registriert.

Der ObjectManager in Magento2 erlaubt die Konfiguration von Plugins über die Datei ‚di.xml‘. Also muss die Datei di.xml angelegt werden.

 

Die Struktur kurz erklärt:

  • ‚type‘: Eine Klasse, Interface oder virtuelle Klasse für die das Plugin gilt.
  • ‚plugin name‘: Ein eindeutiger Name welcher das Plugin identifiziert. Dieser wird auch beim zusammenführen der gesamten Konfiguration verwendet.
  • ‚plugin type‘: Der Name der Klasse oder des virtuellen Typs. Folgendes Schema wird vorgeschlagen :\Vendor\Module\Plugin\<ModelName>Plugin.
  • ‚plugin sortOrder‘: Die Sortierung wenn mehrere Plugins auf die selbe Methode reagieren.
  • ‚plugin disabled‘: Damit kann das Plugin deaktiviert werden.

Als letzte Datei wird jetzt noch das Plugin selbst angelegt.

Jetzt stellt man sich die Frage: Woher weiß Magento2 bei welcher Methode der originalen Klasse die Methode aus dem Plugin ausgeführt werden soll?

Dafür ist der ObjectManager zuständig. Er parst die Methoden und überprüft anhand des Schemas wie das Plugin eingehängt werden soll. Vereinfacht lässt sich das Schema folgendermaßen beschreiben:

  • Suche alle Methodennamen der Klasse die wir in der ‚di.xml‘ definiert haben (Magento\Customer\Model\Vat)
  • Gibt es Methoden in unserer Klasse die auf die Methodennamen in der di-Klasse passen?
    • ‚before’+{originalMethodenName}
    • ‚after’+{originalMethodenName}
    • ‚around’+{originalMethodenName}
  • Wenn ja, platziere unsere Funktion an der entsprechenden Stelle in der neu generierten Klasse

 

In unserem Beispiel wird demzufolge also die Funktion ‚beforeCheckVatNumber‘ verwendet.

Wie man hier erkennt ist der erste Parameter unserer Methode ein Code Model vom Typ Magento\Customer\Model\Vat. Dies ist die Instanz der Klasse. Wir könnten also sogar mit der Instantiierten Klasse arbeiten.

Der Return Wert der Methode unseres Magento2 Plugins übergibt in dem Fall ein Array mit 4 Elementen, diese 4 Elemente werden an die originale Methode aus dem Core übergeben. In diesem Beispiel eben eine UID ohne die ersten beiden Buchstaben zb. AT. Eine nähere Erklärung was genau die Erweiterung macht kann in unserem Beitrag zum Thema Magento2 UID Validierung nachgelesen werden.

An diesem Beispiel ist ganz einfach zu Erkennen, dass das Problem mit Überschreibungskonflikten in Magento2 nun endlich ohne großen Programmieraufwand gelöst wurde. Magento kam somit dem Ruf der Community, nach einer einfacheren Integration von Erweiterungen für Verkäufer (Shopbetreiber), nach.

¹ https://de.wikipedia.org/wiki/Plug-in, Abgerufen am 28.12.2015

² http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html, Abgerufen am 28.12.2015