PDF-Version
Transcrição
PDF-Version
Bachelorthesis Konzeption und Entwicklung einer TYPO3-Erweiterung zur datenbankgestützten Formularerzeugung und -konfiguration von Christian Opitz Erstbetreuer: Zweitbetreuer: Dr. rer. nat. Thomas Meinike Dipl. Ing. Uwe Weihmann Arbeitsplatz: Netzelf – Agentur für guten Eindruck GbR Zeitraum: 15.06.2009 - 15.09.2009 II Inhaltsverzeichnis Abbildungsverzeichnis............................................................................................................................ IV Abkürzungsverzeichnis ........................................................................................................................... IV 1 2 Einleitung ......................................................................................................................................... 1 1.1 Fallstudie .................................................................................................................................. 1 1.2 Aufgabenstellung ..................................................................................................................... 1 Grundlagen....................................................................................................................................... 2 2.1 2.1.1 Allgemeines ...................................................................................................................... 2 2.1.2 Installation........................................................................................................................ 4 2.1.3 Das Backend ..................................................................................................................... 6 2.1.4 TypoScript ........................................................................................................................ 7 2.2 3 4 TYPO3-Framework ................................................................................................................... 9 2.2.1 Aufbau .............................................................................................................................. 9 2.2.2 Verzeichnisstruktur ........................................................................................................10 2.2.3 Datenbank ......................................................................................................................13 2.2.4 TYPO3-Erweiterungen ....................................................................................................17 Analyse vorhandener Formularerweiterungen..............................................................................20 3.1.1 Formhandler...................................................................................................................20 3.1.2 Powermail ......................................................................................................................22 3.1.3 Chronoforms (Joomla!) ..................................................................................................23 3.1.4 Erkenntnisse aus der Analyse.........................................................................................24 Durchführung .................................................................................................................................26 4.1 Entwurf ...................................................................................................................................26 4.1.1 Ansatz und Anforderungen ............................................................................................26 4.1.2 Prototypen .....................................................................................................................27 4.1.3 Funktionsweise...............................................................................................................29 4.2 5 TYPO3 ....................................................................................................................................... 2 Entwicklung ............................................................................................................................31 4.2.1 Arbeitsweise ...................................................................................................................31 4.2.2 Kickstart..........................................................................................................................32 4.2.3 TCA-Konfiguration ..........................................................................................................36 4.2.4 Schnittstellen zu Formhandler .......................................................................................38 4.2.5 ExtBase und FLUID – Die Brücke zu FLOW3 ...................................................................39 Auswertung ....................................................................................................................................43 III 5.1 Zusammenfassung .................................................................................................................43 5.2 Ausblick ..................................................................................................................................44 6 Literaturverzeichnis........................................................................................................................45 7 Anhang ...........................................................................................................................................47 7.1 Selbständigkeitserklärung ......................................................................................................47 7.2 Quellcodes..............................................................................................................................48 7.2.1 tca.php ...........................................................................................................................48 IV Abbildungsverzeichnis Abb. 1: TYPO3-Ordnerstruktur unter Unix ............................................................................................... 4 Abb. 2: TYPO3-Ordnerstruktur unter Windows ....................................................................................... 4 Abb. 3: TYPO3-Installationsassistent Schritt 1 ......................................................................................... 5 Abb. 4: TYPO3-Installationsassistent Schritt 2 ......................................................................................... 5 Abb. 5: Fehler im Frontend: Kein Template ............................................................................................. 5 Abb. 6: TYPO3-Installationsassistent Schritt 3 ......................................................................................... 5 Abb. 7: Fehler im Frontend: Keine Konfiguration .................................................................................... 5 Abb. 8: Die Backend-Benutzeroberfläche eines Administrators im Überblick ........................................ 6 Abb. 9: TYPO3-Funktionsschema (Quelle: TYPO3 Core Development Team 2008 – Inside TYPO3, S.3) ........................................................................................................................................................... 9 Abb. 10: Die wichtigsten Verzeichnisse und Dateien.............................................................................10 Abb. 11: Ein Teil der Ausgabe des TCA im Backend ...............................................................................14 Abb. 12: Formhandler-Funktionsschema (Quelle: Führicht 2009 – EXT: Universal Formhandler, S.5) .21 Abb. 13 Powermail mit IRRE (Quelle: Kellner, Heißmann 2009 – powermail, S.18)..............................23 Abb. 14: Prototyp der allgemeinen Einstellungen für Formulare ..........................................................28 Abb. 15: Prototyp der Feldeinstellungen für Formulare ........................................................................28 Abb. 16: Prototyp der Datenbankeinstellungen für Formulare .............................................................29 Abb. 17: Anzeige von Methoden und Eigenschaften in Eclipse PDT......................................................32 Abb. 18: Kickstarter – allgemeine Informationen ..................................................................................33 Abb. 19: Kickstarter – Moduleigenschaften...........................................................................................33 Abb. 20: Kickstarter – Feldeigenschaften ..............................................................................................34 Abkürzungsverzeichnis CMS SQL PHP XML HTML RSS RPC SOAP IT API TCA conf tx ID uid/pid DB MVC SVN Content Management System (Inhaltsverwaltungssystem) Structured Query Language PHP: Hypertext Preprocessor (Backronym aus Personal Home Page Tools) Extensible Markup Language Hypertext Markup Language Really Simple Syndication Remote Procedure Call Simple Object Access Protocol Informationstechnik Application Programming Interface Table Configuration Array Configuration / Konfiguration TYPO3 Extension Identifier unique/parent identifier Datenbank Model View Controller Subversion 1 1 Einleitung 1.1 Fallstudie Als Grundlage eines inhaltsorientierten Community-Portals für Studenten, Firmen und Lehrkräfte wurde bei der Bedarfsanalyse das CMS TYPO3 ausgewählt. Eine Besonderheit des Portals stellt die Vielzahl an Benutzergruppen mit unterschiedlichen Rechten bzw. Pflichten dar. Die größte Anforderung, die diese hierarchische Gruppenstruktur an das Portal stellt, ist, dass alle Daten, die von den Nutzern erfasst werden müssen, an zentraler Stelle verwaltet werden sollen. In aller Regel werden diese Daten über Formulare erfasst, die je nach Gruppenzugehörigkeit unterschiedliche Felder und Validierungsoptionen besitzen können. So z.B. muss der Benutzer schon bei der Registrierung angeben, zu welcher Gruppe er gehört. Daraufhin werden von ihm je nachdem, welcher Gruppe er sich zugeordnet hat, unterschiedliche Informationen verlangt. (Ist der Nutzer bspw. Vertreter einer Firma, muss er statt des Fachbereichs und des Studienganges Firmenname und Tätigkeitsfeld angeben) Diese Abhängigkeit von der Gruppenzugehörigkeit spiegelt sich in vielen Formularen innerhalb des Portals wieder (z.B. Benutzerprofil, Suche oder Dateiupload). Da die erfassten Daten in direktem Zusammenhang mit den Formularen stehen, sollte die Datenstruktur über die Formularverwaltung abgebildet werden können. Eine weitere wichtige Anforderung, die sich daraus ergibt, ist, dass die Daten dieser Formulare in Relation zu unterschiedlichen Datenbanktabellen stehen können (Nutzer, Gruppen u.a.) und in Abhängigkeit verschiedener Verknüpfungen stehen können. Da es nur sehr umständlich möglich ist, solche Bedingungen über graphische Bedienoberflächen einstellen zu können, muss die Formularverwaltung flexibel um verschiedene Klassen für Validierungsverfahren, Feldtypen und Datenbankverwaltung erweiterbar sein. TYPO3 bietet für diese Forderungen, wenn auch nicht die fertige Lösung, so doch sehr gute Grundlagen. 1.2 Aufgabenstellung Die Aufgabenstellung für diese Arbeit ergibt sich aus den eingangs erläuterten Forderungen an die Formularverwaltung. TYPO3 soll um die benötigten Funktionalitäten in Form einer Extension erweitert werden, welche folgende Funktionalitäten abdecken können muss: • • • • • • Zentrale Verwaltung von Formularen und Formularfeldern Benutzergruppenabhängige Konfiguration der Formulare und Felder Verknüpfung von Formulardaten mit mehreren Datenbank-Tabellen (Ausgabe und Veränderung vorhandener und Speicherung neuer Werte) Formulare müssen sich aus mehreren Schritten bzw. Teilformularen (MultiStepFormulare) zusammensetzen können. Für Formularfelder müssen unterschiedliche Validierungsarten wie nicht leer, Text, Zahl, Dateigröße etc. eingestellt werden können. Die Erweiterung muss um neue Klassen für neue Feld-Typen, Validierungsarten oder Datenbankspeicherung erweitert werden können. Dabei kann auf vorhandene Formularerweiterungen für TYPO3 zurückgegriffen werden. 2 2 Grundlagen 2.1 TYPO3 2.1.1 Allgemeines TYPO3 ist ein Enterprise Content Management System (ECM), das 1997 von dem Dänen Kasper Skårhøj entwickelt und unter der GNU General Public License v.2 veröffentlicht wurde. Seit der Veröffentlichung im Juli 2000 wurde das Projekt durch Skårhøj allein und seit der Einführung des Extension Managers 2002 durch eine Vielzahl von Entwicklern unter der Leitung Skårhøj’s weltweit fortlaufend weiterentwickelt. Unterstützt durch die umfangreiche Arbeit der 2004 gegründeten TYPO3-Association, der ca. 100.000 Mitglieder in über 80 Ländern und Spenden von Unternehmen und Privatpersonen konnte sich TYPO3 mit über 300.000 Installationen zu einem der verbreitetsten Enterprise-Content-Management-Systeme entwickeln. 1 Content Management Systeme sind Systeme zum Erstellen, Bearbeiten, Verwalten und Veröffentlichen von Inhalten wie Texten, Grafiken und Dokumenten. Die Einsatzbereiche (Web Publishing, Blogs, Redaktionssysteme u.a.) sind ebenso vielfältig wie die Plattformen auf denen sie betrieben werden und die Programmiersprachen, in denen sie umgesetzt werden können (PHP, Java, Perl, Python u.a.). TYPO3 gehört zu der Gruppe der Enterprise Content Management Systeme und dient besonders dem Einsatz in Intranets oder als Portalsystem, wird allerdings häufig lediglich als Web Content Management System (WCMS) oder Redaktionssystem eingesetzt. Es wurde in der Programmiersprache PHP geschrieben und kann so in allen Umgebungen eingesetzt werden, auf denen PHP installiert ist (meist serverseitig). TYPO3 ist durchgängig objektorientiert programmiert und bestrebt, Darstellung, Inhalt und Datenquellen strikt voneinander zu trennen. Der Begriff Enterprise Content Management ergibt sich weniger aus dem Einsatzgebiet der Anwendung als aus den Anforderungen, die sich daraus ergeben: „Kennzeichnend für Enterprise Content Management Systeme ist die IT-Welt als Abbild bestehender Unternehmensprozesse, in denen es stattfindet. Zwischen Enterprise Resource Planning (ERP) und Customer Relationship Management (CRM), Dokumenten-Management-Systemen (DMS) und Office-Applikationen muss ein CMS eine vereinende und vermittelnde Rolle einnehmen, um verschiedene Datenformate und Drittsysteme bei der Produktion und Präsentation von Inhalten nutzen zu können.“ 2 TYPO3 wird den Anforderungskriterien, die sich nach Altmann für ein Enterprise CMS ergeben, durchgängig gerecht: • 1 Flexibilität und Integrationsfähigkeit: TYPO3 kann auf jedem Server, auf dem PHP installiert ist, betrieben werden. Mit der Datenbank-Abstraktionsschicht3 unterstützt es die Anbindung an unterschiedliche Datenbanken wie MySQL, PostgreSQL oder Oracle. Zusätzliche Schnittstellen zu Office- und XML-Formaten sowie Webservices sind ebenfalls integriert bzw. frei konfigurierbar. TYPO3 ist nicht auf ein bestimmtes Ausgabeformat begrenzt sondern unterstützt vielfältige Formate wie z.B. HTML, RSS, XML-RPC, SOAP, DocBook XML etc. Vgl. Altmann, F. et al. 2004 – TYPO3, S.51-52; TYPO3 CMS: Facts and Figures 2009 Altmann, F. et al. 2004 – TYPO3, S.44 3 Database Abstraction Layer, URL: http://typo3.org/extensions/repository/view/dbal/current/ 2 3 • • • Modularer Aufbau: Seit der Einführung des Extension Managers ist TYPO3 ein modulares System aus globalen (System-) und lokalen (Nutzer-) Erweiterungen. Das modulare Konzept und die TYPO3-API erlauben umfangreiche Erweiterungsmöglichkeiten auf allen Schichten des Systems. Enterprise-Funktionen: Durch den oben genannten modularen Aufbau und das API ist TYPO3 im Vergleich zu anderen CMS sehr gut um zusätzliche Funktionalitäten erweiterbar, die sich nahtlos in das Look&Feel des TYPO3-Backend einfügen. So sind im Laufe der Zeit viele gute Erweiterungen entstanden, mit deren Hilfe sich TYPO3 für die jeweiligen Anforderungen skalieren lässt. Diese sind bspw. DAM4, Indexed Search5, cal6, commerce7 und viele mehr. TYPO3 selbst stellt die Basis für die Erweiterungen dar und bietet umfangreiche Funktionalitäten für den Einsatz im Enterprise-Bereich: Versionierung von Records, Kollaborationsfunktionen, Frontend- und Backend-Nutzergruppen, Rechteverwaltung, Zugriff über CLI 8 für zeitgesteuerte und automatisierte Wartungsoperationen, Mehrsprachigkeit, Multidomain-Fähigkeit und viele mehr. Eine komplette Liste der TYPO3-Funktionen würde den Rahmen dieser Arbeit sprengen, ist jedoch online verfügbar. 9 Peformance: TYPO3 ist bedingt durch seine Komplexität sehr ressourcenintensiv, was allerdings durch das integrierte leistungsfähige Caching-System ausgeglichen wird. Für Administratoren ist es jedoch stets empfehlenswert, zu überprüfen, ob die installierten Erweiterung sinnvoll mit diesem Caching-System umgehen, denn oft deaktivieren solche das Caching-System für die Seite auf der sie eingesetzt werden oder schlimmstenfalls für das ganze System. Dies kann zu gravierenden Geschwindigkeitseinbußen beim RenderingProzess führen. Daher sind auch Extension-Entwickler angehalten, ihre Erweiterung so zu entwickeln, dass der Caching-Prozess so wenig wie möglich außer Kraft gesetzt wird.10 Die Veröffentlichung unter der GPL11 hat zur Folge, dass alle Erweiterungen, die auf TYPO3 aufsetzen, automatisch derselben Lizenz unterliegen (Wobei sie allerdings nicht zwangsläufig veröffentlicht werden müssen). Dies führte dazu, dass eine Vielzahl an Erweiterungen im TYPO3 Extension Repository (TER) online meist umfangreich dokumentiert zur Verfügung stehen. Durch diese strikte Umsetzung des Open-Source-Gedankens und die sehr gute Abwärts- und Aufwärtskompatibilität, die das TYPO3 Core seinen Erweiterungen bietet, kann TYPO3 sehr schnell und meist ohne zusätzliche Programmierarbeit an die Anforderungen des jeweiligen Einsatzgebietes angepasst werden. 4 Digital Asset Management (Verwaltung von Rechten und Metadaten für digitale Medien), URL: http://typo3.org/extensions/repository/view/dam/ 5 Erweiterung für die Indexierung von Inhalten und Dokumenten, URL: http://typo3.org/extensions/repository/view/doc_indexed_search/ 6 Erweiterung zur Arbeit mit Kalendern (u.a. zur Synchronisation im iCal-Format), URL: http://typo3.org/extensions/repository/view/cal/ 7 Erweiterung, die Shop-Funktionalitäten bereitstellt, URL: http://typo3.org/extensions/repository/view/commerce/ 8 Abk. engl.: Command Line Interface 9 URL: http://www.aoemedia.de/typo3-cms/komplette-feature-liste.html 10 Vgl. Turk 2008 – Caching in TYPO3-Extensions 11 Abk. engl.: General Public License. Vgl. Free Software Foundation 1991 – GNU General Public License v2.0 4 2.1.2 Installation TYPO3 steht in mehreren Paketen zur Verfügung. Für die Installation auf einem bereits bestehenden Server stehen zwei Pakte auf der TYPO3-Downloadseite bereit: Das Source- und das Dummy-Paket. Das Source-Paket enthält die Verzeichnisse t3lib, typo3 und misc mit den Quelldateien des TYPO3-Kerns. Das Dummy-Paket enthält die Verzeichnisse fileadmin, typo3conf, typo3temp und uploads und stellt ein leeres Gerüst für eine lauffähige TYPO3-Installation dar. Dieses enthält später die Konfiguration, Erweiterungen, Templates und Nutzerdateien. Der Vorteil der Trennung des TYPO3-Kerns von diesen Inhalten kommt besonders unter Unix-Systemen zum Tragen, da die Dateien des Kerns im Quellordner belassen und mit Symlinks verlinkt werden können: Abb. 1: TYPO3-Ordnerstruktur unter Unix Abb. 2: TYPO3-Ordnerstruktur unter Windows Die Symlinks erlauben ein einfaches Umschalten der TYPO3-Version. In Abb. 1 sind t3lib, typo3 und index.php Symlinks auf typo3_src/t3lib, typo3_src/typo3 bzw. typo3_src/index.php . Der Ordner typo3_src wiederum ist ein Symlink auf typo3_src-4.2.8. Um die Version 4.2.6 zu verwenden, muss lediglich das Ziel des Symlinks typo3_src geändert werden. Auf diese Art können Updates des TYPO3-Kerns schnell und unkompliziert eingespielt werden. Unter Windows kann diese Möglichkeit nicht ohne weiteres eingesetzt werden. (Abb. 2) Um in diesem Fall eine andere TYPO3-Version zu verwenden, müssen die Verzeichnisse des Kerns überschrieben werden. Nachdem die TYPO3-Dateien auf den Webserver kopiert wurden, kann der Installationsassistent verwendet werden, um TYPO3 grundlegend zu konfigurieren. Dieses kann im Drei-Schritt-Modus betrieben werden, wobei lediglich der Datenbankzugriff und der Import der TYPO3-Tabellen eingestellt werden können. (Abb. 3, 4 und 5). Im fortgeschrittenen Modus können dagegen alle Konfigurationsoptionen eingestellt werden, was allerdings meist nicht direkt bei der Installation nötig ist, da der Assistent Administratoren später im Backend zur Verfügung steht, um die TYPO3Konfiguration zu ändern. Ist die Installation mit dem Assistenten abgeschlossen, muss noch das Passwort für den späteren Zugang zum Installationsassistenten angegeben werden. TYPO3 erzeugt schreibt bereits während des Installationsvorgangs die angegebene Konfiguration in die Datei localconf.php im Verzeichnis typo3conf, daher ist es wichtig, dass TYPO3 über Schreibrechte für dieses Verzeichnis verfügt. 5 Im Standard-Paket werden keine Beispielinhalte mitgeliefert, daher muss im Anschluss im TYPO3Backend zumindest eine Seite angelegt werden. Besucht man anschließend das Frontend, wird TYPO3 den Fehler melden, dass kein Template für diese Seite vorhanden ist (Abb. 6). Der Begriff Template ist in TYPO3 mehrdeutig: Zum einen bezeichnet er Template-Dateien, die in der Regel das HTML-Layout enthalten, und in die Inhalte mit Hilfe von Platzhaltern (Marks) eingefügt werden. Zum anderen bezeichnet Template Datensätze, die Informationen zum Render-Prozess und Konfigurationen für Seiten, Plugins, Platzhalter, Menüs u.a. enthalten und in Relation zu der Seitenebene stehen. Wurde letzteres für die erste Seite angelegt, wird im Frontend der Fehler gemeldet, dass keine Konfiguration für diese Seite gefunden werden konnte. Diese muss erst noch mit Hilfe von TypoScript im Setup-Feld des Template-Datensatzes angegeben werden. Abb. 3: TYPO3-Installationsassistent Schritt 1 Abb. 4: TYPO3-Installationsassistent Schritt 2 Abb. 5: Fehler im Frontend: Kein Template Abb. 6: TYPO3-Installationsassistent Schritt 3 Abb. 7: Fehler im Frontend: Keine Konfiguration 6 2.1.3 Das Backend Das Backend stellt eine vollständige Arbeitsumgebung zur Verwaltung und dem eigentlichen Content-Management dar. Das Erscheinungsbild des Backend kann sich von Redakteur zu Redakteur stark unterscheiden und wird vom Administrator je nach Aufgabengebiet des Redakteurs festgelegt. Grundsätzlich hat ein Redakteur die Aufgabe, innerhalb eines festgelegten Workflow Teile der Inhalte zu bearbeiten, das heißt sie zu erstellen und zu modifizieren. Dabei arbeitet er häufig mit anderen Redakteuren zusammen. Bei der Rechtevergabe, die Aufgabe des Administrator ist, gilt der Grundsatz: Soviel wie nötig und so wenig wie möglich. Jedem Redakteur müssen in Abhängigkeit von seinem konkreten Aufgabengebiet soviel Funktionalitäten und Zugriffsrechte zur Verfügung gestellt werden, wie er benötigt. Diese Aufgabe wird in TYPO3 in der Regel mit Hilfe von Benutzergruppen gelöst, deren Eigenschaften und Rechte von den Benutzern geerbt werden. Dabei können die Nutzerrechte zusätzlich für jeden Nutzer gesondert verändert werden, was bspw. für einen Chefredakteur sinnvoll ist. Diesem können aufgrund seiner Aufgaben eine erweiterte Ansicht und zusätzliche Rechte zur Verfügung gestellt werden. So kann er z.B. erstellte Inhalte untergeordneter Redakteure freigeben bzw. verwerfen und an den zuständigen Redakteur zur Nachbearbeitung zurückgeben. Abb. 8: Die Backend-Benutzeroberfläche eines Administrators im Überblick Wie in Abb. 8 zu sehen, besteht das Backend in der Regel aus drei Spalten: Der Modulleiste, die die für den Benutzer freigeschalteten Haupt- und Submodule enthält, dem Navigationsbereich, der je nach Kontext den Seitenbaum, den Dateibaum oder andere Elemente beinhalten kann oder auch ausgeblendet ist und der Detailansicht, dem eigentlichen Arbeitsbereich. Die Ansicht für Redakteure unterscheidet sich in der Regel von der gezeigten insofern, dass weniger Module angezeigt werden (z.B. nur Web, Benutzerwerkzeuge und Hilfe). 7 2.1.4 TypoScript Eine Besonderheit von TYPO3 ist die eigens entwickelte Sprache TypoScript. Diese Sprache einzuordnen, fällt aufgrund ihrer ungewöhnlichen Funktionsweise schwer. Sie wird genutzt, um • • • • • • TYPO3 und Erweiterungen zu konfigurieren, Templates zu konfigurieren und Marker zu ersetzen, Inhaltselemente wie z.B. Menüs dynamisch zu erstellen, Zusätzliche Funktionen und Klassen einzubinden, Grafiken zur Laufzeit zu erstellen, Backend-Konfigurationen vorzunehmen (TSConfig). Sie dient u.a. als Abstraktionsschicht zwischen dem Rendering-Prozess und dem Template und stellt einen Ersatz für die Verwendung von PHP in Templates dar. Während in anderen CMS wie z.B. Joomla! oder Wordpress PHP im Template verwendet werden müssen, kann bzw. muss das Template in TYPO3 durch TypoScript gefüllt werden. Dies mag auf den ersten Blick umständlich erscheinen, bringt jedoch einige Vorteile mit sich: Während Programmierfehler beim Einsatz von PHP in Templates Fehlerausgaben oder gar den Abbruch des Rendering-Prozesses zur Folge haben können, erzeugt fehlerhaftes TypoScript keine Fehlerausgaben. Zudem sind die Konzepte von TypoScript leicht zu erlernen und somit außer für Administratoren auch für Redakteure geeignet. In der Literatur finden sich hauptsächlich Angaben dazu, was TypoScript nicht und weniger dazu was es ist12. Ein gutes Bild davon, was TypoScript ist und welche Rolle es in TYPO3 spielt, bietet folgendes Zitat: „Die Grundfunktionalität eines datenbankbasierten Frameworks besteht in der Regel darin, Inhalte in eine Datenbank einzupflegen und diese dann – in welcher Form auch immer – für verschiedene Betrachter und Medien aufbereitet wieder auszugeben. Eines haben dabei sämtliche verschiedenen Systeme gemeinsam: Eine bestimmte Anzahl von Funktionen wird in geringfügig abgewandelter Form ständig wiederholt. Datenbankabfragen liefern eine definierte Anzahl von Inhaltselementen, die wiederum in ein vordefiniertes Set von Vorlagen (sogenannten Templates) eingebaut werden müssen, bevor sie für die endgültige Ausgabe zusammengesetzt werden. Die Tatsache, dass diese Funktionen sich prinzipiell sehr ähnlich sind, legt nahe, hierfür eine vereinfachte Schreibweise einzuführen – eine Art Stenografie für Programmfunktionen. Diese sollte auf der einen Seite die Möglichkeit bieten, die Funktionen selbst aufzurufen, auf der anderen Seite sollten eventuell nötige Parameter, Inhalte und ähnliche Dinge an eben diese Funktionen übergeben werden können. Außerdem wäre es äußerst komfortabel, die übergebenen Funktionen und Parameter gegebenenfalls noch intern mithilfe weiterer eigener Funktionen modifizieren zu können. Da TYPO3 auf PHP basiert, bietet es sich an, hierfür ein multidimensionales Array zu definieren, das für die einzelnen Funktionen eigene Arrays zur Verfügung stellt. In diesen Arrays würden wiederum deren Parameter und/oder Unterfunktionen mit weiteren Parametern übergeben. Das Ergebnis wäre ein umfangreiches Super-Array, mit dessen Hilfe die Ausgabe des Systems bis ins kleinste Detail gesteuert werden kann. Die Tiefe der 12 Vgl. Ripfel et. al. 2008 – TYPO3-Profihandbuch, S. 82; Koch 2006 – Mastering Typoscript, S. 10 ff.; 8 Struktur wäre theoretisch unendlich. Praktisch betrachtet, würden dennoch Grenzen durch die jeweils verwendete Hardware und deren maximale Performance gesetzt. Nichts anderes ist TypoScript!“ (Trabold et al. 2009 – TYPO3 Kochbuch, S. 247) Das folgende Beispiel soll eine einfache Übersicht über die Begriffe und Funktionen in TypoScript darstellen: beispielObjekt = OBJEKT //Ein Toplevel-Objekt beispielObjekt.eigenschaft = wert beispielObjekt { eigenschaft = geänderterWert weitereEigenschaft = wert2 } inhaltsObjekt = COA //COA steht für Content Object Array inhaltsObjekt { 10 = TEXT 10.value = Ein Textobjekt 20 < beispielObjekt // Kopieren eines Objektes 30 =< beispielObjekt // Referenzieren eines Objektes } beispielObjekt > //Löschen eines Objektes Nach dem Kompilieren, d.h. nach der Übersetzung in ein PHP-Array würde dieses folgendermaßen aussehen: Array( 'inhaltsObjekt' => 'COA', 'inhaltsObjekt.' => Array( '10' => 'TEXT', '10.' => Array( 'value' => 'Ein Textobjekt' ), '20' => 'OBJEKT', //Der Inhalt des beispielObjekt '20.' => Array( 'eigenschaft' => 'geänderterWert', 'weitereEigenschaft' => 'wert2' ), '30' => '' //Leer, da das Referenzobjekt gelöscht wurde ) ) Würde dieser Code durch den TypoScript-Parser geparst, würde dieser lediglich „Ein Textobjekt“ (ohne Anführungsstriche) ausgeben, da das Toplevel-Objekt OBJEKT nicht existiert. Aus obigem Beispiel geht hervor, wie TypoScript in Arrays umgesetzt wird. Was genau TYPO3 bzw. Erweiterungen mit einem solchen Array machen, kommt auf die Funktion an, die angesprochen wird. So dient TypoScript nicht nur zur Konfiguration der Ausgabe im Frontend sondern unter dem Namen TSConfig auch zur Konfiguration des Backend (z.B. zur Konfiguration des Rich-TextEditors). 9 2.2 TYPO3-Framework 2.2.1 Aufbau TYPO3 ist ein sehr modulares System. Seit seiner Veröffentlichung wurde stets daraufhin gearbeitet auch das Core modular umzusetzen, was bis heute zum großen Teil in Form von Systemerweiterungen (Sysext) realisiert wurde. Durch diesen Fokus auf Modulintegration kann man TYPO3 als Framework verstehen, mit dessen Hilfe weit über reines Content-Management hinausgehende Lösungen umgesetzt werden können. Wesentliche Stärke von TYPO3 ist es dabei, Erweiterungen nicht nur in die Programmlogik sondern auch in die Benutzeroberfläche des Backend zu integrieren. Abb. 9: TYPO3-Funktionsschema (Quelle: TYPO3 Core Development Team 2008 – Inside TYPO3, S.3) 10 2.2.2 Verzeichnisstruktur Wie bereits in 2.1.2 beschrieben, wird TYPO3 in zwei unterschiedlichen Paketen zur Verfügung gestellt. In diesem Kapitel sollen nun die wichtigsten Verzeichnisse und Dateien in TYPO3 vorgestellt werden. Aus Gründen der Übersichtlichkeit wurde für folgende Abbildung auf den Einsatz von Symlinks verzichtet. Sie enthält auch nicht alle Dateien und Verzeichnisse, sondern nur jene, die für das Verständnis der TYPO3-Struktur wesentlich sind. Abb. 10: Die wichtigsten Verzeichnisse und Dateien fileadmin/ Dieses Verzeichnis enthält Dateien, die über das Frontend verfügbar sein sollten. Dies sind bspw. Mediendateien, Stylesheet-Dateien, eigene JavaScript-Bibliotheken oder Dokumente zum Download. Die Inhalte dieses Verzeichnisses können im Backend unter dem Datei-Modul verwaltet werden. misc/ Dieses Verzeichnis enthält Beispieldateien, die z.B. die Konfiguration der .htaccess-Datei, SQLBefehle oder den Aufbau von Sprachdateien im XML-Format aufzeigen. Zudem findet man hier die Datei superadmin.php, die Administratoren als Unterstützung beim Warten von mehreren TYPO3-Installationen helfen soll. Dieses Verzeichnis sollte in Produktivumgebungen geschützt oder gelöscht werden. 11 t3lib/ Hier sind die Klassenbibliotheken des TYPO3-Frameworks zu finden, die im gesamten System und in Erweiterungen zum Einsatz kommen (z.B. class.t3lib_div.php). Die Dokumentation dieser Klassen ist online verfügbar13. Weiterhin enthält dieses Verzeichnis Dateien, die Informationen für die Umwandlung von Zeichensätzen und Kodierungen enthalten, Schriftarten (Truetype) für den Einsatz im Gifbuilder, Interfaces für Hook-Klassen und im Verzeichnis stddb die grundlegenden Vorgabewerte für die Standardtabellen von TYPO3. Ebenfalls hier zu finden ist die Datei config_default.php, die die Standardkonfiguration einer TYPO3-Installation enthält. Diese Standardwerte werden vor denen in der Datei typo3conf/localconf.php geladen und von diesen überschrieben. typo3/ Dieses Verzeichnis enthält sämtliche Dateien, die für die Darstellung und Funktionalitäten des Backend verantwortlich sind. Das Backend ist unter diesem Verzeichnis (z.B. http://localhost/t3installation/typo3) erreichbar, wobei dieses auch umbenannt werden kann. Enthalten sind u.a. Klassenbibliotheken (classes/), Softwarebibliotheken von Drittanbietern (contrib/), modulare Stylesheet-Dateien (css/), Icons und Grafiken (gfx/), Schnittstellendefinitionen (interfaces/), JavaScript-Bibliotheken (js/), die Standard-BackendModule (mod/) und HTML-Templates für die Darstellung im Backend (templates/). Das Unterverzeichnis ext/ ist für globale Erweiterungen vorgesehen, die auch für andere TYPO3Installationen, die diesen TYPO3-Kern verwenden, verfügbar sein sollen. In typo3/sysext/ finden sich die Systemerweiterungen, die einen Großteil der TYPO3Funktionalitäten abdecken. Eine der wichtigsten dieser Erweiterungen ist die Erweiterung cms, die für die grundlegenden Content-Management-Funktionen verantwortlich ist. Zu diesen zählt u.a. die TypoScript-Bibliothek tslib, in der alle Inhaltsobjekte definiert werden, die z.B. im Setup von Template-Datensätzen eingesetzt werden können. typo3conf/ Dieses Verzeichnis ist Bestandteil des Dummy-Pakets und enthält Konfigurationen und Erweiterungen, die nur in der jeweiligen lokalen Installation verfügbar sind. Hier werden auch die Konfigurationen aller aktiven Erweiterungen in Cache-Dateien abgelegt. Diese Dateien sind an dem Präfix temp_ zu erkennen und dienen zur Steigerung der Leistung beim RenderingProzess. Die lokalen Erweiterungen sind in Verzeichnissen mit dem Schlüssel der jeweiligen Erweiterung im Verzeichnis ext zu finden. Weiterhin enthält typo3conf das Verzeichnis l10n14, in welchem Lokalisierungspakete zu finden sind, die im Backend geladen wurden. Weiterhin enthält typo3conf die Datei localconf.php, in der mit dem Installationswerkzeug eingestellten Konfigurationen enthalten sind und die Datei extTables.php, mit der Tabellenkonfigurationen des TYPO3-Kerns überschrieben werden können. Beide Dateien können manuell geändert werden. 13 URL: http://typo3.org/fileadmin/typo3api-4.2.6/ Gebräuchliche Abkürzung für localization (Lokalisierung) wobei 10 die Anzahl an ausgelassenen Buchstaben kennzeichnet. (vgl. Lokalisierung Softwareentwicklung 2009) 14 12 typo3temp/ In diesem Verzeichnis legt TYPO3 sämtliche temporären Dateien wie z.B. dynamisch erzeugte JavaScript-Dateien, Bilder oder heruntergeladene Pakete ab. uploads/ In diesem Verzeichnis legt TYPO3 Dateien ab, die im Backend oder Frontend hochgeladen wurden. „TYPO3 kopiert standardmäßig jede Datei, die mit einem Inhaltselement verknüpft wird, in diesen Ordner (oder einen entsprechenden Unterordner). Ist die Datei dort schon vorhanden – etwa, weil sie bereits mit einem anderen Inhaltselement verknüpft wurde –, fügt TYPO3 dem Dateinamen einen fortlaufenden Zahlenwert an. Außerdem legt TYPO3 in der Datenbanktabelle eine entsprechende Verknüpfung zu dieser eindeutigen Datei ab. So ist sichergestellt, dass die Datei stets eindeutig zugeordnet werden kann und der Inhalt auf der Website auch dann vollständig erhalten bleibt, wenn die ursprüngliche Datei gelöscht wird. Zusätzlich ordnet TYPO3 diese Dateien je nach Verwendung in weitere Unterordner. So finden Sie beispielsweise Bilder im Unterordner pics. PDF-Dokumente und Multimedia-Dateien speichert TYPO3 im Ordner media. Dateien, die mit Datensätzen von Extensions verknüpft sind, werden wiederum in Ordnern gespeichert, deren Namen sich aus einem tx_ sowie dem Extension-Key zusammensetzen. Der Ordner uploads/ muss samt Unterordnern vom Webserver beschrieben werden können, damit die Dateien mit den Inhaltselementen verknüpft werden können.“ (Trabold, Hasenau et al. 2009 – TYPO3 Kochbuch, S.15) _.htaccess Diese Datei ist die Vorlage für eine .htaccess-Datei (hypertext access). Eine solche Datei ist eine Konfigurationsdatei, die in der Regel in jedem Verzeichnis einer Website angelegt werden kann. Die Einstellungen in dieser Datei wirken sich nur auf das beinhaltende Verzeichnis und rekursiv auf dessen Unterverzeichnisse aus (Wobei diese wiederrum eigene .htaccess-Dateien enthalten können, deren Einstellungen die der übergeordneten Verzeichnisse überschreiben). Mit Hilfe von .htaccess-Dateien können freigegebene Konfigurationsvariablen des Webservers (z.B. Apache) geändert oder definiert werden. (vgl. Apache Tutorial 06.01.2009) Die mit TYPO3 mitgelieferte _.htaccess konfiguriert das Apache-Modul mod_rewrite mit dessen Hilfe angeforderte URLs umgeschrieben werden können. Dies ist insbesondere dann sinnvoll, wenn man Nutzern und Suchmaschinen lesbare URLs bieten möchte. Komplexere Systeme wie TYPO3 nutzen dafür meist die Möglichkeit von mod_rewrite, die komplette URL an das Skript zu übergeben und diese dann weiter zu verarbeiten. Somit können z.B. mit Hilfe der Erweiterung realurl die Titel von Seiten als Bestandteile der URL genutzt werden. (Prinzipiell überschreibt realurl bei der Ausgabe einer HTML-Seite von TYPO3 erzeugte Links und übersetzt sie bei einer Anfrage wieder in die ursprüngliche Form) Um diese Datei wirksam zu machen, um die URLManipulation in TYPO3 nutzen zu können, muss die Datei umbenannt und dabei der Unterstrich entfernt werden. index.php Diese Datei nimmt alle Anfragen an TYPO3 über das Frontend an und gibt die fertig gerenderte Seite aus. Sie bindet die Datei index_ts.php der Erweiterung cms ein, welche den RenderingProzess für das Frontend koordiniert. 13 2.2.3 Datenbank TYPO3 verwendet relationale Datenbanktabellen und ist optimiert für den Einsatz mit MySQLDatenbanken, kann aber durch die Datenbankabstraktionsschicht (DBAL) auch mit anderen Datenbank-Systemen arbeiten. Diese Schicht erlaubt den Einsatz von Treibern, die die SQLBefehle für andere Datenbanksysteme anpassen bzw. übersetzen. Um den Eingriff der Treiber in die Abfragen des Kerns und von Erweiterungen zu ermöglichen, stellt TYPO3 Entwicklern mit der Klasse t3lib_DB ein API für sämtliche Datenbankabfragen zur Verfügung. Mit dieser ist es möglich, alle Datenbankabfragen (auch die älterer Erweiterungen) zu kapseln und entsprechend den Anforderungen zu manipulieren. Somit können beispielsweise die relationale Datenbankstruktur von TYPO3 auf objektorientierte Strukturen geleitet, andere Datenquellen wie XML-Dateien oder LDAP genutzt oder Tabellen wie fe_users simuliert werden. Die Treiber lassen sich komfortabel als Erweiterungen installieren. Trotzdem die Abstraktionsschicht den Einsatz mit anderen als relationalen Datenbanken erlaubt, arbeiten TYPO3 und Erweiterungen intern stets mit relationalen Tabellen und der Abfragesprache SQL. Daher wird in weiteren Ausführungen dieser Arbeit zum Thema Datenbanken stets die Rede von Tabellen, Feldern und Datensätzen sein.15 TYPO3 bietet umfangreiche Funktionalitäten für die Verwaltung von Tabellen. Besonders ist dabei, dass Erweiterungen nahezu beliebige Tabellenstrukturen definieren können, die dann von Typo3 verwaltet werden können. Dies beinhaltet insbesondere das Anlegen, Kopieren, Verschieben, Löschen und Ausblenden von Datensätzen solcher Tabellen. TYPO3 nutzt dazu das globale Table Configuration Array ($TCA), das sämtliche Informationen, wie Titel, Felder und Beziehungen zwischen Tabellen, Angaben zum Rendering-Prozess für Formulare im Backend, zu von TYPO3 verwalteten Tabellen enthält. In diesem Array spiegelt sich der modulare Aufbau von TYPO3 wieder, da es grundsätzlich nur vier Tabellen enthalten muss, damit eine TYPO3Installation funktionsfähig ist (Diese sind pages, be_users, be_groups und sys_filemounts). Alle weiteren Tabellen werden dem Array über Erweiterungen hinzugefügt.16 15 16 Vgl. TYPO3 Core Development Team 2008 – Inside TYPO3, S.72 Vgl. TYPO3 Core Development Team 2008 – TYPO3 Core API, S.78 ff. 14 Im Backend kann das TCA mit allen Definitionen ausgegeben werden: Abb. 11: Ein Teil der Ausgabe des TCA im Backend Über den Extension Kickstarter können bequem eigene Erweiterungen mit eigenen Tabellen und Beziehungen zu anderen Tabellen angelegt werden, wobei dieser zuletzt ein Gerüst der Erweiterung mit nahezu allen wichtigen Konfigurationen erzeugt. Bei der Installation einer solchen Erweiterung erkennt TYPO3 die durchzuführenden Änderungen an Tabellen bzw. neu zu erstellende Tabellen anhand einer SQL-Datei sowie der Dateien ext_tables.php, die allgemeine Informationen über Tabellen enthält und tca.php, die Datentypen und Abhängigkeiten der Felder abbildet. Sollen Tabellen von TYPO3 verwaltet werden, müssen einige Voraussetzungen erfüllt werden17: • • • 17 Die Tabelle muss mindestens die Felder uid (unique ID, Integer – der Primärschlüssel mit Autoincrement) und pid (parent ID, Integer – Verweis auf die uid des übergeordneten Datensatzes in der Tabelle tt_content) enthalten. Es ist eine Vielzahl an Feldnamen reserviert, diese sollten nur dann in der Tabelle vorhanden sein, wenn sie auch den von TYPO3 vorgesehenen Zweck erfüllen (z.B. title, tstamp, sorting, deleted). Die SQL-Definitionen der neuen und zu erweiternden Tabellen müssen in der Datei ext_tables.sql enthalten sein. Vgl. Ripfel et al. 2008 – TYPO3-Profihandbuch, S.297 15 • • Die grundlegenden Eigenschaften (u.a. Titel, Feld-Mapping, Icon sowie der Pfad zur dynamischen Konfigurationsdatei) der Tabellen müssen dem TCA über die ctrl-Sektion in der Datei ext_tables.php angefügt werden. Die Felddefinitionen mit Datentypen und Angaben zur Anzeige in Backend-Formularen müssen in der dynamischen Konfigurationsdatei tca.php enthalten sein. Tabellen werden dann von TYPO3 verwaltet, wenn sie dem TCA hinzugefügt werden. Andernfalls sind die Tabellen nicht im Backend sichtbar und müssen komplett von der jeweiligen Erweiterung verwaltet werden. Das folgende Beispiel zeigt die Konfiguration für das Feld Title im TCA der entwickelten Erweiterung: 'title' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/locallang_db.xml:title', 'config' => array ( 'type' => 'input', 'size' => '30', 'eval' => 'required', ) ) Bei der Installation von Erweiterungen liest TYPO3 die SQL-Befehle in der ext_tables.sql ein und vergleicht diese mit den vorhandenen Tabellen. Damit soll größtmögliche Unabhängigkeit der Erweiterungen voneinander erreicht werden. In dieser Datei werden grundsätzlich neue Tabellen angelegt, auch wenn nur Felder an bestehende Tabellen angefügt werden sollen: CREATE TABLE tx_formhandlergui_forms ( uid int(11) NOT NULL auto_increment, pid int(11) DEFAULT '0' NOT NULL, tstamp int(11) DEFAULT '0' NOT NULL, crdate int(11) DEFAULT '0' NOT NULL, cruser_id int(11) DEFAULT '0' NOT NULL, deleted tinyint(4) DEFAULT '0' NOT NULL, hidden tinyint(4) DEFAULT '0' NOT NULL, fe_group int(11) DEFAULT '0' NOT NULL, title tinytext, […] PRIMARY KEY (uid), KEY parent (pid) ); CREATE TABLE pages ( tx_formhandlergui_form int(11) DEFAULT '0' NOT NULL ) Im obigen Beispiel werden laut den SQL-Anweisungen zwei Tabellen erstellt. Das Ausführen der Befehle würde bei der Erstinstallation zumindest den Fehler hervorrufen, dass die Tabelle pages bereits besteht. Dies wird jedoch von TYPO3 verhindert, da dieses die Befehle vor dem Ausführen untersucht und erkennt, dass die Tabelle besteht. Es wandelt den CREATE-Befehl dann in einen 16 UPDATE-Befehl um und fügt die neuen Felder der vorhandenen Tabelle hinzu. Besteht die Tabelle dagegen nicht, wird TYPO3 sie anlegen. Damit ist gewährleistet, dass die SQL-Abfragen in Erweiterungen nicht aufgrund fehlender Tabellen oder Felder fehlschlagen.18 Tabellenverknüpfungen, also Beziehungen zwischen Datensätzen, lassen sich im TCA auf zwei Arten abbilden: Zum einen gibt es die Möglichkeit, einfache Beziehungen über kommaseparierte Listen herzustellen, zum anderen können auch wahre m:m-Verknüpfungen zwischen Tabellen realisiert werden. Mit der kommaseparierten Variante können einem Datensatz Datensätze anderer Tabellen zugeordnet werden, ohne dass dafür eine Zwischentabelle nötig wäre. Dies hat allerdings den Nachteil, dass diese Art der Beziehung nicht die Möglichkeit SQL-JOIN-Abfragen unterstützt und die Abfrage bei der Verknüpfung von mehreren Tabellen sehr unübersichtlich werden kann oder mehrere Abfragen notwendig sind. Für die zweite Art der Relation erzeugt der Kickstarter eine Zwischentabelle, die die Verknüpfungen zwischen den zwei Tabellen enthält. Dies erlaubt den Verknüpfungen jeweils eigene Eigenschaften wie z.B. Sortierung in Form von Feldern in der Verknüpfungstabelle zuzufügen. Solche Tabellen enden in der Regel mit _mm. Häufig benötigen Erweiterungen Konfigurationsmöglichkeiten, für die es nicht zweckmäßig ist, einzelne Felder im TCA bzw. in der betreffenden Tabelle anzulegen. Dies ist insbesondere dann der Fall, wenn sich die Konfigurationen bestimmter Felder häufig ändern. Für solche Fälle hält TYPO3 eine Möglichkeit bereit, die als TCA in XML-Form bezeichnet werden kann: Die FlexForms. Mit Hilfe von FlexForms können dieselben Felder wie im TCA definiert werden (Mit Ausnahme von flex-Feldern), wobei die Felder nicht in Datenbankfeldern sondern als XML-Struktur in einem Feld gespeichert werden. Damit stellen FlexForms Formulare innerhalb von Formularen bzw. Datenquellen innerhalb von Datenbankfeldern dar. Um solche Formulare nutzen zu können, muss für die Felder, die FlexForms beinhalten sollen, der Typ auf flex gesetzt werden. Zudem muss die Datenstruktur, die Definition der Felder der FlexForm, angegeben werden. Diese kann unmittelbar im TCA eingegeben werden, was bei längeren Datenstrukturen allerdings meist zu unübersichtlich ist. Eine andere Möglichkeit ist die Datenstruktur in einer XML-Datei anzulegen und im TCA den Pfad zu dieser zu definieren. Eine Besonderheit und ein wichtiger Hintergrund beim Einsatz von FlexForms ist, dass die XML-Struktur, die in der Datenbank gespeichert wird, sich bei einer Änderung an der Datenstruktur in der FlexForm-Definition nicht ebenso ändert. Vielmehr bleiben in der neuen Definition nicht mehr vorhandene Felder, die vor der Änderung ausgefüllt wurden, erhalten. Dies ist zwar für reguläre Anwendungsfälle sehr praktisch, stand allerdings dem ursprünglichen Gedanken entgegen, die kompletten Formularaufbauten als FlexForms zu führen, da ein Entfernen von Feldern so nicht möglich gewesen wäre. Das obige Beispiel des TCA-Feldes würde in einer FlexForm-Datenstruktur folgendermaßen aussehen: <title> <TCEforms> <label>LLL:EXT:f[…]gui/locallang_db.xml:title</label> <config> <type>input</type> <size>30</size> <eval>required</eval> </config> </TCEforms> </title> 18 Vgl. Ripfel et al. 2008 – TYPO3-Profihandbuch, S.298-299 17 2.2.4 TYPO3-Erweiterungen Erweiterungen kommen in TYPO3 schon allein aufgrund der modularen Struktur sehr häufig zum Einsatz. Da viele Agenturen und Entwickler den Nutzen der Veröffentlichung ihrer Erweiterungen zum einen für die Gemeinschaft und zum anderen für das eigene Marketing erkannt haben, finden sich im TYPO3 Extension Repository (TER)19 derzeit 402520 Erweiterungen. Leider ist das TER gegenüber anderen Erweiterungsseiten wie z.B. dem Joomla!-Extension-Directory nicht gut organisiert, d.h. dass es über keine Kategorien verfügt und zahlreiche veraltete oder nicht dokumentierte Erweiterungen enthält. Die Erweiterungen dienen häufig sehr unterschiedlichen Zwecken und lassen sich in zwei Kategorien unterteilen: System-Erweiterungen (sysext), die immer im Source-Paket enthalten sind und Benutzer-Erweiterungen. Letztere lassen sich zum einen global für alle Installationen, die ein gemeinsames Source-Paket nutzen (typo3/ext) und zum anderen lokal für die jeweilige Installation (typo3conf/ext) installieren. Für die Installation, Verwaltung und mit dem Extension Kickstarter auch Bearbeitung und Erstellung von Erweiterungen verfügt TYPO3 über ein Backend Modul namens Extension Manager. Dieser spielt auch bei der internen Verwaltung der Erweiterungen eine große Rolle. Werden Erweiterungen installiert, schreibt er die installierten Erweiterungen gemeinsam mit deren eventueller Konfiguration in ein serialisiertes Array in die temporäre Konfigurationsdatei (typo3conf/temp_CACHED_[...]_ext_localconf.php), mit dessen Hilfe er später erkennen kann, welche Erweiterungen installiert sind. Verfügen Erweiterungen über lokale Konfigurationsdateien (ext_localconf.php), wird deren Inhalt ebenfalls nacheinander in diese Datei geschrieben. Ebenso werden die Inhalte der ext_tables- und TCA-Dateien der installierten Erweiterungen nacheinander in der Datei typo3conf/temp_CACHED_[…]_ext_tables.php gespeichert. Die Inhalte dieser üblicherweise sehr umfangreichen temporären Dateien werden bei jeder Anfrage im Backend und Frontend geladen. Daher erklärt sich, dass TYPO3 für die Verwaltung von Erweiterungen keine eigenen Datenbank-Tabellen benötigt: Die Module, Plugins, Services, Hooks und andere Methoden, die Erweiterungen nutzen, um das Verhalten von TYPO3 zu beeinflussen, fügen diese der globalen Konfiguration jeweils in den Dateien ext_tables.php bzw. ext_localconf.php hinzu. Da der Code dieser Dateien in den genannten temporären Konfigurationsdateien gespeichert wird, werden die Erweiterungen und TYPO3 zur Laufzeit konfiguriert. Wie bereits erwähnt können Erweiterungen sehr unterschiedliche Funktionalitäten zur Verfügung stellen. Diese sind insbesondere21: • • • 19 Frontend-Plugins, die Inhaltselemente, Textfeld- und Überschriften-Typen, MenüElemente, TypoTags, hinzufügen, ändern oder erweitern können oder nur im Frontend eingebunden werden. Backend-Module, die als neue Hauptmodule oder Submodule in bestehenden Hauptmodulen oder als Funktionen für bestehende Module im Backend eingebunden werden können. Klickmenü-Elemente. Dies sind Elemente, die im Kontextmenü der Datensätze im Modul Liste oder von Elementen im Seitenbaum angezeigt werden und Funktionalitäten zur Verwaltung von Datensätzen hinzufügen. URL: http://typo3.org/extensions/repository/ Ringer 2009 – number of extensions 21 Vgl. Ripfel et al. 2008 – TYPO3-Profihandbuch, S. 411-415 20 18 Weiterhin können Erweiterungen auf verschiedene Weise das Verhalten von TYPO3 oder anderen Erweiterungen beeinflussen. Die drei gängigsten Methoden dafür sind22: • • • XCLASS-Einbindung Dabei registriert eine Erweiterung eine Klasse, die das Verhalten einer anderen Klasse im System beeinflussen soll, ihren Dateipfad im XCLASS-Schlüssel der anderen Klasse im globalen Konfigurationsarray. Am Ende jeder Klassendatei in TYPO3 sollte überprüft werden, ob dieses einen XCLASS-Eintrag für die Datei enthält und falls ja, die entsprechende XCLASS-Datei eingebunden werden. Jede Klasse sollte mit t3lib_div::makeInstance(Klassenname) instanziiert werden. Diese Methode überprüft vor der Instanziierung, ob eine XCLASS-Klasse mit dem Namen ux_Klassenname existiert. Ist dies der Fall, wird diese statt der eigentlich angefragten Klasse instanziiert. Die XCLASSKlasse erweitert in der Regel die andere Klasse (extends) und kann somit deren Methoden falls freigegeben überschreiben. Es ist auch möglich die andere Klasse nicht mittels extends zu erweitern, sondern komplett zu ersetzen. Somit kann nahezu jede Funktionalität in TYPO3 mit XCLASS beeinflusst werden. Hooks Ein großer Nachteil der XCLASS-Einbindung ist, dass das Verhalten einer Klasse so nur einmalig bzw. nur von einer Erweiterung geändert werden kann. Weiterhin besteht die Gefahr, dass sich die Originalklasse bei einem Update ändert und die XCLASS unvorhersehbar agiert. Ein anderer Weg wird mit Hooks beschritten: Hooks, also Einsprungpunkte für andere Methoden werden von Klassen bzw. Erweiterungen definiert und ausgewertet. Dazu werten sie einen von ihnen definierten Schlüssel im globalen Konfigurationsarray aus, der meist ein Array darstellt. Diesem Array können andere Erweiterungen beliebig viele Klassen oder Klassenmethoden hinzufügen. Die Klasse, die den Hook zur Verfügung stellt durchläuft dieses Array zu einem gegebenen Zeitpunkt und ruft die registrierten Klassen oder Methoden auf. Ob diese Klassen oder Methoden sein müssen, welche Funktionen bzw. Argumente sie benötigen und wie mit diesen verfahren wird, ist dabei von Hook zu Hook verschieden und von den Anforderungen an diesen abhängig. Meist werden den Hook-Methoden verschiedene Argumente als Referenz übergeben, sodass der Rückgabewert keine Rolle spielt und die Hooks flexibel agieren können. Services Services verfolgen ein ähnliches Konzept wie Hooks. Mit ihrer Hilfe kann das Verhalten von TYPO3 oder Erweiterungen ohne Änderungen am Original-Code beeinflusst werden. Anders als bei Hooks werden jedoch nicht Klassen bzw. Methoden sondern Service-Typen registriert. Bei der Registrierung eines Service müssen die Priorität und Qualität angegeben werden. Entsprechend diesen Parametern werden die Services dann von TYPO3 aufgerufen. Auf diese Art können bspw. Authentifizierungsprozeduren oder systeminterne Texte bzw. Label überschrieben bzw. beeinflusst werden. Eine der wichtigsten Erweiterungen für Entwickler, die TYPO3 erweitern wollen, ist der Extension Kickstarter23. Dieser ermöglicht das Anlegen eines Gerüstes für eine eigene Erweiterung. Es können mit Hilfe einer Benutzeroberfläche Tabellen und deren Formularelemente, Plugins, 22 23 Vgl. . Ripfel et al. 2008 – TYPO3-Profihandbuch, S. 373 ff. URL: http://typo3.org/extensions/repository/view/kickstarter/current/ 19 Module, Sprachpakete, Clickmenu-Elemente und Services erzeugt werden. Weiterhin bietet der Kickstarter die Möglichkeit, vorhandene Tabellen und Module zu erweitern. Prinzipiell kann man den Kickstarter daher als ein Werkzeug zum Rapid Application Development (RAD) ansehen. Mit einer zusätzlichen Erweiterung24 können mit dem Kickstarter außerdem Plugins in der ModelView-Controller-Architektur (MVC) mit Models, Views, Controllern, Templates und Actions erstellt werden. Da sich TYPO3 aber im Allgemeinen auf dem Weg zur Integration in das neue MVCFramework FLOW3 befindet, werden sich die Methoden für den Entwurf von Erweiterungen mit dem ab Version 4.3 integrierten Framework Extbase und der neuen Template-Engine Fluid maßgeblich ändern. Diese beiden neuen Bestandteile wurden aus FLOW3 rückportiert und sollen auf deren Basis entwickelten Erweiterungen größtmögliche Kompatibilität zu TYPO3 v5 ermöglichen.25 Da der Extension Kickstarter sehr einfach zu verwenden ist, wird an dieser Stelle nicht weiter auf dessen Verwendung eingegangen. Der Einsatz des Kickstartes kann beispielhaft für dieses Projekt in 4.2.2 nachvollzogen werden. 24 Kickstarter for lib/div MVC framework URL: http://typo3.org/extensions/repository/view/kickstarter__mvc/current/ 25 Vgl. Rau 2009 – Die Zukunft der Extension-Entwicklung 20 3 Analyse vorhandener Formularerweiterungen 3.1.1 Formhandler Formhandler26 (vormals MailformPlus MVC) ist der offizielle Nachfolger der älteren Erweiterung MailformPlus27, deren Entwicklung im August 2009 eingestellt wurde. Diese TYPO3-Erweiterung wird komplett über TypoScript konfiguriert, was die Anwendung für Redakteure weniger attraktiv macht, da dafür oft tiefergehende TypoScript-Kenntnisse benötigt werden. Allerdings können Formular-Vorlagen vorgefertigt werden, die dann nur noch im Frontend-Plugin eingebunden werden müssen. Über dieses Plugin lassen sich außerdem Einstellungen zum Emailversand, zu Design-Vorlagen und Sprachdateien, Pflichtfeldern und der Umleitungsseite bei erfolgreichem Ausfüllen des Formulars ändern. Formhandler bietet folgende Leistungsmerkmale: • • • • • • • • • • • • • “HTML-Template based Server side error checks Send submitted values as e-mail Redirect to a page after successful submission Store submitted data in DB Captcha support (captcha, sr_freecap, jm_recaptcha, mathguard, wt_calculating_captcha) Multipage forms HTML mails, plain text mails, multipart mails (HTML+plain) File upload handling Multipage forms with conditions (branches) Frontend listing of submitted data Frontend multilanguage support Backend module to manage and export submitted data (PDF,CSV)” (Führicht 2009 – EXT: Universal Formhandler, S.3) Formhandler ist v.a. an Administratoren gerichtet, die erweiterten Zugriff auf das Verhalten der Erweiterung benötigen. Dazu können verschiedene Klassen in den Formularverarbeitungsprozess eingebunden werden. Dieser Prozess besteht aus folgenden Teilprozessen28: Preprocessing Dieser Schritt findet nur statt, wenn noch keine Formulardaten an Formhandler gesendet wurden also in der Regel dann, wenn das Formular das erste Mal angezeigt wird. In diesem Schritt können vorbereitende Prozesse wie z.B. das Vorladen von Standardwerten abgearbeitet werden. 26 URL: http://typo3.org/extensions/repository/view/formhandler/current/ URL: http://typo3.org/extensions/repository/view/th_mailformplus/current/ 28 Vgl.: Führicht 2009 – EXT: Universal Formhandler, S.8 27 21 Intercepting Die Intercepting-Prozesse werden dann ausgeführt, wenn Formulardaten an Formhandler gesendet wurden. Interceptor-Klassen können vor der erneuten Anzeige des Formulars bzw. des nächsten Schrittes (InitInterceptors) und nach dem erfolgreichen Eingang aller benötigten Formulardaten (SaveInterceptors) eingebunden werden. Damit können beispielsweise CrossSite-Scripting-Angriffe (XSS) vereitelt oder mehrmalige Absendungen von einer IP-Adresse blockiert werden. Validierung Die Validierungsklassen werden ausgeführt, wenn Formulardaten auf Validität untersucht werden. Dies geschieht vor weiteren Prozessen und beeinflusst die Ausgabe des Formulars (indem eventuell aufgetretene Fehler ausgegeben werden). Der Standard-Validator erwartet die Fehlerbehandlungsmethoden mit den zugehörigen Feldern als Parameter. Es stehen umfangreiche Fehlerbehandlungsklassen zur Verfügung. Finishing Das Finishing findet statt, wenn alle Formulardaten eingegangen sind und validiert wurden und alle Schritte eines Formulars durchgeführt wurden. An dieser Stelle können z.B. Formulardaten in der Datenbank gespeichert oder eine Bestätigungsseite angezeigt werden. Abb. 12: Formhandler-Funktionsschema (Quelle: Führicht 2009 – EXT: Universal Formhandler, S.5) Für jeden der beschriebenen Prozesse lassen sich im Setup von Formhandler beliebig viele Klassen einbinden und abarbeiten. Es stehen standardmäßig diverse Klassen folgender Typen zur Verfügung: Preprocessor, InitInterceptor, SaveInterceptor, Logger, Finisher. Zudem können zusätzliche Include-Pfade für das automatische Laden von Klassen und eine andere View-Klasse konfiguriert werden. 22 Ein großer Vorteil von Formhandler besteht darin, dass die Einrichtung von Formularen im Formular-Template geschieht. Damit sind Administratoren mit HTML-Kenntnissen sehr flexibel in der Einrichtung von Formularen da Formhandler selbst keinerlei HTML-Code erstellt. Formhandler erkennt wie in TYPO3 üblich Sprachdefinitionen und Felder über Platzhalter im Template. Die Flexibilität wird dabei nur von den begrenzten Möglichkeiten, die solche Platzhalter mit sich bringen eingeschränkt (z.B. ist das erzeugen dynamischer Auswahllisten nicht ohne weiteres möglich). Für kompliziertere Anwendungsfälle können allerdings eigene Platzhalter mit dynamischen Inhalten über TypoScript ersetzt werden. Weiterhin ist Formhandler komplett in der MVC-Architektur angelegt und arbeitet mit einer aus FLOW3 rückportierten Komponente, die den Aufbau als Package für TYPO3 v5 und FLOW3 erlaubt. Damit kann Formhandler mit wenigen Anpassungen später in TYPO3 v5 und FLOW3 eingesetzt werden. 3.1.2 Powermail Powermail29 ist eine Erweiterung für TYPO3, die v.a. an Redakteure und Administratoren gerichtet ist, die Formulare ohne den Einsatz von HTML erstellen und einrichten möchten. Sie bietet folgenden Funktionsumfang: • • • • • • • • • • • Nutzerfreundliches Anlegen neuer Formulare und Felder im Plugin mit IRRE30 Multistep-Formulare Client- und serverseitige Validierung Speichern von Formulardaten in der Datenbank Ersetzen eigener Platzhalter Vorschau bei Formularerstellung Rich-Text-Editor für Emailvorlagen Validierungsoptionen Standardwerte für Formularfelder Unterstützung für Captchas Export von Formulardaten (XLS, CSV, Tabellen) Vorteil dieser Erweiterung ist die benutzerfreundliche Bedienung beim Einrichten und Konfigurieren der Formulare. Die Verwendung von IRRE zum Anlegen von Formularen und Feldern ermöglicht zwar das Anlegen von Formularen und Feldern im Plugin selbst, bringt jedoch auch Schwierigkeiten mit sich. So muss für ein neu angelegtes Feld zunächst der Feldtyp ausgewählt werden (siehe Abb. 13). Da die Konfigurationsoptionen für Feldtypen dynamisch aus FlexForms nachgeladen werden müssen, erscheint anschließend eine Meldung, dass das Formular neu geladen werden muss, da die Wahl des Feldtyps Einfluss auf die Darstellung des Formulars hat. Wird das Formular anschließend neu geladen, muss man erst wieder den Reiter ‚Fields‘ wählen und anschließend das zuvor definierte Feld finden und auswählen, um es weiter zu konfigurieren. Dies ist ein Verhalten, dass das IRRE-Element mit sich bringt und welches die Arbeit mit powermail erschwert. Powermail legt jedes Formular und jedes Feld als einzelnen Datensatz in der Seite, in der sich das Plugin befindet an. Die Relationen zwischen Formularen, Feldern und dem Plugin werden in den Formularen und Feldern hergestellt. Dies hat zur Folge, dass Felder und Formulare nicht mehrmals verwendet werden können sondern immer zu einem Plugin gehören. 29 URL: http://typo3.org/extensions/repository/view/powermail/current/ Abk. für Inline Relational Record Editing – eine mit TYPO3 v4.1 eingeführte TCAKonfigurationsmöglichkeit, die es erlaubt, Datensätze relationaler Tabellen via AJAX im Formular zu erstellen 30 23 Ein weiterer großer Nachteil von powermail besteht darin, dass für Felder nur eine Validierungsart angegeben werden kann. Abb. 13 Powermail mit IRRE (Quelle: Kellner, Heißmann 2009 – powermail, S.18) 3.1.3 Chronoforms (Joomla!) Chronoforms31 ist eine Komponente zur Formularerzeugung und –Verarbeitung für das CMS Joomla!. Sie bietet prinzipiell dieselben Funktionen wie die obengenannten Erweiterungen für TYPO3 und soll, da es sich um eine Erweiterung für ein anderes System handelt, nur aufgrund ihres interessanten Ansatzes erwähnt werden. Wie Formhandler untersucht Chronoforms HTMLTemplates auf Vorkommnisse von Formularelementen. Dabei wird allerdings im Gegensatz zu Formhandler nicht auf das Vorkommen von Platzhaltern wie ###value_field### oder ###checked_field### sondern auf reguläre HTML-Formularelemente untersucht. Die Erweiterung erkennt dabei automatisch, ob es sich um ein Select-, Textfeld-, Input-, Radio- oder CheckboxElement handelt und ist in der Lage, diese mit Standardwerten, JavaScript-Validierern und bereits abgesendeten Formulardaten (Republishing bei fehlerhaftem Ausfüllen) zu versehen. Ebenso automatisiert ist das Speichern von Formulardaten in der Datenbank: Chronoforms schreibt die Formulardaten mit der Konvention, dass die Feldnamen im Formular denen in der entsprechenden Tabelle entsprechen, automatisch in die Datenbank. Wie in Joomla! üblich, kann außerdem PHP-Code in allen Templates verwendet werden, was jedoch gerade in Anbetracht der 31 URL: http://www.chronoengine.com/ 24 Tatsache, dass Chronoforms diese Templates in der Datenbank vorhält, keine optimale Lösung im Sinne der Trennung von Inhalt, Darstellung und Steuerung darstellt. 3.1.4 Erkenntnisse aus der Analyse Die Ergebnisse der Analyse zeigen sich in folgender Gegenüberstellung: Erweiterung Formhandler powermail Version Konfiguration 0.9.0 Beta Via TypoScript Architektur Eigene Templates Felderstellung MVC – ExtBase kompatibel Ja Via HTML-Template (Felder werden automatisch aus dem Template extrahiert) nein Serverseitig Ja 1.4.16 Stable Via TypoScript bzw. in PluginInstanz TYPO3 Standardaufbau Ja Via IRRE, als Datensatz oder TypoScript in Plugin-Instanz Eigene Felder Validierung Mehrere Validierungsarten für ein Feld Eigene Validierungsarten Hooks Speichern von Formulardaten Relationale Tabellen Mehrere Datenbanken Formularanzeige in Abhängigkeit von der Benutzergruppe Feldanzeige in Abhängigkeit von der Benutzergruppe MultiStep-Formulare MultiStep-Formulare mit Abhängigkeit von Formulardaten Modul zur Anzeige von Formulardaten Exportmöglichkeiten Kompatibel mit TYPO3 v5 (voraussichtlich) Ja nein Ja – via Finisher und TypoScript-Feldmapping Ja – via Finisher und TypoScript-Feldmapping Ja – via Finisher und TypoScript-Feldmapping Ja – im Plugin Ja – via TypoScript oder Hook Serverseitig / clientseitig Nein Ja – via Hook Umfangreich. Möglichkeit in viele Prozesse einzugreifen. Ja via TypoScript-Feldmapping Ja via TypoScript-Feldmapping Nein Ja – im Plugin Bedingt – via TypoScript Nein Ja Ja Ja Nein Ja Ja CSV, PDF XLS, CSV – automatisierter Export mit Cronjobs möglich Nein Ja Es hat sich gezeigt, dass bei Powermail im Gegensatz zu Formhandler ein eher nutzerfreundlicher Ansatz gewählt wurde. Die Vorteile dabei liegen v.a. bei Redakteuren. Da Redakteure allerdings nur selten die funktionalen Elemente von Formularen verwalten sollten, bietet Formhandler dagegen ein Höchstmaß an Flexibilität für Administratoren, die über Erfahrungen mit dem manuellen Erstellen von Formularen mit HTML und CSS verfügen. Prinzipiell lässt sich feststellen, dass Formulare für Formhandler grundsätzlich in HTML erstellt und mit TypoScript konfiguriert 25 werden, was in Powermail komplett innerhalb des Plugins bzw. der Formular- und FeldDatensätze geschieht. Ein Nachteil beider Erweiterungen ist, dass in den Modulen zur Anzeige der Formulardaten jeweils erst die Seite im Seitenbaum ausgewählt werden muss, in der das auszuwertende Formular enthalten ist. Dies ist besonders dann umständlich, wenn auf mehre Seiten verteilte Formulare ausgewertet werden müssen. 26 4 Durchführung 4.1 Entwurf 4.1.1 Ansatz und Anforderungen Der Gegensatz der beiden Erweiterungen, Flexibilität gegen Nutzerfreundlichkeit, ist ein entscheidendes Kriterium für die Entwicklung einer neuen Formularerweiterung. Die neue Erweiterung sollte die Nutzerfreundlichkeit der einen mit der Flexibilität der anderen verbinden. Zugleich sollte sie fehlende Funktionen ergänzen. Diese sind insbesondere: • • • Ein API, das von anderen Erweiterungen genutzt werden kann, um eigene FrontendFormulare und Felder zu definieren und einzusetzen Eine Möglichkeit, Formulare mit Hilfe einer grafischen Oberfläche zu erzeugen und diese als Vorlagen für erweiterte Bearbeitungsmöglichkeiten zu speichern Eine Möglichkeit, Felder in Abhängigkeit von der Gruppenzugehörigkeit des FrontendBenutzers anzuzeigen Um dies zu ermöglichen, sollten prinzipiell beide Erweiterungen verbunden werden. Die Zielsetzung bei Softwareprojekten wie diesem sollte allerdings nicht zwangsläufig einen Fork32 bedeuten: „In a fork, the person(s) creating the fork intend for the fork to replace or compete with the original project they are forking.”33 Diese Intention ist bei diesem Softwareprojekt nicht gegeben, weshalb nach Lösungen gesucht wurde, wie man die nötigen neuen Funktionen am besten mit den vorhandenen Erweiterungen kombinieren könnte. Da die neue Erweiterung nicht nur in diesem Projekt eingesetzt, sondern unter einer Open-Source-Lizenz verbreitet werden soll, muss es anderen TYPO3-Nutzern so einfach wie möglich gemacht werden, die Erweiterung zu installieren. Eine Erweiterung, die zwei ähnliche Erweiterungen voraussetzen würde, würde jedem Nutzer die Frage aufdrängen, wozu er drei vergleichbare Erweiterungen installieren sollte. Mit sehr hoher Wahrscheinlichkeit, würde sich in diesem Falle die Mehrheit der Anwender für eine der älteren Erweiterungen entscheiden. Dies würde zu einem schnellen Ende der neuen Erweiterung führen, da ihr Überleben als Open-Source-Software substantiell von der Unterstützung in Form von Fehlerberichten (Code Reviews, Bug Reports) und Korrekturen (Patches) abhängig ist. Daher musste sich für eine Erweiterung entschieden werden, mit der die neue Erweiterung zusammenarbeiten soll. Die Erweiterung Formhandler wurde nach längerer Entscheidungsfindung für diesen Zweck ausgewählt. Die Gründe dafür liegen darin, dass Formhandler selbst sehr flexibel programmiert wurde. Die verschiedenen Interceptor-Klassen bieten gute Möglichkeiten, in die wichtigsten Prozesse einzugreifen, ohne dabei zwangsläufig die erweiterungsinternen Abläufe kennen oder ändern zu müssen. Ein weiterer wichtiger Vorteil besteht darin, dass Formhandler intern mit dem Komponenten-Manager der Erweiterung gimmefive (siehe 4.2.5) arbeitet, d.h., dass gimmefive nicht installiert sein muss aber kann, damit Formhandler funktioniert. Für den Einsatz der Interceptor-Klassen können dabei dank eines Eingriffs der Formhandler-Entwickler in den 32 „A fork is a competing project based on a version of the pre-existing project’s source code. All OSS/FS projects can be “forked”; the ability to create a fork is fundamental to the definition of OSS/FS.” (Wheeler 2007 – Why Open Source Software) (OSS/FS – Abkürzung für Open-Source-Software und Freie Software) 33 Wheeler 2007 – Why Open Source Software 27 Manager zusätzliche Include-Pfade im TypoScript-Setup angefügt werden. Damit können auch die Interceptor-Klassen von der Autoload-Funktion von gimmefive profitieren. Der Nachteil, dass der Komponenten-Manager im derzeitigen Zustand keine XCLASS-Einbindung unterstützt, kann durch einen kleinen Eingriff in dessen Autoload-Mechanismus ausgeglichen werden. Die Programmierer von Formhandler zeigten sich bereits kooperativ und stellten dem Autor einen eigenen Branch34 zur Verfügung, in dem er die nötigen Anpassungen pflegen kann. Dies hat zum Ziel, dass die Anpassungen für die neue Erweiterung zu dem Zeitpunkt, an dem deren erster Release Candidate veröffentlicht wird, mit dem Trunk35 zusammengeführt werden. Ein weiterer Grund für die Entscheidung, Formhandler als Grundlage zu nutzen, war, dass dieses keine Tabellen für die Formularprozesse benötigt und ausschließlich über das TypoScript-Setup konfiguriert werden kann. Dies sind gute Voraussetzungen, um die Formulare und Felder als Datensätze in den Tabellen der neuen Erweiterungen zu pflegen und aus diesen die TypoScript- und HTML-Vorlagen für Formhandler zu erzeugen. Zusammenfassend soll Formhandler für die Frontend-Prozesse und die neue Erweiterung für die Formularverwaltung im Backend sowie das Erzeugen und die Übergabe der Vorlagen an Formhandler im Frontend verantwortlich sein. Entsprechend wurde auch der Name der neuen Erweiterung gewählt: Sie wird FormhandlerGui heißen und unter dem Extension Key formhandlergui verfügbar sein. 4.1.2 Prototypen Prototypen stellen eine sehr gute Hilfestellung bei der Entwicklung von Anwendung dar. Sie können mit unterschiedlichen Mitteln erzeugt werden und über unterschiedliche Funktionen verfügen. In diesem Fall dienten die Prototypen zur Orientierung, wie die Backend-Formulare aussehen und welche Elemente sie enthalten werden. Über diese Oberflächenprototypen hinausgehende interaktive Prototypen waren für die Entwicklung der Erweiterung nicht notwendig, da die Funktionalitäten im Wesentlichen von TYPO3 vorgegeben sind. Im Folgenden sind die Oberflächenprototypen für die allgemeinen Einstellungen der Formulare (Abb. 14), die Feldeinstellungen (Abb. 15) und die Datenbankeinstellungen (Abb. 16) dargestellt. Die endgültige Anwendung wird zwar stark von diesen abweichen, die prinzipielle Funktionsweise bleibt jedoch gleich. 34 Eine Gabelung bei der versionierten Softwareentwicklung Der Standard-Zweig bei der versionierten Softwareentwicklung, aus dem die Arbeitskopien bezogen und in den Änderungen eingespielt werden. 35 28 Abb. 14: Prototyp der allgemeinen Einstellungen für Formulare Abb. 15: Prototyp der Feldeinstellungen für Formulare 29 Abb. 16: Prototyp der Datenbankeinstellungen für Formulare 4.1.3 Funktionsweise Die Hauptfunktionalitäten von FormhandlerGui liegen in einem eigenen Backend-Modul. Die Frontend-Funktion wird sich vorerst darauf beschränken, die Konfigurationen für Formhandler zusammenzustellen und an dieses zu übergeben (siehe 4.2.4). Das Backend-Modul bündelt die Funktionen von Formhandler. Die Anforderung, die Formulare und Felder an zentraler Stelle verwalten zu können, bedingt, dass das Modul eine Übersicht über die Formulare unabhängig von deren Einsatz im Seitenbaum bieten muss. Dies geschieht über eine Darstellung der Formulare in einer Baumansicht in der Navigationsleiste des Moduls. Um diesen mit den entsprechenden Funktionen wie Klickmenüs und Sofortbearbeitung versehen zu können, musste eine Erweiterung der Klasse t3lib_treeview geschaffen werden, die den Klassen zur Darstellung des Seiten- oder Dateibaums ähnelt. TYPO3 stellt den Modulen zwar viele Funktionalitäten zur Verfügung, überlässt ihnen jedoch die Darstellung eigener Funktionalitäten. Darum musste eine Möglichkeit gefunden werden, um eigene Funktionalitäten wie z.B. die Formulardaten-Reporte im Backend und später unter Umständen auch im Frontend abzubilden. Dies wird durch die Verwendung der MVC-Architektur mit Hilfe eines Komponenten-Managers erreicht, was unter 4.2.5 eingehend erläutert wird. Da die Formular- und Felddatensätze sowohl im Backend als auch im Frontend abhängig von der Gruppenzugehörigkeit des Nutzers bearbeitet bzw. ausgegeben werden sollen, bietet es sich an, diese unter Verwendung des TCA zu definieren. So kann für Backend-Benutzergruppen und Benutzer zudem detailiert festgelegt werden, welche Datensätze welcher Tabellen sie einsehen, bearbeiten und erstellen dürfen. Dabei können auch einzelne Felder der Tabellen gesperrt 30 werden, was besonders für die Datenbank-Einstellungen der Formulare sinnvoll ist. Auf diese Weise ist es möglich, die funktionalen Bestandteile der Formularkonfiguration von den inhaltlichen zu trennen (z.B. können für Redakteur-Gruppen nur die Sprachinhalte freigegeben werden). Außerdem bringt die Organisation der Formular- und Feldtabellen durch das TCA den Vorteil mit sich, dass die Backend-Formulare für die Formular- und Feldverwaltung nicht manuell erstellt werden müssen, sondern automatisch anhand der Felddefinitionen von TYPO3 erstellt werden. Dadurch können andere Erweiterungen ebenfalls neue Felder zu diesen Formularen hinzufügen oder deren Eigenschaften beeinflussen. Die Funktionen von TYPO3 für die Verwaltung von Tabellen und Datensätzen (siehe 2.2.3) können damit voll ausgeschöpft werden. Eine Bedingung dafür, die für diese Erweiterung nicht unbedingt erwünscht ist, ist, dass das Feld pid (Parent ID) der Tabellen zwangsläufig einer Seite zugeordnet werden muss, sofern nicht nur Administratoren die Datensätze bearbeiten können sollen. Jedoch überwiegen die Vorteile der Tabellen-Verwaltung durch TYPO3 so stark, dass dies in Kauf genommen wurde und für die Erweiterung eine Seite vom Typ SysFolder ausgewählt werden muss, in der die Formulare und Felder enthalten sind. Dadurch können diese Datensätze auch unabhängig vom FormhandlerModul unter dem Modul Web->Liste verwaltet werden. Mit Hilfe der TCA-Felddefinitionen können viele Konfigurationsoptionen mit passenden Feldern wie z.B. Checkboxen, Input-Feldern oder Auswahllisten umgesetzt werden. Letztere spielen für FormhandlerGui eine besondere Rolle, da über diese die Felder angelegt, Feldtypen und Validierungsoptionen hinzugefügt und die Tabellen zur Datenbankspeicherung ausgewählt werden. Eine weitere besondere Funktion von FormhandlerGui ist die Konfiguration der DatenbankSpeicherung bzw. der Feldzuweisung (Mapping). Diese kann automatisch geschehen, indem die Felder der für die Speicherung ausgewählten Tabellen gegen die Namen der Formularfelder abgeglichen und passenden Felder zusammengeführt werden. In zukünftigen Versionen der Erweiterung soll zudem eine Funktion implementiert werden, die es erlaubt, für jedes Formularfeld ein Feld in einer der Tabellen auszuwählen, falls die automatische Feldzuweisung nicht genügt (Manuelles Mapping). 31 4.2 Entwicklung 4.2.1 Arbeitsweise Da FormhandlerGui ein Open-Source-Produkt darstellt, gilt es bei der Entwicklung einige Voraussetzungen für die Integrität der Arbeit zu erfüllen. Diese werden insbesondere durch die Coding Guidelines 36 für TYPO3-Erweiterungen definiert. Darin wird u.a. der Aufbau von Klassendateien, Kommentar- und Dokumentationsblöcken, Klassen-, Funktionen- und Bedingungsformatierungen festgelegt. Diese Richtlinien treffen allerdings nur für die herkömmlichen TYPO3-Klassen, wie z.B. Plugin-, Modul-, oder XLASS-Klassen zu. Für die Klassen, die im FLOW3-Stil geschrieben wurden (siehe 4.2.5) wurden daher die Coding Guidelines37 von FLOW3 verwendet. Deren wesentlicher Unterschied zu den Richtlinien von TYPO3 besteht darin, dass das Autor-Attribut nicht den Klassen sondern jeder einzelnen derer Methoden zugeordnet wird und die Klassen und Methoden einer Datei nicht mehr im Dateikopf aufgelistet werden. Dies liegt daran, dass in FLOW3 im Gegensatz zu TYPO3 jede Klasse einer Datei mit demselben Namen zugeordnet werden muss. Den Richtlinien entsprechend wird bei der Entwicklung von FormhandlerGui großer Wert auf Dokumentationen im Programmcode gelegt. Als Entwicklungswerkzeug wurde die die IDE38 Eclipse mit der Erweiterung PDT39 gewählt. Diese erlaubt neben vielen anderen modularen Funktionen wie Code-Komplettierung, Verbindung zu Versionierung und Projektmanagement, Objekt-Browsern und vielem mehr die automatische Anzeige von Variablen und Klassenobjekten, die im Include-Pfad enthalten sind. Damit kann die Geschwindigkeit der Entwicklung wesentlich beschleunigt werden, da die Suche nach Klassenobjekten und Methoden in der Verzeichnisstruktur so meist unnötig ist. Für Klassenobjekte und Funktionen zeigt Eclipse neben deren Speicherort auch die Beschreibungen der Argumente und Rückgabewerte und der Methoden selbst aus den Dokumentationsblöcken an (Abb. 17). Für Klassen, die mit Funktionen wie t3lib_div::makeInstance() oder Tx_GimmeFive_Component_Manager->getComponent() instanziiert werden, kann Eclipse die Eigenschaften dagegen nicht erkennen. Dies kann nur erreicht werden, indem diese Instanzen als Klassenvariablen definiert und mit dem Klassennamen als @var-Kommentar versehen werden. Die native Nutzung der Kommentarblöcke in Eclipse PDT führt dazu, dass der Entwickler wesentlich stärker motiviert wird, diese anzulegen, was wiederrum anderen Entwicklern entgegenkommt. TYPO3 stellt mit der Software-Projektmanagementanwendung RedMine für jede Erweiterung ein eigenes Projekt zur Verfügung, in dem Entwickler die Entwicklung koordinieren können. Diese unterstützt das Management von Fehlerberichten (Tickets, Bugs, Issues), Release-Management, Wikis und die Anbindung an die Versionsverwaltung mit SVN. Zusätzlich zu diesem RedMineProjekt stellt TYPO3 für jede Erweiterung ein SVN-Projektarchiv zur Versionskontrolle zur Verfügung. Damit ist es möglich, aus der IDE heraus Aufgaben oder Fehlerberichte in RedMine über SVN-Commits zu lösen (fixes) oder zu referenzieren (refs). Fehlerberichte können dabei sinnvollerweise auch von anderen registrierten Benutzern abgegeben werden. Dem Manager des RedMine-Projekts unterliegt es, die Aufgaben und Fehler an eventuelle Mitglieder des Projektes 36 Vgl. Dulepov, Suter 2008 – TYPO3 Coding Guidelines, S.2 ff. Vgl. Eilers, Dambekalns – FLOW3 Coding Guidelines, S.1 38 Engl. Abk. für Integrated Development Environment 39 Engl. Abk. für PHP Development Tools 37 32 zu delegieren. Diese Möglichkeiten werden auch bei der Entwicklung von FormhandlerGui eingesetzt40. Abb. 17: Anzeige von Methoden und Eigenschaften in Eclipse PDT 4.2.2 Kickstart Zunächst werden die Erweiterung und die wichtigsten Informationen mit dem Kickstarter erstellt. Dazu muss im Extension Manager die Funktion Create new Extension ausgewählt werden. Anschließend können allgemeine Angaben für die Erweiterung getroffen werden, die später in die Datei ext_emconf.php (Extension Manager Configuration) geschrieben werden (Abb. 18). Die wichtigste Angabe dabei ist der Erweiterungsschlüssel (Extension Key), da er nachdem die Erweiterung erzeugt wurde nur schwer zu ändern ist und er das zentrale Erkennungsmerkmal der Erweiterung darstellt. Weiterhin können neben der Standardsprache Englisch weitere Sprachen für die Beschriftungen und Hinweise hinzugefügt werden. In diesem Fall wurde Deutsch als zusätzliche Sprache angelegt. Im Anschluss wird der Erweiterung ein Backend-Modul innerhalb des Web-Moduls zugefügt (Abb. 19). Die grundsätzliche Einrichtung der Erweiterung ist damit abgeschlossen. Damit die Dateien tca.php, ext_tables.php und ext_tables.sql mit den grundsätzlichen Tabelleneigenschaften angelegt werden, werden für die Erweiterung noch die zwei Tabellen tx_formhandlergui_forms und tx_formhandlergui_fields hinzugefügt und die Erweiterung anschließend gespeichert. 40 URL: http://forge.typo3.org/projects/show/extension-formhandlergui 33 Abb. 18: Kickstarter – allgemeine Informationen Abb. 19: Kickstarter – Moduleigenschaften 34 Da der Kickstarter zwar eine gute Methode ist, Gerüste für Erweiterungen umzusetzen, sich geänderte Erweiterungen jedoch nicht garantiert verlustfrei mit ihm bearbeiten lassen, wird mit dem Kickstarter eine zusätzliche Ersatzerweiterung erzeugt. Damit ist es möglich, jeweils nur die Änderungen durch den Kickstarter in die tatsächliche Erweiterung zu übernehmen. Diese Erweiterung wird zunächst ähnlich der originalen Erweiterung angelegt. Anschließend werden die benötigten Felder der beiden Tabellen im Kickstarter für diese statt der ursprünglichen Erweiterung angelegt. Mit dem Kickstarter lassen sich dazu prinzipiell dieselben Einstellungen vornehmen, die sich im TCA konfigurieren lassen (Abb. 20). Zudem lassen sich für die Tabellen Titel, das Typ-Feld (Abb. 20), das Titelfeld und weitere Eigenschaften angeben. Mit diesen lässt sich u.a. bestimmen, ob eine Tabelle versionierbar sein soll, ob die Felder mittels Flags gelöscht und versteckt werden können, ob sie zeitlich begrenzt oder nur bestimmten Frontend-Gruppen angezeigt werden können und an welchen Stellen die Datensätze erzeugt und angezeigt werden können. Die in der Ersatzerweiterung erzeugten Felddefinitionen werden nach der Erstellung mit dem Kickstarter in die entsprechenden Abschnitte der TCA der ursprünglichen Erweiterung kopiert. Abb. 20: Kickstarter – Feldeigenschaften 35 Für die Tabellen wurden so folgende Einstellungen getroffen: Tabelle tx_formhandlergui_forms – Die Tabelle mit den Formulardatensätzen Titel Formhandler forms Versionierbar Nein (während der Entwicklung) Lokalisierbar Nein Gelöscht-Flag Ja Versteckt-Flag Ja Startzeit/Endzeit erlauben Ja Beschränkung auf Frontend-Gruppen erlauben Ja Manuelles Sortieren erlauben Nein Typ-Feld type (Standard oder MultiStep) Label-Feld title Erzeugen von Datensätze in Seiten erlauben Nein Erzeugen in Inhaltselementen erlauben Nein Felder: title – String Input – Formulartitel type – Selectorblock – Formular-Typ (Standard oder MultiStep) multistep_forms – Database Relation – Formulare für MultiStep-Formulare method – Selectorbox – Formularmethode (GET oder POST) prefix – String Input – Feldnamenpräfix enable_mail – Checkbox – Email-Versand aktivieren enable_db – Checkbox – Datenbankspeicherung aktivieren debug – Checkbox – Debugmodus aktivieren fields – Database Relation – Datensätze aus der Tabelle tx_formhandlergui_fields tables – Selectorbox – Liste der Tabellen in der Datenbank mapping – Passthrough – Das Feld für die manuellen Mapping-Einstellungen email_conf – Flex – Die Einstellungen zum Emailversand Tabelle tx_formhandlergui_forms – Die Tabelle mit den Felddatensätzen Titel Formhandler fields Versionierbar Nein (während der Entwicklung) Lokalisierbar Ja Gelöscht-Flag Ja Versteckt-Flag Ja Startzeit/Endzeit erlauben Ja Beschränkung auf Frontend-Gruppen erlauben Ja Manuelles Sortieren erlauben Nein Typ-Feld field_type (Über Hook-Funktion erzeugt) Label-Feld field_title Erzeugen von Datensätze in Seiten erlauben Nein Erzeugen in Inhaltselementen erlauben Nein Felder: field_title – String Input – Feldtitel field_type – Selectorblock – Feld-Typ (Über Hook-Funktion erzeugt) field_label – String Input – Das Label des Feldes lang_conf – Flex – Die Spracheinstellungen field_conf – Flex – Feldeinstellungen validators – Selectorbox – Validierungsklassen (Über Hook-Funktion erzeugt) 36 4.2.3 TCA-Konfiguration Die Einstellungen, die mit dem Kickstarter vorgenommen und entsprechend für FormhandlerGui übernommen wurden, sind zwar sehr hilfreich bei der Entwicklung, genügen aber nicht zur Konfiguration. Insbesondere um Reiter in den Backend-Formularen zu konfigurieren, müssen weitergehende Einstellung im TCA vorgenommen werden. Das Array, das im TCA für die Anzeige von Feldern und Tabs in Backend-Formularen zuständig ist, ist das Type-Array. Zur Konfiguration von Reitern muss im showitem-Register ein Feld namens --div-- verwendet und in der ext_tables.php das Flag dividersToTabs aktiviert werden. Das in der ext_tables.php definierte TypFeld legt fest, welcher der definierten Typen dargestellt wird. Für die Formulartabelle wurde konfiguriert, dass dies das Feld type ist, welches die Werte 0 (Standard) und 1 (MultiStep) enthalten kann. Die Unterschiede der beiden Typen bestehen darin, dass für den MultiStep-Typen das Feld multistep_forms zusätzlich und der Reiter Felder nicht angezeigt wird: $TCA['tx_formhandlergui_forms']['types'] => array ( '0' => array('showitem' => 'hidden;;1;;1-1-1, title;;2;;2-2-2, enable_email, enable_db, debug, --div-;LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx _formhandlergui_forms.tabs.fields, rows;;;;1-1-1, cols, fields'), '1' => array('showitem' => 'hidden;;1;;1-1-1, title;;2;;2-2-2, multistep_forms, enable_email, enable_db, debug') ) Für die Feldtabelle sind allerdings weitergehende Anpassungen im type-Register erforderlich. Dies rührt daher, dass die Feldtypen nicht fest an zentraler Stelle definiert sind, sondern FormhandlerGui über das globale Konfigurationsarray mitgeteilt werden. Dazu werden die Feldtypen in der ext_localconf.php registriert. Damit soll anderen Entwicklern die Registrierung eigener Feldtypen aus deren Erweiterungen vereinfacht werden. Folgendes Beispiel zeigt die Registrierung des Feldtypen Text: $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['formhandlergui']['fiel dTypes'][] = array( 'tx_formhandlergui_text' => array( 'title' => 'LLL:EXT:[…]/fields.xml:text.title', 'langConf' => 'EXT:[…]tx_formhandlergui_text.lang.xml', 'fieldConf'=> false )); Im TCA der Feldtabelle werden zunächst vier type-Fragmente erzeugt, die anschließend in einer statischen Funktion abhängig von der Konfiguration des Feldtypen zusammengesetzt werden. Diese sind das grundsätzliche Formular im Reiter Allgemein, der Reiter Spracheinstellungen, der Reiter Feldeinstellungen und der Reiter Zugriff. Im TCA sind diese folgendermaßen definiert: $TCA['tx_formhandlergui_fields']['types'] => array ( '0' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, field_type, field_label;;;;2-2-2'), 37 '0-langConf' => array('showitem' => ', --div--;LLL:EXT:[…].lang_conf, lang_conf'), '0-fieldConf' => array('showitem' => ', --div--;LLL:EXT:[…].field_conf, field_conf'), '0-access' => array('showitem' => ', --div--;LLL:EXT:[…].access, fe_group') ); tx_formhandlergui_tca::addFieldTypes2TCA(&$TCA['tx_formhandler gui_fields']); In der Funktion addFieldTypes2TCA werden die registrierten Feldtypen erkannt und die typeDefinitionen entsprechend zusammengesetzt. Für den Feldtyp Text im obigen Beispiel würde diese Funktion zunächst die type-Definition des Registers 0 aus dem obigen TCA-Ausschnitt in das type-Register tx_formhandlergui_text kopieren. Nach anschließender Überprüfung der Konfiguration dieses Feldtyps, wird dieses um das Register 0-langConf erweitert, da fieldConf für diesen Feldtyp mit false deaktiviert wurde. Anschließend wird noch das Register 0-access hinzugefügt. Das Resultat für diesen Feldtypen sähe folgendermaßen aus: $TCA['tx_formhandlergui_fields']['types']['tx_formhandlergui_t ext'] = array( 'showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, field_type, field_label;;;;2-2-2, --div--;LLL:EXT:[…].lang_conf, lang_conf, --div--;LLL:EXT:[…].access, fe_group '); Die Entscheidung, welches der type-Register letztendlich dargestellt wird, hängt von der Auswahl des Nutzers für das Feldtyp-Feld im Backend-Formular der Felddatensätze ab. Die Optionen dieses Auswahlfelds werden von einer zweiten Funktion erzeugt, die ebenfalls die registrierten Feldtypen erfasst. Die Werte der Auswahloptionen entsprechen den Schlüsseln der Feldtypen (z.B. tx_formhandlergui_text). Abhängig von der Auswahl des Nutzers wählt TYPO3 das entsprechende Register im type-Array des TCA. Würde ein Nutzer den Felttyp Text auswählen, würde entsprechend das type-Register tx_formhandlergui_text dargestellt. Zusätzliche Feldtypen ließen sich theoretisch auch direkt in die entsprechenden Register im TCA der Feldtabelle schreiben. Dies würde jedoch den doppelten Umfang dafür benötigter Code-Zeilen bedeuten. Die Felddatensätze können während der Formularerstellung in der Feldauswahlliste erzeugt und bearbeitet werden. Diese Funktion ist nativ in TYPO3 implementiert, birgt jedoch Unannehmlichkeiten für den Benutzer: Die aktuelle Eingabemaske muss für das Erstellen relationaler Datensätze wie den Feldern verlassen werden und steht erst nach dem Schließen der neuen Masken wieder zur Verfügung. Das Bearbeiten vorhandener Datensätze funktioniert dagegen verhältnismäßig nutzerfreundlich in einem Popup-Fenster. Dieses Verhalten muss für neue Datensätze erst in Form eines neuen Wizards programmiert werden, der der Auswahlliste ein neues Feld hinzufügt und das Fenster anschließend schließt. Dieser eigene Wizard verhält sich auch in einem weiteren Punkt anders als der native Assistent zum Erstellen von Datensätzen: Der relationale Formular-Datensatz muss nicht vor dem Erstellen neuer Felddatensätze gespeichert 38 werden, da sowohl Feld- als auch Formulardatensätze in einer fest definierten Seite vom Typ SysFolder liegen. 4.2.4 Schnittstellen zu Formhandler Zunächst beeinflusst FormhandlerGui Formhandler insofern, dass es das Backend-Modul zur Auswertung von Formulardaten deaktiviert und das eigene Modul unter demselben Namen registriert. Damit die Einstellungen, die im Backend-Modul für Formulare und Formularfelder getroffen wurden, an Formhandler weitergegeben werden können sind zwei Schnittstellen nötig. Diese betreffen die Konfiguration des Plugins im Backend und die Frontend-Ausgabe. Die erste Schnittstelle zu Formhandler dient dazu, dass dem Nutzer in den Einstellungen für das FrontendPlugin-Inhaltselement die Formulare aus der FormhandlerGui-Tabelle als vordefinierte Formulare angezeigt werden. Das Plugin von Formhandler wird einer Seite im Backend als PluginInhaltselement hinzugefügt und auf FlexForm-Basis konfiguriert werden. Eine der Parameter, die dabei bearbeitet werden können, ist das vordefinierte Formular. Vordefinierte Formulare müssen standardmäßig im TypoScript-Setup eines Template-Datensatzes konfiguriert werden, damit Formhandler diese erkennen kann. Dies ist möglich, da in der FlexForm-Datenstruktur des Plugins für das Auswahlfeld der vordefinierten Formulare eine Funktion zur Erzeugung der Auswahloptionen definiert ist: <predefined> <TCEforms> <label>[…]/locallang_tca.xml:[…]predefined</label> <config> <type>select</type> <itemsProcFunc>tx_dynaflex_formhandler>addFields_predefined</itemsProcFunc> <maxitems>1</maxitems> <size>1</size> <multiple>0</multiple> </config> </TCEforms> </predefined> In dieser Funktion parst Formhandler das gesamte TypoScript-Setup der Website und extrahiert daraus die vordefinierten Formulare. Dies ist die Stelle, die von FormhandlerGui genutzt wird, um Formulare aus den Formulardatensätzen in der Plugin-Konfiguration verfügbar zu machen. Dabei wird ein Hook genutzt, der vom FlexForm-Parser bereitgestellt und aufgerufen wird, wenn dieser die XML-Struktur in ein Array umgewandelt hat. Dabei wird der Hook-Methode der Aufbau des FlexForms als Referenz übergeben. In der Methode, die FormhandlerGui für diesen Hook registriert, wird dieses Array auf das Vorkommen der von Formhandler definierten Methode zur Erstellung der Formular-Auswahloptionen untersucht. Wird diese gefunden, wird sie wiederrum mit einer eigenen Methode ersetzt, die die Formulare aus der Datenbank abruft und als Auswahloptionen zurückgibt. Die zweite Schnittstelle dient dazu, die Konfiguration der Formulare aus der FormhandlerGuiTabelle an das Formhandler-Plugin zu übergeben. Dazu muss die Klasse, die für das FrontendPlugin von Formhandler eingebunden wird, überschrieben werden. Frontend-Plugins werden in der Regel mit dem Befehl t3lib_extMgm::addPItoST43() in der ext_tables.php der Erweiterung 39 registriert. Diese Funktion fügt dem TS-Setup der Website im Falle von Formhandler u.a. folgendes TypoScript hinzu: plugin.tx_formhandler = USER_INT plugin.tx_formhandler { includeLibs.tx_formhandler = EXT:formhandler/pi/class.tx_formhandler.php userFunc = tx_formhandler->main } tt_content.formhandler = < plugin.tx_formhandler Da FormhandlerGui aufgrund der alphabetischen Reihenfolge stets nach Formhandler geladen wird, kann dieses Setup in der ext_tables.php von FormhandlerGui auf folgende Weise überschrieben werden: t3lib_extMgm::addTypoScriptSetup( 'plugin.tx_formhandler.includeLibs = EXT:formhandlergui/pi/class.tx_formhandler.php'); Wichtig ist dabei, dass Dateinamen und das Verzeichnis relativ zum Wurzelverzeichnis der Erweiterung denen von Formhandler entsprechen, da diese von TYPO3 vor dem Aufruf der Klasse im Frontend auf richtige Namensgebung getestet werden. Nun, da die Plugin-Klasse von FormhandlerGui anstatt der von Formhandler ausgeführt wird, kann in deren main-Methode das TypoScript-Setup für die vordefinierten Formulare manipuliert bzw. erzeugt und anschließend an die main-Methode von Formhandler übergeben werden. Die Erzeugung der Konfiguration geschieht durch die schrittweise Auswertung des im Plugin eingestellten vordefinierten Formulardatensatzes und dessen Felddatensätzen. Die Feldtypen spielen dabei eine entscheidende Rolle, da sie die Templates der Felder und die Methoden, diese zu verarbeiten, bereitstellen. Voraussetzung dafür ist, dass die Klassen der Feldtypen ausschließlich als SingletonKlassen instanziiert werden. Dies bedeutet, dass es für eine solche Klasse nur eine Instanz geben darf. Die Instanzen werden dafür über den Komponenten Manager verwaltet. Zunächst werden den Feldtyp-Klasseninstanzen nacheinander deren Konfigurationen aus den FlexForm-Feldern lang_conf und field_conf als Argumente für deren init-Methode übergeben. Anschließend werden ebenfalls nacheinander die Methoden zur Felderstellung aufgerufen. Den Klassen stehen dabei zwei Singleton-Instanzen zur Verfügung, denen sie Konfigurationen und Template-Teile für Formhandler hinzufügen können. 4.2.5 ExtBase und FLUID – Die Brücke zu FLOW3 PHP-Frameworks wie Zend Framework, Symfony oder CakePHP mit Implementierung moderner Standards wie MVC, Scaffolding, Extreme Programming (XP) bzw. Agiler Softwareentwicklung etc. gewinnen in der Softwareentwicklung mit PHP zunehmend an Bedeutung. Besonders die Softwareentwicklung mit Hilfe von Skeletons (Grundgerüste für Klassen und Dateien wie z.B. Controller) und Scaffolding können die Arbeit für Entwickler wesentlich vereinfachen und Produktionskosten senken. Scaffolding ist eine Technik, die durch das Webframework Ruby on Rails bekannt wurde und eine Methode für die automatisierte Erzeugung sogenannter CRUD- 40 Administrationsoberflächen 41 aus Models bietet. Weiterhin bieten diese Frameworks in Kombination mit den neuen Klassenfunktionen in PHP 5 mit Hilfe von abstrakten und InterfaceKlassen und Namensräumen (Namespaces) konsistente Arbeitsabläufe und Strukturen bei der Entwicklung.42 Da TYPO3 wie viele freie Systeme mit API als Anwendungs-Framework verstanden werden kann, beschlossen die TYPO3-Kernentwickler 2008 die Entwicklung eines von TYPO3 unabhängigen eigenständigen Anwendungs-Frameworks. Unter dem Namen FLOW3 kommt dieses mit vielen neuen Funktionen und Ansätzen wie z.B. dem Domain Driven Design 43 und einer eigenen Template Engine namens Fluid daher. Momentan befindet sich FLOW3 im Alpha-Status44 (Alpha4). Es ist zu erwarten, dass FLOW3 für viele PHP-Entwickler eine starke Alternative zu den etablierten Frameworks darstellen wird, da es diesen v.a. eines voraus haben wird: Die Möglichkeit eines der größten ECMS auf dem Open-Source-Markt in Form von TYPO3 v5 als Paket in ein FLOW3-Projekt zu integrieren. Die Entwicklung dafür ist in vollem Gange und erste Ergebnisse der Arbeit der Entwickler sind bereits in der kommenden Version 4.3 von TYPO3 enthalten, die sich momentan in der Alpha-Phase (Alpha-3) befindet und deren finale Version für Oktober 2009 erwartet wird: Die Möglichkeit, Erweiterungen im Stil von FLOW3- bzw. TYPO3-v5Paketen für TYPO3 4.3 und folgende zu entwickeln und die neue Template Engine FLUID einzusetzen. Diese Möglichkeit wird, wie in TYPO3 üblich, durch eine Erweiterung bereitgestellt, die sich ExtBase nennt und die bisherige Erweiterungs-Entwicklung mit der pi_base-Klasse des t3lib_div-API erneuern soll. Das folgende Beispiel zeigt kurz, wie die zukünftige Arbeit mit Extbase ablaufen kann: class BeispielController extends ActionController { public function indexAction() { $this->view->assign('beispielArray', array('wert1','wert2')); } } Die zugehörige View ist eine HTML- bzw. XML-Datei, die von der Template-Engine FLUID gerendert wird und im folgenden Beispiel mit Hilfe des foreach-View-Helfers im XML-Namespace f eine Liste mit den Werten des Arrays erzeugt: <ul> <f:for each="{beispielArray}" as="beispielWert"> <li>{beispielWert}</li> </f:for> </ul> Aufgrund der Möglichkeiten, die diese Erweiterung bietet, wurde für die Entwicklung der Formular-Erweiterung eine Implementierung auf Basis von ExtBase angestrebt. Besonders interessant war dabei die Möglichkeit, Templates nicht auf herkömmlichem Weg mit Platzhaltern zu füllen, sondern mit der neuen Template-Engine FLUID Anwendungslogik in Form von View41 Engl. Abk. für Create, Read, Update, Delete Vgl. Schmidt 2009 – PHP design patterns, S.5 ff. 43 Sehr abstrahiert: „[…]eine natürlich anmutende Konzentration auf das Wesentliche: den Nutzen für den Auftraggeber.“ (Rau 2009 – Die Zukunft der Extension-Entwicklung) 44 Nähere Informationen auf der Roadmap der TYPO3 Association: http://typo3.org/development/roadmap/ 42 41 Helfern direkt im Template zu nutzen. Allerdings stellte sich nach längerer Beobachtung der Entwicklung heraus, dass die Anzahl der verfügbaren View-Helfer noch stark begrenzt ist und die Verwendung der neuen Architekturen und Paradigmen zwar für Frontend-Plugins, nicht aber direkt für Backend-Module möglich ist. Da die Formularerweiterung allerdings nur ein FrontendPlugin besitzt, um Konfigurationen an Formhandler weiterzugeben, kann kaum von den Vorzügen von ExtBase profitiert werden. Ein weiterer Grund für die Entscheidung gegen ExtBase war zudem, dass Erweiterungen auf ExtBase-Basis derzeit nicht kompatibel mit älteren TYPO3Versionen sind. Um dennoch eine zukunftsfähige Architektur der Erweiterung zu realisieren, wurde auf eine ältere und wesentlich funktionsärmere Möglichkeit zurückgegriffen. Diese Möglichkeit verbirgt sich unter dem Titel Some backported Aspects of FLOW3 bzw. dem Extension-Key gimmefive im TYPO3 Extension Repository45. Der Kern dieser Erweiterung, der Komponenten-Manager, ermöglicht eine Verzeichnis- und Dateistruktur für Erweiterungen, die der von FLOW3-Paketen entspricht, nutzt die Autoload-Funktion der StandardPHPLibrary46, mit der Klassen instanziiert werden können ohne vorher die Dateien mit der Definition einzubinden und bietet eine Autowire-Funktion, die Argumente von Konstruktormethoden so geladener Klassen erkennen und anhand des geforderten Variablentyps automatisch füllen können. Dieser Komponenten-Manager kann als eigenständige Bibliothek in eigene Erweiterungen eingebunden werden, was den Vorteil hat, dass die Erweiterungen, die diesen nutzen, nicht von gimmefive abhängig sind. Der Nachteil dabei ist, dass die abstrakten Klassen für Controller- und View-Klassen sowie der Dispatcher selbst geschrieben werden müssen. Diese Unannehmlichkeit hat allerdings den Vorteil der Flexibilität, die im Falle der Formularerweiterung genutzt wurde: Um ähnlich wie in FLOW3 und ExtBase Variablen an die View übergeben zu können und keine View-Klassen zum Füllen von Platzhaltern schreiben zu müssen, wurde eine eigene View-Render-Methode geschrieben, die die Verwendung von View-Variablen wie in Zend Framework erlaubt. In diesem sind an die View übergebene Variablen in View-Dateien als normale PHP-Variablen und View-Helfer über das $this-Objekt verfügbar. Die eigene Render-Methode verwendet zwar einen wesentlich einfacheren Mechanismus als Zend Framework, um die Variablen in der View verfügbar machen, hat jedoch einen ähnlichen Effekt: <?php class Tx_FormhandlerGui_View_Renderer extends Tx_FormhandlerGui_View_Helpers { public function render($templateFile, $vars=array()) { extract($vars); ob_start(); include_once($templateFile); $templateContent = ob_get_contents(); ob_end_clean(); return $templateContent; } } 45 46 URL: http://typo3.org/extensions/repository/view/gimmefive/current/ URL: http://de3.php.net/spl 42 Die obige Klasse wird von der eigentlichen View-Klasse, an die Variablen aus dem Controller mittels assign übergeben wurden, aufgerufen. Letztere verwaltet die zugewiesenen Variablen in einem Array, das in der Render-Methode extrahiert wird. Die PHP-Funktion extract versucht aus der ersten Ebene eines assoziativen Arrays Variablen mit den Namen der Schlüssel der ArrayElemente zu erzeugen. Aus $vars[‘variable‘] wird somit $variable. Diese Variablen stehen dann im Template-Script zur Verfügung. Da die Render-Klasse eine Klasse mit View-Helper-Methoden erweitert, können öffentliche Methoden aus dieser wie in Zend Framework als View-Helfer über das $this-Objekt aufgerufen werden. Die Render-Methode steht den View-Scripts dabei auf die gleiche Weise zur Verfügung und ermöglicht auch das Rendern anderer View-Scripts im Template. Damit wurden zwei MVC-Paradigmen umgesetzt, die auf ähnliche Weise auch in ExtBase und FLUID Anwendung finden: Die klare Trennung zwischen Controller und View und die Möglichkeit, Anwendungslogik in View-Scripts zu nutzen. Der einzige Unterschied bei der Anwendung besteht darin, dass FLUID-Templates von FLUID gerendert werden und die Variablen und View-Helfer von der Template-Engine selbst gefüllt bzw. kompiliert werden während View-Scripts in der eigenen Variante PHP als Sprache verwenden. Dies birgt zwar das Risiko, dass View-Scripts zu Ausnahmen und Abbrüchen führen können, bietet allerdings den Funktionsumfang von PHP, der in Zukunft in den View-Scripts durch FLUID-Syntax ersetzt werden kann. Die Brücke, die so geschlagen wird an folgender Adaption der obigen ExtBase-Beispiele bzw. deren Ähnlichkeit deutlich: class Tx_FormhandlerGui_Controller_Forms extends Tx_FormhandlerGui_AbstractController { public function indexAction() { $this->view->assign('beispielArray', array('wert1','wert2')); } } Das zugehörige View-Script, das zusätzlich den Einsatz des View-Helfers translate, der in der Klasse Tx_FormhandlerGui_View_Helpers definiert ist, zeigt: <ul> <?php foreach ($beispielArray as $beispiel) { echo '<li>'.$this->translate($beispiel).'</li>'; } ?> </ul> Den Controller-Klassen werden über die Abstraktionsklasse einige Helfer zur Verfügung gestellt, die diesen Einfluss auf die Ablaufsteuerung des Render-Prozesses erlauben. Die wichtigsten dieser Methoden sind _forward und _redirect, mit denen der Controller auf andere Aktionen und Controller als den aktuellen weiter- bzw. umleiten kann. Außerdem kann im Controller das automatische Rendern der View aus dem Dispatch-Prozess heraus unterbunden werden. Damit können die Controller selbst entscheiden, was und wann gerendert wird. Dies ermöglicht, die Controller-Klassen auch unabhängig vom Dispatcher einzusetzen. 43 5 Auswertung 5.1 Zusammenfassung In der vorliegenden Arbeit wurden die wichtigsten Aspekte der Erweiterungsentwicklung mit TYPO3 herausgestellt. Bei der für neu zu entwickelnde Erweiterungen nahezu obligatorischen Recherche stellte sich heraus, dass bereits zwei Erweiterungen veröffentlicht wurden, deren Funktionsumfang mit dem geforderten mehr oder minder stark korreliert. Nach eingehender Analyse der Erweiterungen wurde Formhandler als gute Grundlage für eine neue Erweiterung herausgestellt. Der Hauptgrund dafür ist neben dem großen Funktionsumfang, dass Formhandler ausschließlich über TypoScript und HTML-Templates konfiguriert wird. Damit war es dem Autor möglich, sich hauptsächlich auf die Backend-Funktionalitäten der neuen Erweiterung FormhandlerGui zu konzentrieren und Formhandler die Steuerung im Frontend zu überlassen. Für die Verwaltung und Speicherung von Formularen und Feldern in der Datenbank musste dank der sehr umfangreichen TYPO3-Tabellenfunktion keine neue Struktur sondern lediglich jeweils eine Tabelle im TCA definiert werden. Die Verwaltung der Daten kann so vollständig durch TYPO3 übernommen werden, was neben weniger Zeit- und Arbeitsaufwand v.a. höhere Sicherheit und deutlich mehr Funktionen wie z.B. gruppenbasierte Bearbeitungsrechte oder Versionierung mit sich bringt. In der Erweiterung selbst sind damit lediglich drei Datenbankabfragen notwendig: Eine Abfrage, die die vorhandenen Formulare zur Anzeige im Formhandler-Plugin-Backend-Formular abruft und zwei zum Abrufen des darzustellenden Formulardatensatzes und der zugehörigen Felder für das Frontend. Das Aufsetzen auf Formhandler und die vollständige Integration in die TYPO3-WorkflowUmgebung erlaubte es, den Fokus auf Zukunftsfähigkeit und die Umsetzung moderner Programmierstandards wie der MVC-Architektur zu setzen. Als große Schwierigkeit bei der Konzeption der Erweiterung stellte sich heraus, dass mit ExtBase zwar theoretisch ein modernes MVC-Framework für TYPO3-Erweiterungen existiert, diese jedoch noch nicht final veröffentlicht wurde. Es fiel dabei besonders schwer abzuschätzen, wann mit einer stabilen Version von TYPO3 4.3 gerechnet werden kann und damit, ob diese für die Entwicklung der Erweiterung herangezogen werden könnte. Letztlich zeigte sich jedoch, dass auch nach inzwischen über einem Jahr Entwicklungszeit noch nicht mit einer stabilen Version gerechnet werden kann. Zudem war nicht klar, ob die sonst für TYPO3 bekannte Abwärtskompatibilität auch mit der neuen Erweiterung ExtBase gewährleistet sein würde. Diese Gründe bedingten letztlich, dass die Erweiterung mit einem Hilfskonstrukt namens gimmefive umgesetzt wurde, womit eine schnelle Integration in ExtBase bei gleichzeitiger Abwärtskompatibilität angestrebt wurde. Dabei wurde versucht, das Zusammenspiel der MVC-Komponenten möglichst ähnlich dem von FLOW3 umzusetzen. Ein Ersatz für die uneffektive Methode, Inhalt über Views, die statische HTMLTemplates mit Platzhaltern füllen, auszugeben, wurde mit der Adaption der aus Zend Framework bekannten ViewScripts geschaffen. Letztlich wurden die Anforderungen an die Erweiterung umgesetzt. Bis zur vollständigen Produktreife wird jedoch noch Zeit benötigt, um weitere Feldtypen hinzuzufügen und die Funktionen ausreichend zu testen. Der Umstand, dass die Erweiterung nicht komplett neu geschrieben wurde, sondern auf Formhandler aufbaut, stellt aus Sicht des Autors eine gute Möglichkeit dar, die Risiken von Fehlfunktionen drastisch zu reduzieren. Dies lässt sich damit begründen, dass Formhandler auf der bewährten und vielfach eingesetzten Erweiterung 44 th_mailformplus (Erstveröffentlichung Dezember 2004) aufsetzt und bei beiden Erweiterungen bereits viele Programmfehler berichtet und behoben wurden. Weiterhin kann davon ausgegangen werden, dass die Nutzer von Formhandler auch FormhandlerGui verwenden werden und Programmfehler berichten können, was bei einer zusätzlichen neuen Erweiterung unwahrscheinlich wäre. Es ist ebenso gut möglich, dass die beiden Erweiterungen Formhandler und FormhandlerGui in naher Zukunft vereinigt werden. 5.2 Ausblick Die entwickelte Erweiterung bietet noch genügend Raum für weitere Funktionen wie der Drag and Drop-Funktionalität für die Anordnung von Feldern oder der manuellen Zuordnung von Formularfeldern zu Datenbankfeldern. Zudem soll es in Zukunft eine Möglichkeit für Administratoren geben, mit FormhandlerGui erstellte Formulare in HTML-Templates, TypoScriptSetup und Sprachdateien exportieren zu können, um diese nach ihren Bedürfnissen anzupassen. Mit Hilfe von Subparts in den HTML-Dateien soll es dabei sogar möglich sein, die exportierten Formulare trotz Anpassungen weiterhin mit FormhandlerGui zu verwalten oder auch komplette Formulare zu importieren. Desweiteren soll die Erweiterung als erste Formularerweiterung, die ExtBase und FLUID nutzt, veröffentlicht werden. Dazu sind allerdings trotz der Entwicklung unter diesem Aspekt mit hoher Wahrscheinlichkeit noch einige Anpassungen an der Erweiterung notwendig. Dennoch wird die Adaption für ExtBase durch die an FLOW3 angelehnte Architektur für FormhandlerGui und Formhandler wesentlich schneller möglich sein, als im Falle von Powermail. Falls FormhandlerGui nicht ohnehin mit Formhandler vereint wird, wird FormhandlerGui möglicherweise auch vermehrt Gebrauch von den Erweiterungsmöglichkeiten von Formhandler machen, um dieses um neue Funktionen wie bspw. die Verwendung der Akismet-Antispam-Technologie zu erweitern. Zusammenfassend kann davon ausgegangen werden, dass die Entwicklung an FormhandlerGui noch nicht abgeschlossen ist sondern noch einige Verbesserungen folgen werden. 45 6 Literaturverzeichnis Altmann, Werner; Fritz, René; Hinderink, Daniel (2004): TYPO3. Enterprise content management. München: Open Source Press. Apache Tutorial: .htaccess files - Apache HTTP Server (2009). Online verfügbar unter http://httpd.apache.org/docs/2.2/howto/htaccess.html, zuletzt aktualisiert am 06.01.2009, zuletzt geprüft am 24.08.2009. Bundesministerium für Wirtschaft und Technologie (Hg.) (2001): Open-Source-Software. Ein Leitfaden für kleine und mittlere Unternehmen. Online verfügbar unter http://ossbroschuere.berlios.de/broschuere/broschuere-de.html#N3185, zuletzt aktualisiert am 1.3.2001. Dulepov, Dmitry; Suter, François (2008): TYPO3 Coding Guidelines. Herausgegeben von TYPO3 Association. Online verfügbar unter http://typo3.org/documentation/document-library/coredocumentation/doc_core_cgl/4.3.0/ter_doc_sxw/?no_cache=1, zuletzt aktualisiert am 03.07.2009, zuletzt geprüft am 14.09.2009. Eilers, Tim; Dambekalns, Karsten: FLOW3 Coding Guidelines on one page. Online verfügbar unter http://flow3.typo3.org/fileadmin/CGL/FLOW3_CGL_on_one_page-v7.pdf. GNU General Public License v2.0 (1991). Herausgegeben von Free Software Foundation. Online verfügbar unter http://www.gnu.org/licenses/gpl-2.0.html, zuletzt geprüft am 09.08.2009. Freytag, Asmus; Scherer, Markus (2008): What is Unicode? in German. Unter Mitarbeit von Otto Schulz. Herausgegeben von Unicode Inc. Online verfügbar unter http://www.unicode.org/standard/translations/german.html, zuletzt aktualisiert am 08.08.2008, zuletzt geprüft am 30.08.2009. Führicht, Reinhard (2009): EXT: Universal Formhandler. Herausgegeben von TYPO3 Association. Online verfügbar unter http://typo3.org/documentation/document-library/extensionmanuals/formhandler/0.9.0/view/. Kellner, Alex; Heißmann, Mischa (2009): powermail. Herausgegeben von TYPO3 Association. Online verfügbar unter http://typo3.org/extensions/repository/view/powermail/current/info/?tx_terfe_pi1%5Bdownloa dFile%5D=doc%252Fmanual.sxw&cHash=3997a6bf70. Koch, Daniel (2006): Mastering Typoscript: Typo3 website, template, and extension development. A complete guide to understanding and using TypoScript, TYPO3's powerful configuration language. Birmingham: Packt Publ. (From technologies to solutions). Lokalisierung (Softwareentwicklung) – Wikipedia (2009). Online verfügbar unter http://de.wikipedia.org/wiki/Lokalisierung_(Softwareentwicklung), zuletzt aktualisiert am 21.08.2009, zuletzt geprüft am 24.08.2009. Peacock, Michael (2007): Building Websites With TYPO3. A practical guide to getting your TYPO3 website up and running fast. 1. publ. Birmingham: Packt Publishing Ltd (From technologies to solutions). Rau, Jochen (2009): Die Zukunft der Extension-Entwicklung. Neues MVC-Framework "Extbase" ebnet den Weg von 4.x zu FLOW3. In: t3n, H. 16, S. 126–129. Ringer, Georg (2009): number of extensions. Email in der TYPO3-dev-Mailingliste. Online verfügbar unter http://lists.netfielders.de/pipermail/typo3-dev/2009-September/036941.html, zuletzt aktualisiert am 11.09.2009. Ripfel, Franz; Meyer, Melanie; Höppner, Irene (2008): Das TYPO3-Profihandbuch. Der Leitfaden für Entwickler und Administratoren zu Version 4.1. München: Addison-Wesley (Open source library). 46 Roos, Michiel (2009): Get into FLOW3 with Extbase. Herausgegeben von TYPO3 Association. Online verfügbar unter http://news.typo3.org/news/article/get-into-flow3-with-extbase/, zuletzt aktualisiert am 19.05.2009, zuletzt geprüft am 09.09.2009. Schmidt, Stephan (2009): PHP design patterns. [Entwurfsmuster für die Praxis]. 2. Aufl., aktuell zu PHP 5.3. Beijing: O'Reilly. Trabold, Christian; Hasenau, Jo; Niederlag, Peter (2009): TYPO3 Kochbuch. [Tipps & Rezepte von TYPO3-Experten ; aktuell zu TYPO3 4.2]. 2. Aufl. Beijing: O'Reilly. Turk, Michael (2008): Caching in TYPO3-Extensions. Flagbit GmbH & Co. KG. Online verfügbar unter http://www.typo3-scout.de/2008/05/29/caching-in-typo3-extensions/, zuletzt aktualisiert am 29.05.2008. TYPO3 Association (Hg.) (2008): Berlin Manifesto. Online verfügbar unter http://typo3.org/development/roadmap/berlin-manifesto/, zuletzt geprüft am 31.08.2009. TYPO3 CMS: Facts and Figures. Online verfügbar unter http://typo3.com/Facts-andFigures.factsandfigures.0.html, zuletzt geprüft am 09.08.2009. TYPO3 Core Development Team (2008): Inside TYPO3. Herausgegeben von TYPO3 Association. Online verfügbar unter http://typo3.org/documentation/document-library/coredocumentation/doc_core_inside/4.2.0/ter_doc_sxw/?no_cache=1, zuletzt aktualisiert am 1.12.2008. TYPO3 Core Development Team (2008): TYPO3 Core API. Herausgegeben von TYPO3 Association. Online verfügbar unter http://typo3.org/documentation/document-library/coredocumentation/doc_core_api/4.2.0/ter_doc_sxw/?no_cache=1, zuletzt aktualisiert am 1.12.2008. Wheeler, David A. (2007): Why Open Source Software / Free Software (OSS/FS, FOSS, or FLOSS)? Look at the Numbers! Online verfügbar unter http://www.dwheeler.com/oss_fs_why.html#forking, zuletzt aktualisiert am 16.04.2007, zuletzt geprüft am 10.09.2009. 47 7 Anhang 7.1 Selbständigkeitserklärung Ich versichere hiermit, dass ich die vorliegende Arbeit selbstständig ohne fremde Hilfe verfasst und keine anderen als die im Literaturverzeichnis angegebenen Quellen benutzt habe. Stellen, die wörtlich oder sinngemäß aus veröffentlichten oder noch nicht veröffentlichten Quellen entnommen sind, sind als solche kenntlich gemacht. Die Zeichnungen oder Abbildungen in dieser Arbeit sind von mir selbst erstellt worden oder mit einem entsprechenden Quellennachweis versehen. Diese Arbeit ist in gleicher oder ähnlicher Form noch bei keiner anderen Prüfungsbehörde eingereicht worden. _____________________________________________________ Datum, Unterschrift Studierender 48 7.2 Quellcodes 7.2.1 tca.php <?php if (!defined ('TYPO3_MODE')) die ('Access denied.'); include_once(t3lib_extMgm::extPath('formhandlergui') . '/Resources/Classes/class.tx_formhandlergui_tca.php'); $TCA['tx_formhandlergui_forms'] = array ( 'ctrl' => $TCA['tx_formhandlergui_forms']['ctrl'], 'interface' => array ( 'showRecordFieldList' => 'hidden,fe_group,title,type,method,prefix,enable_email,enable_db,debug,ro ws,cols,fields' ), 'feInterface' => $TCA['tx_formhandlergui_forms']['feInterface'], 'columns' => array ( 'hidden' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden', 'config' => array ( 'type' => 'check', 'default' => '0' ) ), 'fe_group' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.fe_group', 'config' => array ( 'type' => 'select', 'size' => 5, 'items' => array ( array('', 0), array('LLL:EXT:lang/locallang_general.xml:LGL.hide_at_login', -1), array('LLL:EXT:lang/locallang_general.xml:LGL.any_login', -2), array('LLL:EXT:lang/locallang_general.xml:LGL.usergroups', '--div-') ), 'exclusiveKeys' => '-1,-2', 'foreign_table' => 'fe_groups' ) ), 'title' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.title', 'config' => array ( 'type' => 'input', 'size' => '30', 'eval' => 'required', ) ), 'type' => array ( 'exclude' => 1, 49 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.type', 'config' => array ( 'type' => 'select', 'items' => array ( array('LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:t x_formhandlergui_forms.type.I.0', '0'), array('LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:t x_formhandlergui_forms.type.I.1', '1'), ), 'default' => '0', 'size' => 1, 'maxitems' => 1, ) ), 'method' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.method', 'config' => array ( 'type' => 'select', 'items' => array ( array('LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:t x_formhandlergui_forms.method.I.0', '0'), array('LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:t x_formhandlergui_forms.method.I.1', '1'), ), 'size' => 1, 'maxitems' => 1, ) ), 'prefix' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.prefix', 'config' => array ( 'type' => 'input', 'size' => '10', ) ), 'enable_email' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.enable_email', 'config' => array ( 'type' => 'check', ) ), 'enable_db' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.enable_db', 'config' => array ( 50 'type' => 'check', ) ), 'debug' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.debug', 'config' => array ( 'type' => 'check', ) ), 'rows' => array( 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.rows', 'config' => array ( 'type' => 'user', 'userFunc' => 'tx_formhandlergui_tca->rows' ) ), 'cols' => array( 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.cols', 'config' => array ( 'type' => 'user', 'userFunc' => 'tx_formhandlergui_tca->cols' ) ), 'fields' => array( 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.fields', 'config' => array ( 'type' => 'select', 'foreign_table' => 'tx_formhandlergui_fields', 'foreign_table_where' => 'ORDER BY tx_formhandlergui_fields.field_label', 'size' => 6, 'minitems' => 0, 'maxitems' => 100, 'wizards' => array( '_PADDING' => 2, '_VERTICAL' => 1, 'add' => array( 'type' => 'popup', 'title' => 'Create new record', 'icon' => 'add.gif', 'params' => array( 'table' => 'tx_formhandlergui_fields', 'setValue' => 'prepend', ), 'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1', 'script' => 'EXT:formhandlergui/mod/wizard_add.php', ), 'list' => array( 'type' => 'script', 'title' => 'List', 51 'icon' => 'list.gif', 'params' => array( 'table' => 'tx_formhandlerdev_fields', 'pid' => '###CURRENT_PID###', ), 'script' => 'wizard_list.php', ), 'edit' => array( 'type' => 'popup', 'title' 'script' => 'Edit', => 'wizard_edit.php', 'popup_onlyOpenIfSelected' => 1, 'icon' => 'edit2.gif', 'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1', ), ), ) ), 'multistep_forms' => array ( 'exclude' => 0, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.multistep_forms', 'config' => array ( 'type' => 'group', 'internal_type' => 'db', 'allowed' => 'tx_formhandlergui_forms', 'size' => 5, 'minitems' => 0, 'maxitems' => 100, ) ), 'tables' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.tables', 'config' => array ( 'type' => 'select', 'itemsProcFunc' => 'tx_formhandlergui_tca>tableSelect', 'size' => 10, 'maxitems' => 10, ) ), 'auto_mapping' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.auto_mapping', 'config' => array ( 'type' => 'check', 'default' => 1 ) ), 'mapping' => array ( 'config' => array ( 52 'type' => 'passthrough', ) ), 'email_conf' => array ( 'exclude' => 0, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.email_conf', 'config' => array ( 'type' => 'flex', 'ds' => array ( 'default' => 'FILE:EXT:formhandlergui/Resources/Flex/email_conf.xml', ), ) ) ), 'types' => array ( '0' => array('showitem' => ' hidden;;1;;1-1-1, title;;2;;2-2-2, enable_email, enable_db, debug, --div-;LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.tabs.fields, fields'), '1' => array('showitem' => ' hidden;;1;;1-1-1, title;;2;;2-2-2, multistep_forms, enable_email, enable_db, debug'), '0-db' => array('showitem' => ', --div-;LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.tabs.db, tables;;;;1-1-1, auto_mapping;;;;2-2-2'), '0-email' => array('showitem' => ', --div-;LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_forms.tabs.email, email_conf;;;;1-1-1 ') ), 'palettes' => array ( '1' => array('showitem' => 'fe_group'), '2' => array('showitem' => 'type,method,prefix','canNotCollapse' => 1), '3' => array('showitem' => 'auto_mapping','canNotCollapse' => 1) ) ); $TCA['tx_formhandlergui_forms']['types']['0']['showitem'] .= $TCA['tx_formhandlergui_forms']['types']['0-db']['showitem']; $TCA['tx_formhandlergui_forms']['types']['1']['showitem'] .= $TCA['tx_formhandlergui_forms']['types']['0-db']['showitem']; $TCA['tx_formhandlergui_forms']['types']['0']['showitem'] .= $TCA['tx_formhandlergui_forms']['types']['0-email']['showitem']; $TCA['tx_formhandlergui_forms']['types']['1']['showitem'] .= $TCA['tx_formhandlergui_forms']['types']['0-email']['showitem']; $TCA['tx_formhandlergui_fields'] = array ( 'ctrl' => $TCA['tx_formhandlergui_fields']['ctrl'], 'interface' => array ( 53 'showRecordFieldList' => 'sys_language_uid,l10n_parent,l10n_diffsource,hidden,fe_group,field_type, field_label,validators' ), 'feInterface' => $TCA['tx_formhandlergui_fields']['feInterface'], 'columns' => array ( 'sys_language_uid' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.language', 'config' => array ( 'type' => 'select', 'foreign_table' => 'sys_language', 'foreign_table_where' => 'ORDER BY sys_language.title', 'items' => array( array('LLL:EXT:lang/locallang_general.xml:LGL.allLanguages', -1), array('LLL:EXT:lang/locallang_general.xml:LGL.default_value', 0) ) ) ), 'l10n_parent' => array ( 'displayCond' => 'FIELD:sys_language_uid:>:0', 'exclude' => 1, 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.l18n_parent', 'config' => array ( 'type' => 'select', 'items' => array ( array('', 0), ), 'foreign_table' => 'tx_formhandlerdev_fields', 'foreign_table_where' => 'AND tx_formhandlerdev_fields.pid=###CURRENT_PID### AND tx_formhandlerdev_fields.sys_language_uid IN (-1,0)', ) ), 'l10n_diffsource' => array ( 'config' => array ( 'type' => 'passthrough' ) ), 'hidden' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden', 'config' => array ( 'type' => 'check', 'default' => '0' ) ), 'fe_group' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.fe_group', 'config' => array ( 'type' => 'select', 'size' => 5, 'items' => array ( 54 array('', 0), array('LLL:EXT:lang/locallang_general.xml:LGL.hide_at_login', -1), array('LLL:EXT:lang/locallang_general.xml:LGL.any_login', -2), array('LLL:EXT:lang/locallang_general.xml:LGL.usergroups', '--div-') ), 'exclusiveKeys' => '-1,-2', 'foreign_table' => 'fe_groups' ) ), 'field_type' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_fields.field_type', 'config' => array ( 'type' => 'select', 'items' => array ( array('LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:t x_formhandlergui_fields.field_type.I.0', '0'), ), 'itemsProcFunc' => 'tx_formhandlergui_tca>fieldTypeSelect', 'size' => 1, 'maxitems' => 1, ) ), 'field_title' => array ( 'exclude' => 0, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_fields.title', 'config' => array ( 'type' => 'input', 'size' => '30', ) ), 'field_label' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_fields.label', 'config' => array ( 'type' => 'input', 'size' => '30', 'eval' => 'nospace', ) ), 'lang_conf' => array ( 'exclude' => 0, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_fields.lang_conf', 'config' => array ( 'type' => 'flex', 'ds_pointerField' => 'field_type', 'ds' => array ( 55 '0' => 'FILE:EXT:formhandler_dev/flexform_tx_formhandlerdev_fields_field_opt.xml ', ), ) ), 'field_conf' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_fields.field_conf', 'config' => array ( 'type' => 'flex', 'ds_pointerField' => 'field_type', 'ds' => array ( '0' => 'FILE:EXT:formhandler_dev/flexform_tx_formhandlerdev_fields_field_opt.xml ', ), ) ), 'validators' => array ( 'exclude' => 1, 'label' => 'LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_fields.validators', 'config' => array ( 'type' => 'select', 'items' => array ( array('LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:t x_formhandlergui_fields.validators.I.0', '0'), ), 'size' => 5, 'maxitems' => 20, ) ), ), 'types' => array ( '0' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden, field_type, field_title;;;;2-2-2, field_label;;;;3-3-3'), '0-langConf' => array('showitem' => ', --div-;LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_fields.tabs.lang_conf, lang_conf'), '0-fieldConf' => array('showitem' => ', --div-;LLL:EXT:formhandlergui/Resources/Language/locallang_db.xml:tx_formhandle rgui_fields.tabs.field_conf, field_conf'), '0-access' => array('showitem' => ', --div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.access, fe_group') ), 'palettes' => array ( '1' => array('showitem' => 'field_title','canNotCollapse' => 1), '2' => array('showitem' => 'lang_conf','canNotCollapse' => 1), '3' => array('showitem' => 'field_conf','canNotCollapse' => 1) ) ); tx_formhandlergui_tca::addFieldTypes2TCA($TCA['tx_formhandlergui_fields'] ); ?>