Plugins in der eigenen Komponente unterstützen
From Joomla! Documentation
Das Event-System in Joomla! ermöglicht eine flexible Methode für Komponenten, Module und Plug-ins, um mit anderen Plug-ins zu kommunizieren, indem man dem Beobachter-Muster folgt. Dieses Pattern lässt sich am einfachsten als einfacher Kommunikationsmechanismus beschreiben. Die Grundvoraussetzung ist, dass sich null oder mehr „Beobachter“ oder „Hörer“ für ein bestimmtes, bekanntes Event beim System registrieren. Zu einem bestimmten Zeitpunkt im Entwicklungszyklus einer Anwendung löst der "Kommunikator" (in unserem Fall eine Komponente, ein Modul oder ein Plugin) das Event aus und gibt einige Informationen an alle „Beobachter“ weiter. Die „Beobachter“ können dann auf die an sie weitergegebenen Informationen reagieren und optional ein Ergebnis an den „Kommunikator“ zurückgeben.
Hintergrund
Joomla! Observer Implementation
Joomla! implementiert das Observer-Pattern auf globaler Ebene durch die Klassen JPlugin (Observer) und JEventDispatcher (Observable). Jeder, der eine Benachrichtigung über Ereignisse erhalten möchte, erstellt ein Plug-in, das die Klasse JPlugin
erweitert. Unterklassen von JPlugin
registrieren sich automatisch bei der globalen Klasse JEventDispatcher, wenn ihre Plugin-Klasse geladen wurde (mehr dazu später). Die Klasse JEventDispatcher
wird als Dispatching-Mechanismus verwendet, der Ereignisse von den Kommunikatoren empfängt und an die geladenen Hörer weiterleitet. Eine vollständige Beschreibung findet sich in der Plugin Developer Overview.
Warum sollte man Kommunikator werden?
Es kann Zeiten im Entwicklungszyklus einer Komponente geben, in denen es sinnvoll wäre, andere zu informieren, dass eine Aktion stattgefunden hat. Nehmen wir zum Beispiel an, Sie haben eine Compact Disc (CD)-Bibliothekskomponente. Möglicherweise möchten Sie andere benachrichtigen, sobald eine neue CD zur Bibliothek hinzugefügt wurde. In diesem Fall könnten Sie ein bekanntes Event dokumentieren (z.B. onCdAddedToLibrary
) und zum entsprechenden Zeitpunkt das Event „auslösen“, indem Sie Informationen über die neue CD, die der Bibliothek hinzugefügt wurde, weitergeben. Alle Plug-ins, die dieses Event umgesetzt haben, werden mit den Informationen benachrichtigt und können diese nach eigenem Ermessen verarbeiten. Direkte Kommunikation!
Umsetzung
Wie man Kommunikator wird
Da das gesamte Dispatching vom Joomla!-Kern übernommen wird, ist es einfach, ein Kommunikator zu werden. Eigentlich geht es nur darum, einen bestimmten Satz von Plug-ins zu laden und die Trigger-Methode der Klasse JEventDispatcher
aufzurufen.
Eventuell stellen Sie sich die Frage, woher Sie wissen können, welchen Satz von Plugins Sie laden sollen. Das bleibt Ihnen überlassen. Plugins werden auf einer Gruppenebene verwaltet, die in der XML-Deployment-Datei des Plugins definiert ist. Es gibt acht vordefinierte Plugin-Gruppen, und jede Plugin-Gruppe ist für einen anderen Aufgabenbereich vorgesehen. Zum Beispiel gibt es eine Plugin-Gruppe search, die für die Suche zuständig ist, und eine Plugin-Gruppe user, die für benutzerspezifische Funktionen wie das Hinzufügen und Entfernen eines Benutzers im Joomla!-System zuständig ist. Diese Plugin-Gruppen werden nur dann geladen, wenn sie benötigt werden, nämlich vom Kommunikator. Sie können also Ihre eigene Plugin-Gruppe erstellen und sie so nennen, wie Sie wollen. Da Ihre Komponente gut beschrieben ist, werden alle „Hörer“ genau wissen, auf welche Plugin-Gruppe und Ereignisse sie achten sollen.
Events auslösen
Dies führt uns zum eigentlichen Zweck dieses Beitrags: wie man Events auslöst, damit implementierte Plugins auf sie reagieren können. Zuerst müssen Sie Ihre Plugin-Gruppe laden. Dies geschieht über den folgenden Code:
JPluginHelper::importPlugin( 'myplugingroup' );
Dadurch werden alle aktivierten Plugins geladen, die sich selbst als Teil Ihrer Gruppe definiert haben. Als Nächstes müssen Sie eine Instanz der Klasse JEventDispatcher
abrufen:
$dispatcher = JEventDispatcher::getInstance();
Bitte hier zwei Dinge beachten: Als Erstes verwenden wir die Methode getInstance()
und nicht new
, um eine neue Instanz zu erstellen. Das liegt daran, dass wir die globale Singleton-Instanz des JEventDispatcher-Objekts abrufen müssen, die eine Liste aller verfügbaren Plug-ins enthält.
Als nächstes muss unser benutzerdefiniertes Event ausgelöst werden:
$results = $dispatcher->trigger( 'onCdAddedToLibrary', array( &$artist, &$title ) );
Wir haben hier das Ereignis onCdAddedToLibrary
ausgelöst und Künstler-Namen und den Namen des Titels übergeben. Welche und wie viele Parameter Sie übergeben, bleibt Ihnen überlassen. Die Übergabe von Parametern per Referenz (unter Verwendung eines &
) ermöglicht es den Plugins, die übergebenen Variablen zu ändern. Alle Plugins erhalten diese Parameter, verarbeiten sie und geben optional Informationen zurück. Der aufrufende Code kann über das Array $results
auf die zurückgegebenen Werte zugreifen (jedes Element entspricht dem zugehörigen Ergebnis eines Plugins).
Einschränkungen
Eine API wird definiert
Indem Sie Events für Plugins anbieten, auf die geantwortet werden kann, erstellen Sie effektiv eine API. Richtige Planung ist extrem wichtig – sobald Sie Ihren Code veröffentlichen, werden andere Entwickler anfangen, sich auf die Namen und Parameter Ihrer Events zu verlassen. Wenn diese später geändert werden, zerstört dies die Kompatibilität mit allen Plugins, welche diese verwenden.
Die richtige Plugin-Gruppe laden
Bei der Trigger-Methode ist zu beachten, dass nicht definiert ist, welche Gruppe von Plugins benachrichtigt werden soll. Eigentlich werden alle geladenen Plugins benachrichtigt, unabhängig davon, in welcher Gruppe sie sich befinden. Es ist wichtig, dass Sie einen Event-Namen verwenden, der nicht mit dem Event-Namen einer anderen Plugin-Gruppe kollidiert. In den meisten Fällen ist dies kein Problem, da Ihre Komponente diejenige ist, die die Plugin-Gruppe lädt und Sie daher wissen, welche Plugins bereits geladen sind. Beachten Sie jedoch, dass die Plugin-Gruppe system sehr nahe am Anfang der Abfrage geladen wird. Achten Sie darauf, dass Sie keine Konflikte bei der Vergabe von Event-Namen mit den System-Events verursachen.