Stud.IP-Plugins
- Alle Plugins ((:pitscount:))
- Admin-Plugins
- Core-Plugins
- Homepage-Plugins
- Portal-Plugins
- Standard-Plugins
- System-Plugins
- Auth-Plugins
- Plugins für Version:
1.4 | 1.5 | 1.6 | 1.7 | 1.8 | 1.9 | 1.10 | 1.11 | 2.0
< Bestandteile von Plugins | Plugin-Spezifikation 2.0 | Plugin-Versionsschema >
Auf dieser Seite... (ausblenden)
Um das Problem zu lösen, Stud.IP an bereits vorhandenen Stellen, also in seiner Kernfunktionalität, zu erweitern, kommt die im folgenden beschriebene Komponentenarchitektur zum Einsatz.
Diese Architektur kann sinnbildlich so erklärt werden, dass Stud.IP aus einer Menge an Komponenten besteht.
Eine Komponente ist ein funktionales Subsystem, dass einen Service im Kontext von Stud.IP anbietet. Beispiele: ein Fotoalbum für Benutzer, ein Newsfeed-Aggregator, ein Prüfungssystem usw. Der Stud.IP-Kern soll in diesem Zusammenhang der Einfachheit halber als eine einzelne Komponente gelten.
Jeder dieser Komponenten hat die Möglichkeit, "Steckdosen" (Extension Points) anzubieten, in die sich wiederum andere Komponenten "einstöpseln" können. Das erlaubt es einer Komponente, die Funktionalität einer anderen zu erweitern, ohne dass die erweiterte Komponente überhaupt wissen muss, dass es diese sie erweiternde Komponente überhaupt gibt. Erforderlich ist nur, dass die eine Komponente ihre "Steckdosen" (Extension Points) zur Verfügung stellt und nutzt und andere Komponenten sich in diese "Steckdosen" (Extension Points) einstöpseln können.
Grundsätzlich bietet zuallererst nur das Kernsystem solche Extension Points an. Jedes weitere installierte Plugin erhält aber die Möglichkeit, eigene Extension Points hinzuzufügen.
Extension Points werden in PHP durch Interfaces abgebildet. Damit wird eine Schnittstelle sichergestellt, über die beide Seiten kommunizieren können. Ein solches Komponenteninterface sieht beispielweise so aus:
Ein Komponenteninterface definiert eine Menge von Operationen, die eine Komponente ausführen können muss. (Beispiel: Einen Text für eine Box innerhalb der Stud.IP-Homepage liefern.)
Idealerweise werden Komponenteninterfaces eine feine Granularität aufweisen. Ein Gegenbeispiel ist das implizite Interface der alten Homepage-Plugins.
Komponenteninterfaces müssen ihrerseits das Markerinterface "Studip_Component" implementieren, damit der Komponentenmanager in die Lage versetzt wird, automatisch zwischen normalen Interfaces und Komponenteninterfaces unterscheiden zu können. Es ist ja immer möglich, dass eine Komponente auch Interfaces implementiert, die nichts mit der Komponentenarchitektur zu tun haben.
Komponenteninterfaces repräsentieren die "Steckdose", in die sich eine Komponente "einstöpseln" kann. Das "Einstöpseln" geschieht durch das Schreiben einer Klasse, die dieses Interfaces implementiert ("class ExampleComponent implements Studip_PortalComponent"). Ausserdem muss diese Klasse – die Komponente – beim weiter unten beschriebenen Komponentenmanager registriert werden.
Der Komponentenmanager ist für zwei Aufgaben zuständig. Zum einen können bei ihm Komponenten angemeldet und abgemeldet werden, zum anderen kann man über ihn alle Komponenten erhalten, die ein bestimmtes Komponenteninterface ("Steckdose") implementieren, um dann an diesen die im Komponenteninterface deklarieren Methoden aufzurufen. Da man nur Komponenten erhält, die dieses Komponenteninterface implementieren, kann man sicher sein, dass diese Methoden auch tatsächlich zur Verfügung stehen, da der Compiler dieses zusichert.
Der Komponentenmanager definiert u.a. folgende Methoden:
Die Klassenmethode #instance
liefert die Singleton-Instanz des Komponentenmanagers:
An dieser Instanz kann dann eine Komponente mittels ihres Namens registriert werden:
Achtung: Es muss sichergestellt werden, dass der Quellcode der benannten Komponente bereits geladen ist. Da der Komponentenmanager die Komponente nicht untersuchen kann.
Auf ähnliche Weise kann eine Komponente auch wieder beim Komponentenmanager abgemeldet werden:
Auch hier gilt, dass der Quellcode der Komponente geladen sein muss.
Um alle Komponenten zu erhalten, die ein bestimmtes Komponenteninterface implementieren, sendet man #components
an den Komponentenmanager:
Gelegentlich will man an allen Komponenten eines Komponenteninterfaces nur eine Methode aufrufen, ohne dass man deren Rückgabewert benötigen würde – wenn man den Komponenten also nur etwas "mitteilen" will. Für diesen Fall kann man #signal
senden:
Jedes Plugin-Paket muss genau eine Plugin-Klasse enthalten (siehe Bestandteile). Diese Plugin-Klasse...
< Bestandteile von Plugins | Plugin-Spezifikation 2.0 | Plugin-Versionsschema >