Objekte und ObjektTemplates

In Konquadrat gibt es sogenannte Objekte (nach OOP eigentlich Klassen), die mit Hilfe von XML konfiguriert werden können. In dem XML definiert man, wie der Objekt-Typ heißt, welche Felder es gibt und noch einige Information für das Backend.

Ein Konquadrat-Objekt ist immer eine finale Klasse, kann also nicht mehr erweitert werden! Deswegen gibt es zusätzlich noch ObjektTemplates (nach OOP eigentlich Abstrakte Klassen). ObjektTemplates sind fast wie Objekte konfiguriert (Unterschiede sind in der XML-Dokumentation zu finden).

Die Konfiguration der Objekte und ObjektTemplates kann an zwei unterschiedlichen Stellen möglich sein. Entweder liegen die Konfigurationen in der Datenbank als Konquadrat-Objekte oder sie liegen als XML-Dateien im Dateisystem. Es kann nur eine von beiden Varianten gleichzeitig aktiv sein! Falls in der konquadrat.ini der Eintrag "configDirectory" gesetzt ist, wird versucht die Konfigurationen aus diesem Ordner zu laden. Falls der Eintrag nicht gesetzt ist, wird die Konfiguration aus der Datenbank gezogen.

Falls die Konfigurationen aus der Datenbank geladen werden, ist es möglich diese über das Backend zu verändern. Dafür muss man im Backend die interne Adresse "#grid/Config" aufrufen. Die Config-Objekte werden beim Speichern automatisch validiert (einige Validierungen sind jedoch erst beim ConfigReload möglich).

Für die Objektkonfiguration ist eine XSD-Datei hinterlegt. Diese ist im Konquadrat-Ordner unter "src/Config/object.xsd" zu finden. Die XML-Dokumentation ist hier zu finden.

Die Objektkonfiguration von Konquadrat wird nicht live aktualisiert, sondern muss manuell aktualisiert werden!

Das Aktualisieren der aktuellen Objektkonfiguration kann im Backend über die interne Adresse "#admin/reloadConfig" durchgeführt werden. Um diese Aktion auszuführen muss der Benutzer Admin-Rechte besitzen!

Sobald das Neuladen der Konfiguration gestartet wurde, wird Konquadrat für alle Zugriffe gesperrt und alle im Backend eingeloggten Benutzer müssen sich neu einloggen (falls etwas an der Konfiguration verändert wurde). Deswegen sollte es mit allen eingeloggten Benutzern abgesprochen werden, wenn ein ConfigReload gemacht wird, da ansonsten Eingaben verloren gehen könnten.

Beim ConfigReload wird die Datenbankstruktur aktualisiert und anschließend werden die realen PHP-Klassen/-Interfaces/-Traits generiert und in das Dateisystem geschrieben.

Jedes Objekt und ObjektTemplate muss einen eindeutigen Namen besitzen! Der Name darf nur aus Buchstaben bestehen und sollte in CamelCase geschrieben sein. Objekte und ObjektTemplates können in Unter-Namespaces unterteilt werden. Hierfür muss im Namen ein '\' verwendet werden.

Konquadrat-Objekte können nicht restlos gelöscht werden! Alle Objekte werden lediglich als gelöscht markiert! Dadurch ist es möglich selbst gelöschte Objekte wiederherzustellen.

Technische Details zur Datenbank

Alle Objekte verwenden als Haupttabelle "kon2_object". Die Tabellenstruktur sieht wie folgt aus:

  • id - int(10) unsigned, NOT NULL, PRIMARY KEY, AUTO_INCREMENT
  • uuid - varchar(36) UNIQUE
  • parentId - int(10) unsigned
  • path - text
  • type - enum(alle Objekt-Typen) NOT NULL
  • deleted - tinyint(1) NOT NULL, default '0'
  • creationDateTime - datetime
  • changeDateTime - datetime

Auf parentId und type ist jeweils ein Index. 

Für jeden ObjektTemplate-Typ und Objekt-Typ wird jeweils eine eigene Tabelle erstellt, sofern der Typ mindestens ein Feld hat (magic und dynamicMagic zählen hierbei nicht)! Jede Tabelle hat zusätzlich zu den konfigurierten Feldern noch eine id-Spalte auf der der Primärschlüssel der Tabelle liegt. Der Tabellenname wird generiert in dem der Objekt-Typ-Name von CamelCase in SnakeCase umgewandelt wird und vorhandene '\'  durch zwei '_'  ersetzt werden. Also aus dem Typ "MeinProjekt\SuperTollerTeilnehmer" wird der Tabellenname "kon2_object_mein_projekt__super_toller_teilnehmer".

Technische Details zur Klassenstruktur

Konquadrat erstellt beim ConfigReload in dem "kon2/objects/generated"-Ordner die echten PHP Klassen / Interfaces / Traits. Alle generierten Klassen / Interfaces / Traits verwenden den Namespace "\com\setasign\Konquadrat\Object\Custom" (+ eventuelle Unter-Namespaces). Alle generierten Klassen sind als Final deklariert!

Da in PHP unter normalen Umständen keine Möglichkeit für eine Mehrfachvererbung besteht (ausser bei Interfaces) muss Konquadrat ein wenig tricksen um diese zu ermöglichen.

Wenn ein ObjektTemplate generiert wird, werden zwei Dateien generiert. 

Zum einen wird ein Interface erstellt mit dem selben Namen wie das ObjektTemplate. Zusätzlich wird noch ein Trait erstellt dass den Namen von dem ObjektTemplate + 'Trait' als Namen hat. In dem Trait wird, das eigenen Trait (siehe Traits) verwendet, falls eines vorhanden ist, ansonsten bleibt das Trait einfach leer.

Falls man einen TypeHint auf ein ObjektTemplate macht, sollte man das Interface verwenden und nicht das eigene oder generierte Trait!

Wenn das ObjektTemplate ein oder mehrere andere ObjektTemplates erweitert, werden die entsprechenden Interfaces mit "extends" erweitert und die benötigten Traits in dem eigenen Trait mit "use" verwendet.

Wenn ein Objekt generiert wird, wird eine finale Klasse generiert. Diese Klasse erweitert AbstractObject und implementiert alle Interfaces von den verwendeten ObjektTemplates. Zusätzlich werden die Traits von den verwendeten ObjektTemplates verwendet und falls vorhanden das eigene Trait (siehe Traits).

Daraus resultiert das zwar auf eine gewisse Art und Weise eine Mehrfachvererbung möglich ist in Konquadrat, jedoch werden dabei keine Methoden und Properties vererbt, da diese erst in der finalen Klasse importiert werden mit "use". Mehr zur Vererbung von Methoden ist unter Überschreiben von Methoden zu finden. 

Beispiel

Es gibt das ObjektTemplate "HasEmailTpl" mit dem Feld "Email" und einem eigenen Trait mit der Methode sendEmail(). Zusätzlich gibt es ein ObjektTemplate "PersonTpl" ohne Felder oder Methoden und das ObjektTemplate implementiert "HasEmailTpl". Desweiteren gibt es ein Objekt "Teilnehmer", welches das ObjektTemplate "PersonTpl" implementiert. 

alt 

Hieraus werden nun 5 Dateien generiert. Das Interface "HasEmailTpl", das Trait "HasEmailTplTrait" (mit "use Traits\HasEmailTpl"), das Interface "PersonTpl" (mit "extends HasEmailTpl"), das Trait "PersonTplTrait" (mit "use HasEmailTplTrait") und die finale Klasse "Teilnehmer" (mit "extends AbstractObject", "implements PersonTpl" und "use PersonTplTrait").  

alt