1. Kapitel 1 - Einleitung

1.1. An wen sich dieses Buch richtet

Das Entwicklerhandbuch richtet sich primär an PHP-Entwickler, die das Clansuite CMS und das Clansuite Framework erweitern und eigene Module schreiben wollen. Sekundär richtet es sich aber auch an Administratoren, die das Clansuite CMS bereits einsetzen und nun den Schritt wagen wollen, Clansuite noch besser an eigene Bedürfnisse anzupassen.

Das Buch erklärt, wie Sie eine lokale Entwicklungsumgebung für Clansuite einrichten und welche Werkzeuge und Hilfsmittel Sie zum erfolgreichen Entwickeln benötigen. Neben einer ausführlichen Beschreibung aller Komponenten des Clansuite Frameworks und einer Erläuterung des Aufbaus des Clansuite CMS werden auch alle technischen Standards und Entwurfsmuster des Systems erklärt. Die Plugin- und Modulentwicklung wird jeweils anhand eines Beispiels Schritt für Schritt nachvollziehbar dargestellt.

Kurzum: Das Buch ist Pflichtstoff für diejenigen, die Clansuite-Core oder Modulentwickler werden wollen.

Das Clansuite-Projekt lebt davon, dass Entwickler ihre Zeit, Ihr Können und Ihr Wissen dem Projekt widmen. Mit dem Entwicklerhandbuch hoffe ich, das notwendige Entwicklerwissen aus erster Hand weitergeben zu können, um mit und für Clansuite zu entwickeln.

1.2. Inhalt und Aufbau des Entwicklerhandbuchs

Inhalt und Aufbau des Entwicklerhandbuchs
Kapitel 1 - Einleitung

Einführende Worte zu Inhalt und Struktur des Entwicklerhandbuchs. Zugleich ein Projektüberblick aus Entwicklersicht.

Kapitel 2 - Die Projektorganisation

In diesem Kapitel wird die Organisationsstruktur des Projekts besprochen, sowie Grundprinzipien und Spielregeln für die Zusammenarbeit der Entwickler dargelegt.

Kapitel 3 - Der Einstieg in die Clansuite Entwicklung

Beschrieben wird, wie man einen Webserver einrichtet, den Quellcode von Clansuite bezieht und eine lokale Entwicklungsumgebung für die Programmierung von Clansuite einrichtet.

Kapitel 4 - Grundlegende Orientierung und Verzeichnisübersicht

Allgemeine Übersicht und Verzeichnisstruktur von Clansuite.

Kapitel 5 - Das Framework und die einzelnen Core-Komponenten

Erläuterung der MVC-Architektur und der einzelnen Bestandteile des Frameworks. Definitionen und Erklärungen zu den verwendeten Entwurfsmustern.

Kapitel 6 - Die Konfigurationseinstellungen

Überblick über die Konstanten, Systemvariablen und Einstellungen.

Kapitel 7 - Der Modulaufbau

Beschreibung des Modulaufbaus, sowie der automatischen und manuellen Modulerstellung.

Kapitel 8 - Der View - von Render-Engines, Themes und Templates

Zunächst werden das Clansuite Theme-System und die einzelnen Render-Engines erklärt. Sodann wird auf den Einsatz und die Erstellung von Templates und Layout-Themes eingegangen.

Kapitel 9 - Die Fehlersuche und die Behandlung von Fehlern und Ausnahmen

Erklärt werden mehrere Methoden für die Fehlersuche (Debugging), sowie die Behandlung von Fehlern und Ausnahmen.

Kapitel 10 - Die Erstellung und der Einsatz von Formularen

Das Kapitel behandelt die Erstellung und den Umgang mit Formularen. Besprochen wird die automatische und manuelle Formularerstellung, sowie die Formularvalidierung.

Kapitel 11 - Überblick über fremde Bibliotheken

Überblick über die fremden Bibliotheken und ihre Einbindung in das CMS. Erklärt werden die Systemschnittstellen unter anderem zu Smarty, Phemto und JQuery.

Kapitel 12 - Die Clansuite Toolbar

Besprochen wird die Installation, Verwendung und Programmierung der Clansuite Toolbar für Mozilla Firefox.

Kapitel 13 - Das Deployment und der Ablauf eines Clansuite Releases

Informationen zum Ablauf der Veröffentlichung von Clansuite.

Kapitel 14 - Testsuite

Erläuterungen zum Testing von Clansuite.

Kapitel 15 - Dokumentation

Information zur Erstellung der Dokumentation von Clansuite

Kapitel 16 - Der Clansuite Webserver

Das Kapitel informiert über die Entwicklung des Clansuite Standalone Webserver Pakets.

Kapitel 17 - Quellcodekonventionen

Das Kapitel informiert über die in diesem Projekt verwendeten Quellcodekonventionen.

Kapitel 18 - Subversion

Das Kapitel erläutert die Verwendung von Subversion eingehend.

Anhang A

Vollständige Lizenztexte der Dokumentation

1.3. Zum Umgang mit dem Buch

1.3.1. Nötige Vorkenntnisse

Das Buch setzt voraus, dass der Leser grundsätzliche Kenntnisse der Programmierung in PHP mitbringt. Clansuite ist eine objektorientierte Software, daher sind Kenntnisse der objektorientierten Programmierung mit PHP wünschenswert, aber nicht zwingende Voraussetzung für das Lesen und Verstehen des Buches.

1.3.2. Zur Lesweise

Man kann dieses Buch sowohl in monochron-linearer Lesart lesen, wobei man sich in der Reihenfolge der Kapitel durch das Buch arbeitet, als auch in polychron-nichtlinearer Lesart, wobei man mehrere Seiten des Entwicklerhandbuchs zeitgleich im Browser aufschlagen und als Referenz und Nachschlagewerk verwenden kann.

1.3.3. Zur Verwendung von deutschen und englischen Fachbegriffen

Das Handbuch verwendet deutsche Fachbegriffe. Bei der ersten Erwähnung eines Fachbegriffs wird der jeweilige englische Fachbegriff angegeben.

1.3.4. Konventionen des Entwicklerhandbuchs

Innerhalb des Buchs werden folgende semantische Auszeichnungen, Texthervorhebungen und Symbole genutzt.

Typographie

Fett Kontextbezogene Hervorhebung. Kursiv Kontextbezogene Hervorhebung.

Darstellung von Quellcode

Quellcode wird in einer eigenen Box dargestellt. Die nicht gedruckte Version des Buches enthält dabei das entsprechende Syntax-Highlighting der jeweiligen Programmiersprache. Auf öffnende und schließende Tokens wird aus Platzgründen verzichtet.

Quellcode Beispiel in der Sprache PHP
echo 'Hallo Welt.';
Anmerkung
Randnotiz
Dies ist eine Randnotiz. Randnotizen sind zumeist kleine Exkurse in verwandte Themen und bieten Hintergrundinformationen.
Tipp Ein Hinweis bzw. Tipp.
Wichtig Wichtige Informationen.
Warnung Warnung vor möglichen Fehlerquellen.
Achtung Vorsicht.

1.4. Warum gibt es das Clansuite Projekt?

"Jede gute Software beginnt mit den persönlichen Sehnsüchten eines Entwicklers."

Die Kathedrale und der Basar (1999)
— Eric S. Raymond

Dieses Zitat von Eric S. Raymond entstammt dem bekannten Essay über Open-Source-Softwareentwicklung "Die Kathedrale und der Basar" (engl. „The Cathedral and the Bazaar“).
[http://gnuwin.epfl.ch/articles/de/Kathedrale/catb_g.2.html, Raymond 1999, Die Kathedrale und der Basar, Kapitel. 2: Post muß immer ankommen]
Das Zitat gibt zutreffend wieder, warum das das Clansuite Projekt existiert. Denn der Ursprung von Clansuite liegt im Bereich der ungelösten Probleme und unbefriedigten Bedürfnisse.

Ausgangspunkt für die Entwicklung von Clansuite war der Einsatz verschiedenster CMS. Viele davon habe ich umfangreich modifiziert, um den administrativen Bedürfnissen unseres eSport-Teams besser zu entsprechen und uns einige Arbeit abzunehmen. Die dabei entstandenen Ideen und nützlichen Funktionen habe ich im Laufe der Zeit an die verschiedenen Clan-CMS Entwicklergemeinschaften herangetragen. Doch diese waren zumeist schlecht organisiert und auf unnötige Dinge festgelegt, während Sie zugleich nicht in der Lage waren, bei der Entwicklung wichtiger Funktionen mitzuhelfen, oder einfachste Benutzerwünsche oder Fragen zu beantworten. Als ich angefangen habe Funktionserweiterungen einzupflegen, habe ich relativ schnell feststellen müssen, dass ich immer im Randbereich arbeitete und die jeweiligen Grenzen des Systems erreichte.

Zu oft fehlten die Wesentliches leistenden Funktionen, während man sich fehlerbehaftete Entwürfe leistete, auf welchen man aufbauen sollte. Einige meiner Ideen konnten nicht so einfach umgesetzt werden, wieder andere landeten viel zu oft in meinem Entwurfsnotizblock. Kurzum, die Unzulänglichkeiten der bestehenden Programme reizten mich als Programmierer.

Am Ende beschloss ich ganz von vorne anzufangen, und ein dem E-Sport gewidmetes CMS zu erstellen.

Clansuite war geboren.

1.5. Was will das Clansuite Projekt eigentlich?

Das Projektziel ist die Entwicklung eines gemeinschaftsgetragenen, freien Content Management Systems basierend auf einem Webanwendungsframework. Dazu setzen wir neueste Internettechnologien ein und konzentrieren uns auf die wesentlichen Verwaltungsbedürfnisse von eSport-Teams. Einfachheit und Handhabbarkeit stehen sowohl für den Nutzer als auch für den Entwickler im Vordergrund.

Wer an dieser Stelle ein großes Leitbild oder ein Corporate Mission Statement amerikanischer Art erwartet ist hier falsch. Um das Ganze in einem kurzen und prägnanten Glaubenssatz zusammenzufassen, können wir nur das Clansuite Projekt Mantra anbieten (und ja, wir kennen Guy Kawasaki).

Wir wollen Folgendes:

Wichtig Clansuite - just an eSports CMS. - Einfach, komfortabel, schnell, flexibel. Ist ein freies, dynamisches und auf einem Framework basierendes Webseitenverwaltungssystem insbesondere für Clans und eSport-Teams basierend auf PHP5+, Doctrine, Smarty, Ajax.

Damit ist alles gesagt.

1.6. Projektüberblick aus Entwicklersicht

Clansuite ist ein einfaches, komfortables, schnelles und flexibles Content Management System. Als Open-Source-Software kann Clansuite ohne Lizenzkosten eingesetzt werden. Im Vergleich zu Konkurrenzsystemen im Marktsegment "Clan und E-Sport CMS" erweist es sich als technisch überlegen. Im Marktsegment "CMS" als leistungsstark und durchsetzungsfähig. Diese Positionierung hat Clansuite der zukunftsgerichteten objektorientierten Softwarearchitektur zu verdanken und einem geordneten Entwicklungsprozess. Die zahlreichen Kommunikationsmittel der Projektinfrastruktur gewährleisten die Anhörung und Einflussnahme der Nutzer und sichern die Weiterentwicklung. Das System ist vom Nutzer an eigene Anforderungen und Bedürfnisse anpassbar und kann nach eigenen Vorstellungen weiterentwickelt werden. Die Nutzung der GNU/GPLv2+ Lizenz erzwingt, dass eigene Weiterentwicklungen wiederum der Gemeinschaft der Clansuite Nutzer zur Verfügung gestellt werden.

Internettechnologien

Clansuite setzt auf neueste Internettechnologien. Eine Aufzählung der Abkürzungen der verschiedenen Sprachen mag verdeutlichen, dass moderne Internetanwendungen immer auf einem Technologiemix basieren: HTML (Hypertext Markup Language), XHTML (Extended Hypertext Markup Language), CSS (Cascading-Style Sheets), XML (Extensible Markup Language), XSLT (XSL Transformations), JS (JavaScript), AJAX (Asynchronous Javascript and XML), PHP (Hypertext Preprocessor). Um mit diesen Basistechnologien auf einfache Weise umgehen zu können, werden zahlreiche lizenz- und technikkompatible Bibliotheken eingesetzt. Sie finden nachfolgend einige Kurzdarstellungen der Technologien. Eine genaue Darstellung aller Bibliotheken finden Sie in Kapitel 11.

PHP 5.2+

Clansuite wird in der serverseitigen Programmiersprache PHP programmiert. Dabei wird gegenwärtig die Version PHP 5.2.3 zugrunde gelegt. PHP steht für "PHP: Hypertext Preprocessor" oder "Personal Home Page Tools". Es ist eine Skriptsprache mit einer an C angelehnten Syntax. Man verwendet sie, um dynamische Webanwendungen zu programmieren. Dynamisch bedeutet dabei, dass die früher statischen Webseiten nun durch Nutzung der Webanwendung direkt verändert werden können. PHP ist Open-Source-Software. Clansuite nutzt die objektorientierten Features dieser Scriptsprache. Zum Einsatz kommen dabei Standardentwurfsmuster der objektorientierten Softwareentwicklung.

Warum PHP?

Für die Entwicklung mit PHP waren die folgenden Dinge ausschlaggebend: PHP ist leicht erlernbar. Die Zugangshürden sind nicht allzu hoch. PHP ist gut dokumentiert. Erstens durch das offizielle PHP-Handbuch
[http://php.net/manual/de/index.php, PHP Handbuch]
, zweitens durch Lehrbücher
[http://www.amazon.de/s/&url=search-alias%3Dstripbooks&field-keywords=php, Amazon PHP Bücher]
und drittens durch zahlreiche kommentierte Anwendungsbeispiele, die im Internet frei verfügbar sind
[http://www.google.com/codesearch?q=lang:php]
. PHP ist Open-Source Software und damit kostenlos verfügbar und einsetzbar. Auch viele kostenlose Webserveranbieter unterstüzten PHP. Es hat eine breite Nutzerbasis, denn die Mehrzahl der dynamischen Internetanwendungen ist in PHP geschrieben. Die Nutzer sind zu dem hochkommunikativ. Dies zeigt sich insbesondere an den zahlreichen Communitytreffen und Konferenzen. PHP ist plattformunabhängig und z. B. nicht auf ein darunterliegendes Framework, wie z. B. Mircososft .NET angewiesen. Die IT-Firmen Yahoo, IBM und Oracle, sowie Mircosoft befürworten und unterstützen PHP. An dieser Stelle sei aber auch auf die alternativen Technologien wie das Microsoft Framework für Active Server Pages (ASP), die von Sun Microsystems entwickelten JavaServerPages (JSP und Servlets) und Adobe Systems Coldfusion sowie Perl und Python (speziell Zope) hingewiesen. Einer Entwicklung mit Coldfusion oder ASP stand der kommerzielle, proprietäre Charakter der Produkte entgegen.

CMS und Framework

Das Clansuite-CMS ist als nutzerfreundliche fertige Anwendung gedacht, die lediglich konfiguriert werden muss. Die Basis des Systems bildet ein objektorientiertes Model-View-Controller-Framework. Ein Framework kann man sich als Werkzeugkiste oder Entwicklungsrahmen vorstellen. Das Model-View-Controller-Konzept ist eine Aneinanderreihung von bestimmten objektorientierten Standardentwurfsmustern um eine Trennung in Applikationsschichten zu erreichen. Die Trennung in Schichten verbessert die Programmierbarkeit des Systems. Mehr dazu erfahren Sie im Kapitel 5, in welchem das Framework ausführlich erläutert wird.

Doctrine (PHP-Bibliothek)

Zur Arbeit mit Datenbanken setzt Clansuite auf die PHP-Bibliothek Doctrine. Es ist ein Werkzeug zur objektrelationalen Abbildung von Daten (engl. object-relational mapping, abgekürzt: ORM). Programmiersprachen kapseln Daten und Verhalten in Objekten, hingegen legen relationale Datenbanken Daten in Tabellen ab. Unter objektrelationaler Abbildung versteht man die Auflösung dieses Strukturwiderspruchs und den Überführungsprozess von Daten aus Objekten in eine relationale, regelmäßig tabellarische Datenstruktur. Doctrine verwendet eine mächtige Datenbankenabstraktionsschicht (engl. database-abstraction layer, abgekürzt: DBAL). Datenbankenabstraktion bedeutet, dass mittels einer Abfragesprache ein breites Spektrum von relationalen Datenbanken, die jeweils eine eigene Abfragesprache haben, abgefragt werden kann. Ein besonderes Merkmal von Doctrine ist, das Datenbankanfragen in einem eigenen Datenbankenabfragedialekt namens Doctrine Query Language (DQL) gestellt werden. Diese Abfragesprache ist SQL-ähnlich und durch den Einsatz verketteter objektorientierter Methoden möglich. Aufgegriffen wird ein Ansatz aus der Java-Welt, nämlich Hibernates HQL. Doctrine bietet eine mächtige Alternative zum standardmäßigen Einsatz von SQL und Flexibilität, ohne das Quellcode unnötig wiederholt werden muss.

Smarty (PHP-Bibliothek)

Smarty ist eine Open-Source Template-Engine für PHP. Im Clansuite Framework stellt sich Smarty als das standardmäßig verwendete Hilfsmittel zur Generierung der Präsentation dar. Smarty ist eine kompilierende Engine. Das bedeutet, das Vorlagedateien nur einmal verarbeitet werden und das erneute Parsen der Vorlagen bei jedem Seitenaufruf vermieden werden kann. Gleichsam unterstützt Smarty das Caching, wodurch die Seitenauslieferung beschleunigt stattfinden kann.

Markupsprachen (XHTML, HTML, CSS)

Die von Clansuite generierten Dokumente setzen verschiedene Markupsprachen, wie HTML und XHTML ein. HTML ist eine Auszeichnungssprache (engl. markup language) und beschreibt die logischen Bestandteile eines Textdokuments. Die Formatierung der Dokumente erfolgt mittels Cascading-Stylesheets (CSS).

Javascript (JS, E4X, jQuery)

Clansuite setzt die clientseitige Scriptsprache JavaScript ein. Seit der JavaScript Version 1.6 enthält JS auch E4X (engl. ECMAScript for XML), welches die Zusammenarbeit von JS mit XML als Datenstruktur vereinfacht. Um die Programmierung zu vereinfachen, verwendet Clansuite die JavaScript-Bibliothek jQuery.

Ajax (Asynchronous JavaScript and XML)

Ajax ist die Abkürzung der Wortfolge „Asynchronous JavaScript and XML“. Entwickelt wurde AJAX ursprünglich, um zu überprüfen, ob ein E-Mail-Postfach neue Post enthält. Es bezeichnet ein Konzept der asynchronen Datenübertragung zwischen einem Server und einem Client. Im Webanwendungsumfeld sind es ein Webserver und der Webbrowser des Clients. Bei der synchronen Datenübertragung wird eine HTTP-Anfrage vom Webbrowser an den Webserver gesendet, woraufhin der Webserver, wenn er über die angefragte Ressource verfügt, einmal mit einer vollständigen Antwortseite antwortet. Mittels asynchroner Datenübertragung ist es möglich HTTP-Anfragen durchzuführen, während ein HTML-Dokument angezeigt wird. Die HTTP-Abfrage erfolgt mittels Javascript, die Antwort mittels XML (häufig auch JSON). Dabei werden lediglich Teile eines Dokuments verändert oder aktualisiert. Die Neuheit besteht darin, dass ein vollständiges Laden der Seite unterbleibt und der Nutzer der Seite, während die Daten vom Server geladen werden, weiter auf der Webseite arbeiten kann, ohne auf die neue Seite warten zu müssen. Die Seiten können auf diese Art dynamisch aktualisiert werden. Daher bezeichnet man Ajax auch als eine Schlüsseltechnik zur Realisierung des Web 2.0.

Open-Source Lizenz GNU/GPLv2+

Das Clansuite CMS/CMF unterliegt der GNU General Public License (GPL) Version 2 und (je nach Wahl) jeder höheren Version. Die GPL ist eine von der Free Software Foundation (FSF) herausgegebene Lizenz. Das Grundanliegen dieses Lizenztyps ist die Sicherung der Freiheit, alle Versionen eines Programms zu teilen und zu verändern. Es besteht ein unentgeltliches einfaches Nutzungsrecht für jedermann. Dabei kommt ein von Richard Stallman als "Copyleft" betiteltes Prinzip zum Einsatz. Copyleft ist ein Copyright, welches den Schutzrechtscharakter quasi umdreht. Statt die Weiterentwicklung eines Softwareprogramms durch starke Schutzrechte zu blockieren und andere von der Weiterentwicklung auszuschließen, stellt das Copyleft-Prinzip die Freiheit eines Programmes beim Lizenznehmer sicher. Die Bindung jedes weiterentwickelnden Autors an diese Lizenz bezeichnet man regelmäßig auch als den "viralen Charakter" der GPL. Clansuite als Werk ist somit nicht gemeinfrei (public domain). Immer ist der ursprüngliche Autor auch der Inhaber der Rechte und der Halter des Copyrights. Der ursprüngliche Autor oder Inhaber abgetretener Rechte kann das Werk auch unter einer beliebigen anderen Lizenz weitergeben. Wer mehr über "Die Definition Freier Software" erfahren möchte, kann den gleichnamigen Artikel
[http://www.gnu.org/philosophy/free-sw.de.html, Die Definition Freier Sofware, Free Software Foundation, 2005.]
der Free Software Foundation lesen.

Open-Source, Basar-Entwicklungsmodell und Transparenzgebot

Es gibt unterschiedliche Entwicklungsmodelle um Open-Source-Programme zu entwickeln.
[http://gnuwin.epfl.ch/articles/de/Kathedrale/]
Für das Clansuite Projekt ist eine transparente Entwicklung ein wichtiger Wert. Seit Anbeginn der Entwicklung folgt das Projekt dem sogenannten "Basar" Entwicklungsmodell. Dabei ist der Quellcode zu jeder Zeit und in jedem Entwicklungsstadium über das Internet verfügbar. Auf diese Art und Weise ist jeder Entwicklungsschritt am Quelltext für jeden Entwickler und Nutzer einfach nachvollziehbar. Dieses Modell hat sich in der Open-Source-Welt als überaus erfolgreich erwiesen und sich gegen das Entwicklungsmodell "Kathedrale" mehrheitlich durchgesetzt. Beim Entwicklungsmodell "Kathedrale" wird kein öffentlich zugängliches Quellcodearchiv geführt und der Quelltext wird solange unter Verschluss gehalten, bis eine neue Version entwickelt wurde. Der Quelltext ist meistens bis zur "closed-beta" und der anschließenden Veröffentlichung nicht einsehbar. Beispielsweise folgen das Webspell Projekt und Clansphere’s Coresphere dem Kathedralen-Entwicklungsmodell.

Open-Source Infrastruktur

Aus dem Transparenzgebot folgt die Transparenz im Hinblick auf die Projektinfrastruktur. Alle eingesetzten Werkzeuge sind Open-Source und ihre Konfigurationsdateien sind öffentlich.

Plattformunabhängig

Clansuite ist plattformunabhängig. Der Nutzer benötigt einen Webbrowser und einen Internetzugang. Der Betreiber benötigt einen Webserver mit MySQL und PHP. Clansuite läuft auf Webservern unter Linux, Solaris, MAC OS X und Windows. Beim Aufsetzen der zum Betrieb erforderlichen Software kann auf kostenlose Webserverstacks (fertige Pakete) zurückgegriffen werden. Die zusätzlich benötigte Software zur Nutzung und Anpassung von Clansuite ist immer auch als Open-Source-Software verfügbar.

Webserverstack für Windows mit vorinstallierter Entwicklerversion

Das Projekt bietet einen eigenen Webserverstack für die Plattform Windows an. Das Clansuite CMS wird hier als Teil eines auf „XAMPP Lite“ basierenden Webserverstacks ausgeliefert. "XAMPP Lite" ist ein verkleinertes Paket des bekannten XAMPP Webservers des Apachefriends Projekts
[http://www.apachefriends.org, Apache Friends Webseite]
. Das Webserverpaket kann kostenlos von unserer Webseite heruntergeladen werden. Er dient Entwicklungszwecken und beinhaltet immer die aktuellste Entwicklerversion aus der Quellcodeverwaltung.

1.7. Urheberrechtshinweis und Lizenzen

Der Autor und damit Urheber des Werks ist Jens-André Koch. Ich stelle dieses Werk unter die Lizenzen GNU Free Documentation License Version 1.3 (GNU-FDL v1.3) und die Creative-Commons Namensnennung-Weitergabe unter gleichen Bedingungen 3.0 (CC-BY-SA v3). Damit biete ich als Urheber jedermann weitgehende Nutzungsrechte an diesem Werk an. Die Lizenzen gestattet die Vervielfältigung, Verbreitung und Veränderung des Werkes, auch zu kommerziellen Zwecken. Im Gegenzug verpflichtet sich der Lizenznehmer zur Einhaltung der Lizenzbedingungen. Diese sehen unter anderem die Pflicht zur Nennung des Autors (Jens-André Koch) oder der Autoren (Jens-André Koch et. al.) vor und verpflichten den Lizenznehmer dazu, abgeleitete Werke unter dieselbe Lizenz zu stellen (Copyleft-Prinzip). Wer sich nicht an die Lizenzbedingungen hält, verliert automatisch die durch die Lizenzen eingeräumten Rechte.

1.8. Haftungsausschluss

Der Autor hat die Dokumentation nach seinem bestem Wissen und mit größtmöglicher Sorgfalt erstellt. Er übernimmt keinerlei Gewähr für die Aktualität, Korrektheit, Vollständigkeit oder Qualität der bereitgestellten Informationen. Falls sich dennoch unvollständige, fehlerhafte, irrtümlich falsche, veraltete oder illegale Informationen eingeschlichen haben, so bitte ich um Entschuldigung und um eine hinweisende Mitteilung. Haftungsansprüche gegen den Autor, welche sich auf Schäden materieller oder ideeller Art beziehen, die durch die Nutzung oder Nichtnutzung der dargebotenen Informationen oder durch die Nutzung fehlerhafter und unvollständiger Informationen verursacht wurden, sind grundsätzlich ausgeschlossen, sofern seitens des Autors kein nachweislich vorsätzliches oder grob fahrlässiges Verschulden vorliegt.

1.9. Verwendung von Markennamen

Die in diesem Werk wiedergegebenen Gebrauchsnamen, Handelsnamen, Warenbezeichnungen und Herstellernamen usw. können auch ohne besondere Kennzeichnung Marken sein und als solche den gesetzlichen Bestimmungen unterliegen.

1.10. Anregung und Kritik

Natürlich gibt es sowohl an der Software als auch an der Dokumentation immer etwas zu verbessern. Für Anregungen und Kritik bin ich dankbar.

Ich bin unter der folgenden Adresse postalisch zu erreichen:

Jens-André Koch
Jahnstraße 36
17033 Neubrandenburg

Ich bin über E-Mail erreichbar unter der Adresse:

jakoch at web dot de

Für Anregung und Kritik steht auch das Forum des Clansuite Projekts zur Verfügung. Sie erreichen es unter der Webadresse http://forum.clansuite.com/.

Herzlichen Dank.

1.11. Danksagung

Zuerst möchte ich mich bei allen Menschen für ihr Verständnis bedanken, denen ich aufgrund meiner Arbeit an Clansuite und an der Dokumentation nicht zur Verfügung stand. Dann möchte ich mich bei denjenigen Menschen bedanken, die mich unterstützt haben und einen Teil des Entwicklungsweges gemeinsam mit mir gegangen sind.

Neubrandenburg und Greifswald im Dezember 2009

Jens-André Koch

2. Kapitel 2 - Die Projektorganisation

Ein Open-Source Projekt, wie das Clansuite Projekt, ist auf eine bestimmte Art und Weise organisiert. Open-Source bedeutet, dass der Quellcode öffentlich einsehbar ist und über die ganze Welt verteilt gleichzeitig entwickelt werden kann. Es bedeutet auch, dass zu jedem Zeitpunkt im Leben des Projekts neue Personen in den Entwicklungsprozess eintreten können. Eine solche verteilte Zusammenarbeit macht ein hohes Maß an Organisation erforderlich. In diesem Kapitel werden daher die Organisationsstruktur und die Kommunikationsmittel vorgestellt, sowie die Grundprinzipien und Spielregeln für die Zusammenarbeit der Entwickler dargelegt.

2.1. Organisationsstruktur

Das Clansuite Projekt hat eine bestimmte Organisationsstruktur und Leitung. Die Organisationsstruktur ergibt sich aus den Spielregeln nach denen die verteilte Zusammenarbeit abläuft. Wer sich als Entwickler an diese Verfahrensweisen hält, trägt dazu bei, dass sich Arbeitsanteile ergänzen und alle von der Arbeitsteilung profitieren können. Wer die Organisation "Clansuite" betrachtet, der wird eine klare Projektleitung erkennen. Aufgabe der Leitung ist es, die wesentlichen Entscheidungen für die Erreichung des Projektziels zu treffen.

Struktur und Kommunikationsmittel
Abbildung 1. Überblick über Struktur und Kommunikationsmittel

2.1.1. Die Projektleitung

Das gegenwärtig gelebte Leitungs- und Führungsmodell ist historisch gewachsen. In den Anfangstagen des Projekts gab es eine Doppelspitze bestehend aus Florian Wolf und Jens-André Koch. Doch die Vergangenheit hat gezeigt, dass das Commitment der Projektbeteiligten von unterschiedlicher Dauer ist, denn die Interessen von Menschen können sich im Laufe der Zeit ändern. Für ein Open-Source Projekt stellen sich diese Ab- und Zugänge von Personal als ein natürlicher Prozess dar. Die Doppelspitze hat sich als zerbrechlich erwiesen und seit dem Projektausstieg von Florian Wolf wird das Clansuite Projekt durch Jens-André Koch geleitet.

Als Projektmanager ist er für die Planung, Kommunikation und Organisation im Projekt zuständig. Zu seinem Aufgabenbereich gehört es, für die entsprechenden Rahmenbedingungen des Projekts zu sorgen und es gegenüber Dritten zu positionieren. Er trägt auch die Verantwortung für die Wahrung der Lizenzkompatibilitäten beim Einsatz fremder Bibliotheken. Als Herausgeber veröffentlicht er Clansuite und die zugehörige Dokumentation.

Im Bereich Open-Source Softwareentwicklung wird der Projektleiter auch Maintainer genannt. Maintainer ist, wer den Quelltext, als ein öffentliches Gut, verwahrt und verwaltet. Aber immer dann, wenn nur einzelne oder eine Handvoll Menschen die Entscheidungen über öffentliche Güter treffen, spricht man im Open-Source Bereich häufiger auch vom gutmütigen oder wohlwollenden Diktator (engl. "Benevolent Dictator for Life", abgekürzt: "BDfl"). Damit wird zumeist der Initiant und Gründer oder derjenige mit führender Stellung im Projekt betitelt.
[Cyberchiefs. Autonomy and Authority in Online Tribes. Mathieu O’Neil. Macmillan/Pluto Press, 2009.]

Dieses Projektleitungsmodell ist in der Open-Source Welt häufig anzutreffen.
[The Success of Open Source. Steven Weber. Harvard University Press, 2005.]
So namhafte Projekte wie Perl (Larry Wall), GNU (Richard Stallman) und der Linux-Kernel (Linus Torvalds) werden nach diesem Modell geführt. Und auch PHP (Rasmus Lerdorf), die Programmiersprache dieses Projekts und viele weitere Internetanwendungen, wie Wikipedia (Jimmy Wales), Drupal (Dries Buytaert), Wordpress (Matt Mullenweg). Es liegt zumeist in der Tatsache begründet, dass die Projekte als Ein-Mann-Show im Bereich Entwicklung und Leitung beginnen und die verantwortungsvolle Übersichtsperspektive des Gründers damit gewahrt wird. Kennzeichnend für dieses Führungsmodell sind ein gemeinschaftstauglicher Führungsstil und ein abschließendes und überstimmendes Veto- und Entscheidungsrecht zumeist auf Lebenszeit.

Natürlich kann es gelegentlich zu heftigen Diskussionen aufgrund dieses Führungsmodells kommen. Für das Clansuite Projekt gelten daher folgende Hinweise: Wer den Diktator kritisieren möchte, weil er denkt, es fehle ihm an Qualität, dem sind die folgenden Persönlichkeitsbeschreibungen zum Gebrauch empfohlen: Arroganz, Willkür, Selbstherrlichkeit, Selbstüberschätzung. Von emotionaler Bepingpongung mit solcherlei Persönlichkeitsmerkmalen hält der Diktator allerdings nicht viel. Er wird den Kritisierenden daher immer höflich auf die Ebene des Sachproblems zurückverweisen oder alternativ mit: "Dann forkt doch einfach!" antworten.

2.1.2. Das Projektsekretariat

Das Projektsekretariat ist die zentrale Anlaufstelle der Projektleitung. Es ist zuständig für die Entlastung des Projektleiters und seine Stellvertretung. Zu den Aufgaben des Projektsekretariats gehören auch die Betreuung und Kommunikation mit Entwicklern und Nutzern. Hierbei steht insbesondere die Organisation von Besprechungen mit den Entwicklern und die Bereitstellung und Pflege der Projektdokumentation, insbesondere ihre Archivierung und Sicherung im Vordergrund. Gegenwärtig werden die Sekretariatsrollen teilweise durch die Moderatoren des Forums, hauptsächlich aber durch den Projektleiter und durch virtuelle Büroräume, beispielsweise die zentrale Einstiegsseite für die Dokumentation, verwirklicht.

2.1.3. Die Entwickler

Entwickler sind eine Voraussetzung für ein gemeinschaftsgetragenes Projekt. Das Projekt ist so konzipiert, dass ein arbeitsteiliges Entwickeln angestrebt ist. Über weite Teile des Entwicklungswegs war und ist dieses Projekt allerdings eine Ein-Mann-Show.

Wie wird man Mitglied des Clansuite Teams?

Es ist nicht schwer Entwickler im Clansuite Entwickler-Team zu werden, man muss nur Mitmachen.

Die Grundvoraussetzung für die Aufnahme ins Team ist die Vorausleistung eines Arbeitsanteils. Diese Voraussetzung ist nicht als Gängelei gemeint. Sie dient dazu, Entwickler zu finden, die ein vernünftiges und ernst gemeintes Commitment im Hinblick auf das Projekt haben. Es geht darum Entwickler zu finden, die sich nicht nur kurzfristig mit den Zielen des Projekts identifizieren können.

Die Aufnahme ins Team erfolgt beispielsweise gegen Vorlage einiger Patches, gegen Einsendung eines oder mehrerer Programmergänzungen (Features), bei entsprechendem Community-Service (sprich Supportarbeit oder Moderation im Forum) oder bei wiederholter Mitarbeit im Bereich Fehlersuche.

Falls dennoch absehbar ist, dass ein Interesse am Projekt nicht von dauerhafter Art sein kann, dann ist ein einmaliger Arbeitsbeitrag sinnvoll. So wird dem Projekt auch wirklich etwas beigesteuert und es verbleibt nicht bei "Geschwatze" (siehe dazu auch Spielregel 5). Letzteres bringt keinem Projektbeteiligtem etwas und schafft auch keinen Mehrwert für die Nutzer.

Spielregeln für Entwickler

Für hinzukommende Entwickler gelten die folgenden Spielregeln.

Spielregel 1: Kommunikation zwischen den Entwicklern ist "fast" alles.

Der wichtigste Faktor ist die wechselseitige Abstimmung durch Kommunikation untereinander. Die Zusammenarbeit der Entwickler kann nur funktionieren, wenn die Kommunikation über die Quellcodeentwicklung ablaufen kann. Ohne Kommunikation gibt es keine Koordination von Verhalten, denn jeder könnte irgendetwas anderes tun. Eine der wichtigsten Spielregeln für die Zusammenarbeit der Entwickler lautet daher: Kommunikation ist "fast" alles.

Diese Spielregel mag sich zunächst trivial, und wie ein Allgemeinplatz anhören, doch Fakt ist, dass bei zunehmender Teamgröße zwangsläufig Kommunikationsprobleme auftreten. Diese können wiederum nur durch weitere verbesserte Abstimmung gelöst werden. Sollten sich Kommunikationsprobleme anhaufen und so auswirken, dass Entwicklungsarbeit nicht mehr möglich ist, dann stecken nicht nur das Projekt, sondern zumeist auch alle am Problem Beteiligten in einer sehr demotivierenden Krise. Eine hilfreiche Strategie ist die Fokussierung auf das Entwicklungsproblem und nicht auf die Personen, die dazu unterschiedliche Meinungen haben können.

Spielregel 2: Wir wahren die Umgangsformen und die Netiquette!

Wir pflegen hier einen offenen, sehr kommunikativen und kreativen Umgangsstil. Bitte verhaltet Euch entsprechenden den Regeln der Netiquette. Wir arbeiten hart an den Problemen und sind nett zueinander. Es gilt die Spielregel "Work hard & be nice to people". Konflikte sind sachlich zu lösen.

Spielregel 3: Der Quellcode folgt den Quellcodekonventionen

Der geschriebene Quellcode hat sich nach den Programmierrichtlinien zu richten. Orientieren Sie sich an vorhandenem Quellcode oder schauen Sie im Kapitel 17 "Grundsätzliches zum Coding-Style" nach, um genauere Angaben zu finden.

Spielregel 4: Bei Sorgen, Nöten oder Unklarheiten ein Mitglied des Supportteams oder einen Entwickler fragen!

Falls eine Frage auftaucht, dann fragen Sie ein Mitglied des Supportteams oder einen der Entwickler. Vorher sollten Sie allerdings eine Suche im Forum und Dokumentation durchführen.

2.2. Kommunikationsmittel

Um die Kommunikation zwischen den Entwicklern zu erleichtern, stehen die folgenden Kommunikationskanäle zur Verfügung. Das Vorhandensein der nachfolgenden Organsiations- und Kommunikationsmittel bewirkt nicht, dass sich ein Entwicklerteam automatisch zusammenschweißt und fortan Großartiges vollbringt. Ohne vorherige Kommunikation kann eine solche Dynamik nicht in Gang gebracht werden. Voraussetzung für ein In-Gang-Setzen ist wiederum, dass die Menschen von alleine miteinander kommunizieren wollen.

2.2.1. Quellcode

Ein wesentlicher Teil der Kommunikation ist der Quellcode selbst. Wir setzen daher auf Codingstandards und solide Dokumentation des Quellcodes. Dadurch wird die Nachvollziehbarkeit des Codes für alle Entwickler erhöht und insgesamt führt dies zu einer Steigerung der Qualität des Quellcodes. Die Einhaltung der Konventionen wird durch automatische Überprüfung mittels CodeSniffer sichergestellt und in einem öffentlich verfügbaren Bericht über den Quellcodezustand veröffentlicht. Anhand dieses Berichts ist es jedem Entwickler möglich eventuell erforderliche Korrekturen vorzunehmen, und zur Einhaltung der Konventionen beizutragen. Eine ausführliche Darstellung der Quellcodekonventionen anhand von Beispielen finden Sie im Kapitel 17.

2.2.2. Revisionsverwaltungssystem "Subversion"

Wir setzen Subversion (SVN) als Revisionsverwaltungssystem für den Quellcode ein. Damit können wir Änderungen, die durch die einzelnen Entwickler beigesteuert werden, einfacher nachverfolgen und im Fehlerfall rückgängig machen. In der Nachvollziehbarkeit von Änderungen liegt, neben dem nicht unerheblichen Motivationseffekt, ein wesentlicher Vorteil der Revisionsverwaltung. Es ist somit gewährleistet, dass alle Entwickler wissen, was zu welchem Zeitpunkt geändert wurde und wer die Veränderungen vorgenommen hat. Letztere Angabe ist beim Auffinden von Fehlerursachen und bei Streitigkeiten wichtig.

Subversion ist eine zentral organisierte Versionskontrolle. Unser Subversion-Server wird durch gna.org bereitgestellt. Grundsätzlich hat somit jeder Entwickler die Möglichkeit für sich alleine und offline am Quellcode zu arbeiten. Anders als bei GIT
[http://git-scm.com/]
steht der lokal und offline weiterentwickelte Quellcode jedoch nicht unter Revisionskontrolle. Eine Versionierung erfolgt bei der Arbeit mit Subversion erst durch das Übertragen der Änderungen auf den zentralen Server.

Wir arbeiten inkrementell, zumeist ultra-inkrementell. Dies bedeutet, dass auch kleinere und kleinste Codeänderungen in die Revisionsverwaltung "eingecheckt", also an das System übertragen, werden. So wird eine stetige Verbesserung in kleinen Schritten bewirkt.

Es gilt folgende goldene Spielregel:

Man kann viel schreiben und noch mehr reden, aber nur ausführbarer Code und geschriebene Dokumentation zählen.

Spielregel 5: Was nicht im SVN ist, ist nicht in der Clansuite-Welt.

Mehr zum Umgang mit Subversion erfahren Sie im Kapitel 3.

2.2.3. Bugtracker "Trac"

Als Projektmanagementtool verwenden wir den Bugtracker Trac. Hier halten wir fest, welche Aufgaben noch anstehen oder bereits erledigt wurden. Er dient also der Verwaltung von Fehlermeldungen, Wünschen und Arbeitsaufgaben und bietet die Möglichkeit Kommentare zu verfassen. Zudem stellt er einen komfortablen Quellcodebrowser, eine Roadmap und die Timeline bereit, in welcher die letzten Änderungen verfolgt werden können.

Alles ist wichtig und sollte sofort erledigt werden, am besten schon gestern!

Aus diesem Grund gibt es bei uns eine Roadmap, einen groben Fahrplan in die Zukunft. In der Roadmap sind Meilensteine der Entwicklung festgelegt. Die Meilensteine geben die einzelnen Entwicklungsstufen und Versionen von Clansuite wieder. Jeder Meilenstein besteht wiederum aus kleineren Schritten: den Aufgaben.

Wir haben festgelegt, mit 3 Arten von Aufgaben (engl. Tasks oder Issues) zu arbeiten. Diese Aufgabetypen sind Bugs, Todos und Feature Requests. Bugs stehen für gefundene Fehler - diese sind zu beheben. Todos stehen für offene Aufgaben - diese sind abzuarbeiten. Feature Requests stehen für Vorschläge und Wünsche der Nutzer - diese sind einzuarbeiten.

Sie können den Bugtracker unter der URL http://trac.clansuite.com/ erreichen.

Struktur und Aufgabentypen des Bugtrackers
Abbildung 2. Überblick über Struktur und Aufgabentypen im Bugtracker
Wichtig Teilweise werden auch erhebliche Umwege in Kauf genommen, um den Fahrplan umzusetzen. Dies dient jedoch der kreativen Wegfindung. Der Weg ist das Ziel. Und so kann es vorkommen, dass bei unserer Reise durch das Clansuite-Land teilweise recht große Ausflüge in Regionen unternommen werden, die nicht auf der Roadmap verzeichnet sind. Wenn Ihr das feststellt, könnt Ihr entweder fragen, wohin die Reise gerade geht oder besser, dem Reisenden Gesellschaft leisten.
Spielregel 6: Es muss klar erkennbar sein, wer woran arbeitet! (Transparenzgrundsatz)

Jeder Entwickler soll über den Bugtracker erfahren können, wer gerade woran arbeitet! Wer eine Aufgabe bearbeitet oder bearbeiten möchte, hat sich einzutragen. Wer eine Aufgabe abschließend bearbeitet hat, trägt sie auch aus! Das Löschen von Aufgaben ist untersagt.

2.2.4. Forum

Für längere Diskussionen steht das Forum bereit. Gäste können das Forum zwar lesen, aber nichts schreiben. Wer Beiträge schreiben möchte, registriert sich bitte dort. Der Login vom Forum gilt auch für den Bugtracker Trac.

Wichtig Für Entwickler gilt: Der eigene Benutzername ist kleinzuschreiben. (Wegen der Anmeldemöglichkeit beim Bugtracker.)

Sie können das Forum unter der URL http://forum.clansuite.com/ erreichen.

2.2.5. Pastebin

Für die Schnellkommunikation zwischen den Entwicklern kann auf eines der bekannten Pastebin-Systeme (oft auch NoPaste genannt) zurückgegriffen werden. Er dient dazu Quellcode, zumeist Codeschnipsel und Auszüge, aber auch längere Codesegmente zu veröffentlichen. Dabei wird der Quellcode automatisch mit Syntaxhervorhebungen dargestellt. Zudem ist das Einfügen von Markierungen möglich. Die Codeschnipsel stehen für einen Zeitraum zwischen einem Monat und sechs Monaten zur Verfügung. Jeder Post wird unter einer Nummer geführt. Durch Zuschicken der URL mit dieser Nummer kann ein Posting einfach referenziert werden. Auf diese Art und Weise kann die entsprechende URL sehr einfach in einem Chat oder im Forum gepostet werden, ohne den Gesprächsverlauf durch überlange Quelltextabschnitte zu unterbrechen.

Zwei oft genutzte Pastebins sind unter den URLs http://pastebin.com/ und http://gist.github.com/ zu finden.

2.2.6. IRC-Channel

Wenn Sie den schriftlichen Livekontakt bevorzugen, dann können Sie den Internet Relay Chat verwenden. Dafür ist ein IRC-Client, wie z.B. mirc oder irssi, notwendig oder Sie nutzen den unten angebotenen Webchat, um direkt von der Webseite aus zu chatten. Sie erreichen die Entwickler und Benutzer von Clansuite in zwei Chatnetzwerken. Wir sind im "Quakenet", dem Chatnetzwerk der Onlinezocker, sowie im "Freenode", einem Chatnetzwerk für Freie und Open-Source Projekte, jeweils im Channel "#clansuite" zu finden.

Der IRC-Channel #clansuite @ Quakenet wird durch den Bot "cslogbot" geloggt, um die Entwicklerchats auch nachlesen zu können. Das Archiv mit den IRCLogs ist unter http://irclogs.clansuite.com/ zu erreichen.

Tipp Im IRC-Channel #clansuite @ Quakenet stehen einige Befehle für den Bot "csweetie" zur Verfügung. So zeigt der Befehl "!paste" den Link zum Pastebin, sodass man ihn nicht jedes Mal heraussuchen zu muss. Des weiteren steht der Befehl "!php" zur Verfügung. Gibt man "!php" gefolgt von einem PHP-Befehl ein, beispielsweise "!php compact", dann erhält man den Link zur Befehlsreferenz im PHP-Handbuch.
Quakenet Verbindungsdaten

Server de.quakenet.org

Port 6666

Channel #clansuite

Freenode Verbindungsdaten

Server irc.gnu.org oder irc.freenode.net

Port 6667

Channel #clansuite

2.2.7. Teamspeak

Wenn Sie mündlichen Kontakt mit den Entwicklern möchten, dann können Sie sich auf den Teamspeak-Server des Clansuite Projekts verbinden. Im Teamspeak finden unsere regelmäßigen Entwicklertreffs statt, in denen wir die Weiterentwicklung von Clansuite besprechen. Für Entwickler gehören diese Teamspeak-Sessions zum Pflichtprogramm.

Tipp Sie können Teamspeak kostenlos unter der URL http://www.teamspeak.com/ herunterladen! Wenn Sie den Client installiert haben, können Sie nachfolgenden Link verwenden um auf den Clansuite Server zu connecten.
Teamspeak Verbindungsdaten

IP clansuite.com

Port 9987

Link ts3server://clansuite.com?port=9987

2.2.8. Livesupport (Hotline)

Clansuite verfügt über eine integrierte Hotline. Darüber können Sie direkt aus dem System heraus mit dem Supportteam und den Entwicklern Kontakt aufnehmen. An zahlreichen Stellen innerhalb des Systems können Sie unseren Livesupport Button finden. Dazu klicken Sie beispielsweise unter "Hilfe" einfach auf den Button "Live Support", um ein Dialogfenster zu öffnen. Sie können an der grünen oder roten Farbe des Buttons vorher erkennen, ob die Supportzentrale besetzt ist. Wenn ein Mitarbeiter des Supportteams verfügbar ist, dann werden Sie direkt mit ihm verbunden und können Ihre Fragen stellen oder Probleme im Chat schildern. Sollte kein Mitarbeiter verfügbar sein, so können Sie zumindest eine Textnachricht hinterlassen, damit wir Sie zu einem späteren Zeitpunkt per Email kontaktieren können.

2.2.9. Dokumentation

Die Dokumentation ist einer der wichtigsten Kommunikationskanäle. Dieser Kanal ist zweigeteilt. Zum einen gibt es die Dokumentationen für Benutzer. Dies sind das Benutzerhandbuch und die Schnellanleitung (Quickguide). Zum anderen gibt es das Entwicklerhandbuch (Sie lesen es gerade!) und die ergänzenden API Klassenreferenzen.

Sie können die Dokumentation unter der URL http://docs.clansuite.com/ erreichen.

2.3. Der Entwicklungsprozess

Für neue Entwickler ist die Kenntnis des Entwicklungsprozesses von Bedeutung. Der Entwicklungsprozess ist in mehrere Phasen unterteilt.

Der Entwicklungsprozess
Abbildung 3. Der Entwicklungsprozess

Zunächst erfolgt die Ideenfindung, danach die Spezifikation. Hier wird das "Was" der Entwicklung zunächst grob, dann fein bestimmt. Ursprung einer Idee kann beispielsweise ein Forumsbeitrag mit einem Feature-Request sein. Eine Spezifikation ist eine Anforderungsanalyse und eine Zusammenstellung der denkbaren Anwendungsfälle. Sie kann informell, durch Beschreibung in Textform, oder formell, durch Verwendung eines grafischen Modellierungswerkzeugs, erfolgen.

Wer ein wenig Erfahrung mitbringt und sich zu orientieren weiß, der kann regelmäßig den Teil der Spezifikation überspringen. Dies geht nicht bei vertraglich gebundener Softwareentwicklung, da die genaue Spezifikation ja zumeist die Anweisungsgrundlage für angestellte Programmierer ist und definiert, was eigentlich vom Programm erfüllt werden soll. Wenn beispielsweise ein Forum in PHP programmiert werden soll, dann kann man sich an zahlreichen bestehenden Implementationen orientieren und muss nicht zwingend zur Spezifikation übergehn. Denn Spezifikation und Implementation sind fast regelmäßig doppelte Arbeit und beide Prozesse sind fehleranfällig.

Es ist auch möglich, einen Teil der Spezifikation gleich als Tests zu implementieren. Dieses Vorgehensmodell nennt sich "Test-getriebene Entwicklung" (engl. Test-driven Development, abgekürzt: "TDD"). Clansuite unterstützt diese Vorgehensweise durch eine Testsuite. Mehr zu dieser Entwicklungsmethode erfahren Sie im Kapitel 14, wo die Testsuite ausführlich besprochen wird.

Nachdem das "Was" beschrieben wurde, wird es in Aufgaben zerlegt. Die Aufgaben werden in den Bugtracker "Trac" (siehe oben) eingetragen und zum Bestandteil der Roadmap gemacht.

Die Implementation ist das "Wie", hier wird das "Was" durch Programmierung, Integration und den anschließenden SVN Commit umgesetzt. Nachdem die Programmierung abgeschlossen ist, wird die Aufgabe im Bugtracker durch Statusänderung ausgetragen und es folgt die Dokumentationsphase.

In der Dokumentationsphase wird das Nutzer- und Entwicklerhandbuch so ergänzt, dass Nutzer neue Features vernünftig handhaben und Entwickler die Implementierung nachvollziehen und darauf aufbauen können.

Anschließend wird durch manuelles Testen oder automatische Testfälle die Funktionsfähigkeit sichergestellt und dabei gefundene Fehler behoben.

Sind alle Aufgaben eines Entwicklungsabschnitts der Roadmap erfüllt, erfolgt die Veröffentlichung. Mit der Veröffentlichung geht Clansuite in den produktiven Einsatz über.

An die Veröffentlichung schließt sich die Wartung an.

Neben dem hier eingesetzten Modell und der Test getriebenen Entwicklung gibt es zahlreiche weitere Vorgehensmodelle und Softwareentwicklungsprozesse
[http://de.wikipedia.org/wiki/Vorgehensmodell_zur_Softwareentwicklung, Wikipedia Category Software Development Process]
.

3. Kapitel 3 - Der Einstieg in die Clansuite Entwicklung

Dieses Kapitel ist eine Anleitung für den Einstieg in die Clansuite-Entwicklung. Zunächst wird die Einrichtung eines lokalen Entwicklungs-Webservers und das Holen des Clansuite-Quellcodes aus dem SVN-Archiv oder dem GIT-Archiv besprochen. Dann wird die Einrichtung einer Entwicklungsumgebung und die Installation der Clansuite Community Toolbar erklärt.

Grundlage für die Beschreibungen innerhalb dieses Kapitels ist ein Windows-XP Betriebssystem. Die Schritte können allerdings denkanalog auf Linux und MAC übertragen werden.

3.1. Das Einrichten des lokalen Webservers

3.1.1. XAMPP

Am einfachsten lässt sich ein Webserver unter Windows installieren, wenn man ein fertiges Webserverpaket verwendet. So lässt sich beispielsweise das XAMPP-Package von Apachefriends.org oder das Clansuite Webserverpack verwenden. Diese Packages sind bereits so eingerichtet, dass sie ohne großen Konfigurationsaufwand lauffähig sind. Die normale XAMPP Version, aber auch der "XAMPP Lite" können eingesetzt werden. Die Webseite des Apache-Friends Projekts: http://apachefriends.org/de/xampp-windows.html

Achtung Die von mir bereitgestellten Konfigurationsdateien beziehen sich immer auf den "xampplite"!
Tipp Im Verzeichnis von XAMPP findet man die Datei "xampp-control.exe". Ein Rechtsklick mit der Maus öffnet das Kontextmenü, indem man dann "Verknüpfung erstellen" wählt. Nun kann die Verknüpfung via Drag’n'Drop in die Taskleiste gezogen werden, wo sie dann einen komfortablen Server-Startknopf darstellt.

3.1.2. Clansuite Webserverpack für Windows

Das Clansuite Projekt stellt ein fertiges Webserverpack für Windows zur Verfügung. Das Clansuite Webserverpack basiert auf WPN-XM. Es dient Entwicklungszwecken und ist keinesfalls für den Livebetrieb gedacht.

3.1.3. MySQL einrichten

Wenn der Serverstack läuft, einfach die URL http://localhost/phpmyadmin/ im Webbrowser aufrufen und einen neuen User mit Passwort anlegen. Diese Daten dann auch bei der Installation von Clansuite verwenden.

3.2. Den Clansuite Quelltext beziehen

Der Quellcode von Clansuite kann aus dem Subversion-Archiv (englisch: Repository) geholt werden. Das kann einerseits über die Konsole geschehen, andererseits kann ein grafisches Interface für SVN eingesetzt werden.

3.2.1. SVN Checkout über die Konsole

Voraussetzung für den Checkout über die Konsole ist die Installation der SVN Tools.

svn checkout svn://svn.gna.org/svn/clansuite/trunk

3.2.2. GIT Checkout über die Konsole

Das Clansuite Git-Archiv wird von GitHub gehostet. Es ist unter der Adresse https://github.com/jakoch/Clansuite.git zu finden. Nach der Benutzerregistrierung auf Github, kann das Repository geforked werden.

Voraussetzung für den Checkout über die Konsole ist die Installation des Git Tools "msysgit"
[http://code.google.com/p/msysgit/, msysgit]
. Download unter: http://code.google.com/p/msysgit/downloads/list

Als grafisches Interface empfehle ich TortoiseGIT. Download unter: http://code.google.com/p/tortoisegit/downloads/list

Danach einfach den folgenden Code in der "Git Bash" ausführen, um deine Kopie des Repositories zu klonen.

git clone git@github.com:dein_username/Clansuite.git

Wenn das Repository geklont wird, dann zeigt es standardmäßig auf dein entferntes (engl. remote) Repository (origin), welches dein Fork des Originals (username/Clansuite.git) und nicht das von dir geforkte Repository (jakoch/Clansuite.git) ist. Damit Updates eingespielt werden können, ist für das ausgecheckte Repository noch das entfernte Original-Repository festzulegen.

Dazu wird ein weiteres Remote-Repository namens "upstream" festgelegt:

# Zunächst in das Verzeichnis des Clansuite Git Repositories wechseln
cd clansuite

# Das Original-Repository als "upstream" hinzufügen
git remote add upstream git://github.com/jakoch/Clansuite.git

# Änderungen des Original-Repositories laden, ohne eigene Dateien zu verändern
git fetch upstream

3.2.3. SVN Checkout mittels TortoiseSVN

a) Das SVN-Userinterface "TortoiseSVN" installieren

Ich rate hier zu "Tortoise SVN". Aber natürlich gibt es auch andere SVN-Userinterfaces, wie z.B.: RapidSVN oder gSVN. Es ist ein nützliches Standardtool für diese Aufgabe, da es sich in den Explorer einklinkt und dort ein SVN Verwaltungsmenü anbietet. Bitte achten Sie darauf, je nach Betriebssystem (32bit oder 64bit) die richtige Version herunterzuladen. Nach der Installation ist gegebenenfalls ein Neustart des Systems notwendig.

Webseite des "Tortoise" Projekts: http://tortoisesvn.net/downloads

b) Den Clansuite Sourcecode beziehen

Im Datei-Explorer-Kontextmenü (rechte Maustaste) sollte nun "SVN Checkout" und ein Menü mit dem Namen "Tortoise SVN" auftauchen.

Die URLs für den Checkout von Clansuite sind: svn://svn.gna.org/svn/clansuite/trunk - checkt nur den trunk/head aus svn://svn.gna.org/svn/clansuite - checkt das ganze Projekt aus

Als Checkout-Directory kann man direkt einen lokalen Webserverpfad nehmen: C:\xampplite\htdocs\clansuite Ich verwende ein Verzeichnis namens "work" und lege alle Projekte darin ab: C:\xampplite\htdocs\work\clansuite

Sobald der Checkout erfolgreich beendet worden ist, steht der Sourcecode im Checkout-Verzeichnis zum bearbeiten und installieren zur Verfügung. Für die Installation ruft man die URL einfach http://localhost/clansuite/ oder http://localhost/clansuite/installation auf. Der Installationsassistent führt Sie dann durch die Installation.

TIP: Das Verzeichnis "C:\xampplite\htdocs\" entspricht der Browser-URL "http://localhost". Das Verzeichnis "C:\xampplite\htdocs\work" entspricht der Browser-URL "http://localhost/work/".

TIP: Man gehe mit dem Explorer in das Verzeichnis "C:\xampplite\htdocs\work\", dort ist "clansuite" enthalten. Hier nun per Kontextmenü eine "Verknüpfung erstellen" und diese in die Taskleiste ziehen. Hierdurch erhält man einen sofortigen Sprung in das Entwicklungsverzeichnis.

3.3. Die Installation von Clansuite

In den beiden vorherigen Abschnitten haben Sie erfahren, wie sie einen lokalen Webserver aufsetzen und den Quellcode von Clansuite beziehen. In diesem Abschnitt geht es um die Installation.

Die Installation von Clansuite für Entwickler unterscheidet sich nicht von dem Installationvorgang für Nutzer. Daher wird an dieser Stelle auf das Installationskapitel im Benutzerhandbuch verwiesen.

3.4. Die Entwicklungsumgebung einrichten

Als Nächstes kann man die Umgebung einrichten. Das Einrichten einer Entwicklungsumgebung kostet Zeit und Mühe und kann, bis alle Einstellungen bis ins Detail getroffen sind, zu einem Geduldsspiel werden. Am Ende zahlt sich die Investition sicher aus, dennoch ist der Konfigurationsaufwand, bis alles zufriedenstellend läuft, frustrierend. In diesem Abschnitt werden daher einige Erfahrungen der Clansuite Entwickler im Umgang mit Entwicklungswerkzeugen weitergegeben. Beschrieben wird welche Software, warum verwendet und wie diese Werkzeuge im Zusammenhang mit Clansuite eingesetzten werden.

Im Laufe meiner Entwicklungsarbeit an Clansuite sind mir die unterschiedlichsten Menschen in ihrer Rolle als Entwickler begegnet. Manche von Ihnen berichteten in regelmäßigen Abständen und mit einigem Stolz, von diesem und jenem Betriebssystem auf ein anderes gewechselt zu sein. Wieder andere berichteten vom Wechseln von einer integrierten Entwicklungsumgebung auf die Nächste. Man wechselte fleißig von Aptana zu Eclipse dann zu Netbeans und wieder zurück. Bei diesen Wechseln geht sehr viel Zeit verloren, die zum Entwickeln nutzbar wäre. Mich hat es daher wenig gewundert, das produktive Beiträge für das Projekt in Form von SVN-Commits ausblieben.

Oft ist die Wechselmanitis auch mit dem innigen Wunsch verbunden, doch endlich einen Editor zu entdecken, der einem das Programmieren abnimmt, weil es doch "so komplex" ist. Diese Suche kann ewig dauern. Editoren und IDE’s haben einen ebenso langen Weg der Abstraktion hinter sich, wie die Programmiersprachen, für die sie Hilfsmittel sind. Sie werden auch immer nur Hilfsmittel eines Entwicklers sein, um Komplexität zu bezwingen und sich auszudrücken. Man ist Programmierer, wenn man gelernt hat, sich wie ein Programmierer auszudrücken.

Zu einer vernünftigen Entwicklungsumgebung gehören daher auch Bücher und Nachschlagewerke. Sich ein Lehrbuch über die Programmiersprache PHP und objektorientierte Programmierung anzuschaffen, kann nicht schaden. Die Lektüre darin ebenso wenig. Hilfreich ist es auch, wenn man eine Sprachreferenz der Programmier- und Skriptsprachen, die man einsetzt, in greifbarer Nähe oder zumindest nur wenige Mausklicks entfernt hat. Die Ergänzung der Entwicklungsumgebung um die Clansuite Toolbar wirkt hier Wunder, stellt sie doch den Zugriff auf die wesentlichen Projektseiten und eine komfortable Suche im PHP-Manual bereit. Eine ausführliche Erläuterung der Suchfunktionen der Toolbar finden Sie in Kapitel 12.

Wer professionell entwickeln möchte, sollte sich eine gleichbleibende Entwicklungsumgebung einrichten und dann lernen damit wirkungsvoll umzugehen. Sicher ist die Wegfindung, also "wie" und "womit" der Output erzeugt wird, auch wichtig, aber primär geht es darum, den Output an sich zu erzeugen. Wer diesen, seinen, Weg einmal gefunden hat, der mag ihn von Zeit zu Zeit wieder verändern. Aber die Zeitspanne bis zu einer Veränderung sollte so gesetzt werden, dass man in der Zwischenzeit vernünftig arbeiten kann. Ein ständiges Wechseln der Umgebung ist daher zu vermeiden.

Damit ist nicht gesagt, dass man keine neuen Werkzeuge ausprobieren sollte. Ganz im Gegenteil. In regelmäßigen Abständen sollte man seine Entwicklungsumgebung dahin gehend überprüfen, ob neue verbesserte Werkzeuge erhältlich sind. Wenn dies der Fall ist, kann man einen Austausch vornehmen. Dieser Hinweis mag trivial erscheinen, doch meine Erfahrung bestätigt die Notwendigkeit, auf diesen Umstand hinzuweisen.

3.4.1. Webbrowser

Natürlich gehört auch der Webbrowser zur Entwicklungsumgebung. Er nimmt die durch die Webanwendung generierte Ausgabe entgegen, interpretiert sie und sorgt schließlich für die Darstellung. Diese Kernaufgabe wird von der Layout- bzw. Render-Engine, dem technischen Kern, wahrgenommen. Neben dieser Kernaufgabe erfüllen Webbrowser eine Reihe weiterer Nebenaufgaben. Beispielsweise erhöhen sie die Nutzbarkeit durch das Führen von Verlaufslisten der besuchten Webseiten (Chronik), das Aufbewahren von Lesezeichen (Bookmarks) und das Bereitstellen von Popup- und Werbeblockern.

Derzeit (2010) gibt es mehrere Entwicklungslager mit unterschiedlichen Layout- bzw. Render-Engines. Zu beachten und zu verstehen ist jedoch, dass jeder Webbrowser die Interpretationsregeln für Webdokumente unterschiedlich streng umsetzt. Die Standards für die Webdokumente sind zwar vom World Wide Web Consortium (W3C) eindeutig beschrieben, doch nicht jeder Webbrowser verhält sich standardkonform. Um die Standardkonformität zu fördern, wurde eine Sammlung von Test-Webseiten unter dem Namen "Acid-Tests"
[http://acidtests.org/]
entwickelt. Inzwischen liegt die dritte Version dieser Testsammlung vor
[http://acid3.acidtests.org/]
.

Das Einpflegen von Style-Fixes und Hacks, um einen bestimmten Browser doch noch zur vernünftigen Darstellung eines Seiteninhalts zu bewegen, ist den meisten Webentwicklern eine wohlbekannte und lästige Geschichte. Nichts ist grauenvoller, als einen Flickenteppich aus Style-Fixes pflegen zu müssen. So zeigt beispielsweise der Microsoft Internet Explorer in den Versionen 5 bis 7 Webseiten sehr abweichend von den Standards an. Erst die Version 8 des IE (unter Verwendung der Render-Engine Trident Version 4) schafft Abhilfe und erfüllt den Acid2-Test. Eine Läuffähigkeit von Clansuite auf dem Mircosoft Internet Explorer ist zu keinem Zeitpunkt angestrebt. Neuere Versionen dieses Browsers werden zeigen, ob sich eine Kompatibilität mit Clansuite einstellt.

Eine hilfreiche Webseite um die standardkonforme Darstellung in verschiedenen Webbrowsern zu überprüfen, ist Adobe Browserlab
[https://browserlab.adobe.com/]
. Browserlab ist ein cloudbasierter Webseiten-Darstellungsdienst, der die Ausgabe verschiedener Browser auf verschiedenen Betriebssystemen zurückliefert.

Übersicht zu Webbrowsern
Mozilla Firefox                         http://mozilla-europe.org/de/firefox/
Google Chrome                           http://google.com/chrome/
Opera                                   http://opera.com/
Maxthon                                 http://maxthon.com
Safari                                  http://apple.com/de/macosx/features/safari/
Netcape Navigator                       http://netscape.de/
Microsoft Internet Explorer (Windows)   http://microsoft.com/germany/windows/internet-explorer/

Wir schlagen die Entwicklung mit und für Mozilla Firefox vor.

Webentwickler Addons für Firefox

Wer Mozilla Firefox einsetzt, kann auf zahlreiche Addons für Entwickler zurückgreifen. Stellvertretend für viele hilfreiche Werkzeuge sind die Web Developer Extension, Firebug sowie YSlow genannt.

Übersicht zu Webentwickler Addons für Firefox
Firebug
http://getfirebug.com/
https://addons.mozilla.org/de/firefox/addon/1843/

Firebug ist ein Werkzeug zur Untersuchung einer Webseite. Dazu aktiviert man den "Untersuchen"-Modus
und zeigt mit dem Mauszeiger auf das Webseitenelement. In der Firebug-Konsole werden dann der
Quelltext dieses Elements, sein CSS und weitere Eigenschaften angezeigt.
Man kann auch eine direkte Veränderung durch "Bearbeiten" herbeiführen.

FireCookie
https://addons.mozilla.org/de/firefox/addon/6683/

FireQuery
Erweitert Firebug um Unterstützungsfunktionen zum Entwickeln mit jQuery
http://firequery.binaryage.com/

YSlow
http://developer.yahoo.com/yslow/
https://addons.mozilla.org/de/firefox/addon/5369/

FirePHP
http://firephp.org/

CSS Usage
Hilft beim Optimieren und Aufräumen von CSS Dateien durch Auffinden ungenutzer CSS-Selektoren.
https://addons.mozilla.org/de/firefox/addon/10704

Poster
https://addons.mozilla.org/de/firefox/addon/2691

Live HTTP Header
https://addons.mozilla.org/de/firefox/addon/3829/

Tamper Data
https://addons.mozilla.org/de/firefox/addon/966/

Webdeveloper Toolbar
http://chrispederick.com/work/web-developer/
https://addons.mozilla.org/de/firefox/addon/60/

HTML Validator
Führt eine Validierung des (X)HTML Quellcodes durch und beinhaltet sowohl den SGML Validator als auch HTML Tidy.
http://users.skynet.be/mgueury/mozilla/

3.4.2. Clansuite Toolbar als Firefox-Addon installieren

Um die Entwicklerinstallation abzurunden und einen komfortablen Zugriff auf alle Projektinformationen zu haben, kann man die Clansuite Toolbar herunterladen und durch "Ausführen mit Firefox" im Browser installieren. Unter "Optionen" lassen sich die Entwicklermenüs ein- und ausschalten, sowie die Pfade an Ihre Entwicklungsumgebung anpassen.

Eine Besonderheit stellen die Links des Menüs "Goto" dar. Als die Basis-URL der Links, können Sie beispielsweise einen virtuellen Host in den Optionen definieren. Somit könnten Sie beispielsweise "clansuite-dev.com" im Browser aufrufen.

Links des "Go to"-Menüs in der Clansuite Toolbar
"Frontend @ localhost"  ->  "http://clansuite-dev.com/"
"Control Center"        ->  "http://clansuite-dev.com/?mod=controlcenter/"
"Installation"          ->  "http://clansuite-dev.com/installation/"
"Web-Installation"      ->  "http://clansuite-dev.com/installation/webinstaller/webinstaller.php/"
"Converter"             ->  "http://clansuite-dev.com/installation/converter/"

3.4.3. VirtualHost (Windows)

Die Einrichtung eines virtuellen Hosts kommt dann in Betracht, wenn auf dem lokalen Entwicklungsrechner ein oder mehrere Webanwendungen mit unterschiedlichen Domains oder Subdomains erreichbar sein sollen, aber ein Nameserver nicht zur Verfügung steht. Wer sich beispielsweise den virtuellen Host "www.clansuite-dev.com" lokal einrichtet, kann die Webanwendung nicht nur im Browser um diese Adresse erreichen, sondern auch die Schnellverknüpfungen der Clansuite Toolbar nutzen.

Wer sich an dieser Stelle fragt, warum der virtuelle Host nicht "www.clansuite.com" sein darf, der findet eine einfache Antwort. Weil die lokale VHost-Adresse dann den echten Host, mit der Internetseite inklusive Forum, ersetzen würde und man folglich keinen Zugang hätte. Daher wählt man eine "fiktive" oder jedenfalls ungebräuchlichen VHost Domainnamen.

Unter "c:\xampplite\apache\conf\extra" findet man die Datei "httpd-vhosts.conf". In dieser Datei kann manuell der Vhost "ServerName clansuite-dev.com", sowie "ServerAlias www.clansuite-dev.com" hinzugefügt werden. Alternativ kann man die Datei einfach mit der Version aus dem Clansuite SVN ersetzen. Die entsprechende Datei gibts hier: http://svn.gna.org/svn/clansuite/trunk/build-tools/xampp/httpd-vhosts.conf

Beispielinhalt für "httpd-vhosts.conf"
NameVirtualHost *:80

<VirtualHost *:80>
     ServerName localhost
     ServerAlias localhost
     DocumentRoot "D:/xampplite/htdocs"
     ErrorLog "D:/xampplite/apache/logs/localhost-error.log"
     CustomLog "D:/xampplite/apache/logs/localhost-access.log" common

     <Directory "D:/xampplite/htdocs">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

<VirtualHost *:80>
     ServerName clansuite-dev.com
     ServerAlias www.clansuite-dev.com
     DocumentRoot "D:/xampplite/htdocs/work/clansuite/trunk"
     ErrorLog "D:/xampplite/apache/logs/www.clansuite-dev.com-error.log"
     CustomLog "D:/xampplite/apache/logs/www.clansuite-dev.com-access.log" common

     <Directory "D:/xampplite/htdocs/work/clansuite/trunk">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

Damit das System diese URL auf den lokalen Server umleitet, muss noch die "hosts"-Datei im Verzeichnis "%SystemRoot%\system32\drivers\etc\hosts" angepasst werden. Man trage "127.0.0.1 clansuite-dev.com" sowie "127.0.0.1 www.clansuite-dev.com" ein, um eine entsprechende URL-Namensauflösung zum localhost zu erhalten.

Tipp Wer die besagte hosts-Datei nicht per Hand editieren möchte oder die Datei gar häufiger editieren muss, um neue Domains aufzunehmen oder alte zu löschen, dem sei das kleine Programm "Hostsman" ans Herz gelegt. Es ist ein spezialisierter Editor für die hosts-Datei mit Backup-Funktionalität. Sie können es unter http://abelhadigital.com/hostsman herunterladen.

Alternativ kann auch eine Vorlagedatei aus dem SVN geholt werden: http://svn.gna.org/svn/clansuite/trunk/build-tools/xampp/hosts/

3.4.4. Xdebug - als PHP-Debugger und Profiler einbinden

Download Falls "php_xdebug.dll" nicht vorhanden ist, dann kann man sie von http://xdebug.org/ downloaden. Entsprechend umbenennen und ins Verzeichnis "C:\xampplite\php\ext" ablegen.

Um die richtige Binary für Xdebug zu finden kann auf die Projektwebseite zurückgegriffen werden. Unter http://xdebug.org/find-binary.php findet man ein Formular um den Inhalt der eigenen phpinfo() Ausgabe zu posten. Nach der Auswertung der Versionsangaben der Serversoftware, wird die entsprechende Xdebug-Binary und eine Installationsanleitung dafür angezeigt.

Tailored Installation Instructions for Xdebug
Summary

    * Xdebug installed: no
    * Server API: Apache 2.0 Handler
    * Windows: yes - Compiler: MS VC6 - Architecture: x86
    * Zend Server: no
    * PHP Version: 5.3.1
    * Zend API nr: 220090626
    * PHP API nr: 20090626
    * Debug Build: no
    * Thread Safe Build: yes
    * Configuration File Path: no value
    * Configuration File: D:\xampplite\php\php.ini
    * Extensions directory: D:\xampplite\php\ext

Instructions

   1. Download php_xdebug-2.1.0-5.3-vc6.dll
   2. Move the downloaded file to D:\xampplite\php\ext
   3. Edit D:\xampplite\php\php.ini and add the line
      zend_extension = D:\xampplite\php\ext\php_xdebug-2.1.0-5.3-vc6.dll
   4. Restart the webserver

XDebug in der php.ini einschalten In "c:\xampplite\apache\php.ini" nach "xdebug" suchen.

Wichtig ist, nicht die alte Methode zum Laden der Webservererweiterung zu verwenden. Alte Versionen von XDebug wurden mittels "extension=php_xdebug.dll" geladen. Diese Art und Weise des Ladens der Debugging-Erweiterung führt jedoch zu erheblichen Problemen. Dies liegt daran, dass XDebug, wenn es als normales Modul des Webservers läuft, nicht auf alle Sichtbarkeitsbereiche der Zend Engine zugreifen kann. Stellen Sie also zunächst sicher, dass "extension=php_xdebug.dll" auskommentiert ist. Die Auskommentierung wird durch voranstellen eines Semikolon erreicht (";extension=php_xdebug.dll").

Eine neuere und bessere Methode der Einbindung ist daher XDebug als Erweiterung der Zend Engine zu laden. Dies kann durch "zend_extension_ts = "c:\xampplite\php\ext\php_xdebug.dll" erreicht werden. Hierfür ist der Zend Extension Manager zu aktivieren. Dies kann durch hinzufügen der Zeile zend_extension_ts = "C:\xampp\php\zendOptimizer\lib\ZendExtensionManager.dll" erfolgen. Zu beachten ist die Inkompatibilität mit der Zend Erweiterung "Zend Optimizer". Zend Optimizer durch Auskommentieren der entsprechenden Zeilen zu deaktiveren. Um dies zu tun, kann nach der Zeichenfolge "zend_extension_manager.optimizer_ts" in der php.ini gesucht werden. Zend Optimizer ist eine Laufzeitbibliothek, die den Quellcode vor der Kompilierung optimiert um somit eine Beschleunigung erzielen.

Eine ausführliche Anleitung zum Thema "Wie installiere ich XDebug?" findet sich in Kapitel 16 (Der Webserver).

Xdebug-Einstellungen für Debugging mit Netbeans IDE
# In der php.ini folgende Werte setzen:
xdebug.idekey         = netbeans-xdebug
xdebug.remote_enable  = on
xdebug.remote_handler = dbgp
xdebug.remote_host    = localhost
xdebug.remote_port    = 9001

3.4.5. Einfache Texteditoren

Übersicht zu Texteditoren
.Notepad++
Notepad++ ist ein Open-Source Texteditor.
Er bietet Syntax-Highlightning und alle Funktionen, die zur Bearbeitung von PHP- und HTML- und CSS-Dateien
erforderlich sind.
http://notepad-plus.sourceforge.net/de/site.htm

.jEdit
jEdit ist ein Open-Source Texteditor unter GNU/GPLv2+ und durch zahlreiche Plugins gut erweiterbar.
http://jedit.org/

.KomodoEdit
Komodo Edit ist ein kostenloser komfortabler Editor.
http://activestate.com/komodo_edit/

.PHPEdit
PHPEdit bringt neben Syntax Highlighting und Code Hinting viele weitere hilfreiche Features mit.
http://waterproof.fr/products/PHPEdit/

.Vim
Vim ist angelehnt an und benannt nach dem Unix-Editor "Vi". Er bringt jedoch mehr Features mit.
Für manche ist Vim daher ein konfigurierbarer und mächtiger Texteditor, für andere schon eine IDE.
http://vim.org/

3.4.6. Integrierte Entwicklungsumgebungen (IDEs)

Integrierte Entwicklungsumgebungen beherrschen zumeist eine Reihe fortschrittlicher Techniken, um Entwickler zu unterstützen. Dazu gehören automatisches Quelltextfolding, automatische Quellcodevervollständigung und das vorlagenbasierte Erstellen von Quellcodeabschnitten. Auch eine Kontexterkennung von verfügbaren Methoden und Variablen unter Auswertung des DocBlocks und die Anzeige als Code-Hint ist oft verfügbar.

Übersicht zu IDEs
.Netbeans
Netbeans ist eine in Java geschriebene Open-Source Plattform für die Entwicklung von IDE für Windows, Linux, Mac OS X und Solaris.
http://netbeans.org/

.Eclipse
Eclipse ist ein in Java geschriebenes Framework zur Erstellung von integrierten Entwicklungsumgebungen (IDE).
http://eclipse.org/
Es gibt zahlreiche Plugins und Addons für Eclipse unter:
http://eclipseplugincentral.com/.

Wer sich eine individuelle Eclipse IDE zusammenklicken möchte, kann den Eclipse Download Service von
Yoxos OnDemand ausprobieren.
http://ondemand.yoxos.com/geteclipse/start/

.Eclipse-PDT
Insbesondere gibt es ein Eclipse-IDE-Paket namens PHP Development Tools (PDT) welches speziell für PHP-Entwickler zusammengestellt wurde.
http://eclipse.org/pdt/

.PHPeclipse IDE
PHPeclipse ist eine PHP-IDE auf Basis von Eclipse.
Die Entwicklungsumgebung bietet einen Editor, Parser und Debugger .
http://phpeclipse.de

.QuantaPlus
Q+ ist eine IDE für Linux. Sie ist Teil der KDE Webdevelopment Tools.
http://kdewebdev.org/
http://quanta.kdewebdev.org/
NetBeans
Allgemeines zu NetBeans als PHP IDE

http://netbeans.org/kb/docs/php/editorguide.html

Downloaden

Die aktuelle Version von Netbeans findet sich unter http://netbeans.org/downloads/.

Nightly/Latest Development Versions unter http://bits.netbeans.org/download/trunk/nightly/latest/.

Zusammenspiel mit SVN + SSH

Netbeans die SVN Binaries zeigen

Gehen Sie in der Menüleiste auf "Tools" (1) und dort auf den Menüpunkt "Options" (2). Es öffnet sich das Options-Dialogfenster. Im Options-Diaglogfenster gehen Sie zuerst auf "Miscellaneous" (3) dann auf den Reiter "Versioning" (4). Hier wählen Sie unter "Versioning Systems" Subversion aus (5) und geben schließlich den Pfad zur Ihrer Subversioninstallation an (6).

Tools→Options→Miscellaneous→Versioning→Subversion→Browse (Pfad zu SVN angeben)

Netbeans den Tunnel zeigen

  1. Beziehen des Clansuite SVN

  2. Zusammenspiel mit Trac

  3. Beziehen der Clansuite Tickets (Netbeans mit Trac verbinden)

Um Netbeans mit Trac zu verbinden sind auf beiden Seiten Plugins erforderlich. Netbeans hat gegenwärtig (v6.9) keine native Unterstützung für Trac. Die Konnektivität zu Trac wird daher mittels eines Drittanbieter Plugins nachgerüstet. Das entsprechende Plugin hat den Namen CubeOn und ist unter http://code.google.com/p/cubeon/ zu finden. Seitens Trac ist, für einen Zugriff von außen, das XML-RPC Plugin (Remote Procedure Call) erforderlich. Man findet es unter http://trac-hacks.org/wiki/XmlRpcPlugin.

Im CubeOn Einrichtungsdialog ist nun noch der Nutzername und das Passwort für den Login bei Trac festzulegen. Danach steht einem Abruf der Tickets nichts mehr im Wege. Die Auflistung erfolgt im "TaskExplorer" Fenster und kann konfiguriert werden.

Netbeans mit dem CodingStandard verbinden

  1. Installation Dafür ist es notwendig Netbeans mit einem Plugin zu erweitern. Das Plugin für die CodingStandard-Kontrolle stammt von Benjamin Eberlei und Manuel Piechler. Es kann aus dem GitHub-Repository heruntergeladen werden.

Gehen Sie nach dem Download auf "Tools" (1) und dort auf den Menüpunkt "Plugins" (2). Es öffnet sich das Plugin-Dialogfenster. Im Plugin-Dialogfenster gehen Sie auf den Reiter "Downloaded" (3) und dort auf "Add Plugins" (4). Nun geben Sie den Pfad zum gerade heruntergeladenen Plugin "de-whitewashing-php-cs.nbm" an. (5) Nun werden die Metainformationen des Plugins angezeigt. Das Plugin stellt sich Ihnen als "phpcs2" vor. Danach klicken sie auf "Install". (6)

Tools→Plugins→Downloaded→Add Plugins→Browser (Pfad zum Plugin)→Install

Es öffnet sich das Netbeans Installer Dialogfenster. Gehen Sie nun auf "Next" anschließend akzeptieren Sie die Lizenz. Nun kommt ein Hinweis darauf, dass dieses Plugin nicht offiziell durch Netbeans signiert wurde und somit nicht den Status "trusted" besitzt. Sie müssen sich keine Sorgen deshalb machen. Wenn Sie dem Quellcode nicht vertrauen, schauen Sie vorher einfach in die GitHub Quellcodeverwaltung. Wenn mögliche Bedenken ausgeräumt sind, gehen Sie auf "Continue" und "Finish". Das Plugin wurde nun erfolgreich installiert.

Konfiguration

Gehen Sie in der Menüleiste auf "Tools" (1) und dort auf den Menüpunkt "Options" (2). Es öffnet sich das Options-Dialogfenster. Im Options-Diaglogfenster gehen Sie zuerst auf "PHP" (3) dann auf den Reiter "Code Sniffer" (4).

Anwendung

Netbeans ist nun in der Lage PHPCodeSniffer aufzurufen und die aktuell geöffnete Datei gegen den CodingStandard zu prüfen. Der Fehlerreport ist in der "File"-Ansicht unter "Tasks" verfügbar.

3.4.7. Datenbankwerkzeuge

Übersicht zu Datenbankwerkzeugen
.phpMyAdmin
phpMyAdmin ist eine freie PHP-Applikation und in den meisten Webserverstacks bereits als Verwaltungswerkzeug für MySQL-Datenbanken enthalten.
http://phpmyadmin.net/

.Adminer (früher phpMinAdmin)
Datenbankenbrowser für MySQL, PostgreSQL, SQLite, MS SQL and Oracle, bestehend aus einer Datei.
http://adminer.org/

.DBKiss
Browser für MySQL und PostGreSQL Datenbanken, bestehend aus einer Datei.
http://gosu.pl/dbkiss/

.SQL Buddy
Webbasiertes Verwaltungswerkzeug für MySQL-Datenbanken.
Eine Alternative zu phpMyAdmin.
http://sqlbuddy.com/

.HeidiSQL
HeidiSQL ist ein sehr einfaches grafisches Verwaltungswerkzeug für MySQL Datenbanken.
Die Desktopanwendung wird von Ansgar Becker (http://anse.de/) in Delphi entwickelt.
http://heidisql.com/

.MySQL Workbench Community Edition
Featurereiches Werkzeug zum visuellen Datenbankentwurf.
http://mysql.de/products/workbench/

.Liquibase
Liquibase ist ein datenbankunabhängiges Werkzeug zum Tracken, Verwalten und Versionieren von Datenbankdefinitionen und ihren Änderungen.
http://liquibase.org

3.4.8. Dokumentations- und Übersetzungswerkzeuge

Übersicht zu Dokumentations- und Übersetzungswerkzeugen
.AsciiDoc + Python
Für die automatische Erstellung der Dokumentation auf einem Windowssystem wird AsciiDoc und deshalb auch Python benötigt.
AsciiDoc: http://methods.co.nz/asciidoc/
Python: http://python.org/ftp/python/2.5.1/python-2.5.1.msi

Für die SourceCode-Highlighting Features von AsciiDoc wird zusätzlich das "src-highlite" Paket des GNU
Projekts benötigt.
http://gnuwin32.sourceforge.net/

.gettext
Für die automatische Erstellung der Übersetzungsdateien bzw. das Auslesen von zu übersetzenden Texten sind die
gettext Tools hilfreich.
http://gnu.org/software/gettext

.poEdit
Die Sprachdateien von Clansuite können auch mit einem externen Editor bearbeitet und übersetzt werden.
poEdit eignet sich hervorragend für diese Aufgabe.
http://poedit.net/

3.4.9. Allgemeine Werkzeuge

Übersicht zu allgemeinen Werkzeugen
.WinMerge
WinMerge ist ein Open-Source-Werkzeug zum Vergleichen zweier Dateien und zum Feststellen von Versionsunterschieden.
http://winmerge.org/

.Putty
PuTTY ist ein Werkzeug zur Verwaltung von SSH-Keys unter Windows-Systemen und ein telnet Client.
http://putty.org/
http://chiark.greenend.org.uk/~sgtatham/putty/download.html

.WinSCP
WinSCP ist ein grafisches SFTP, FTP Werkzeug. Es unterstüzt das SCP-Protokoll und die Verwendung von geschützten SSH-Verbindungen (Tunneling).
http://winscp.net/

.Filezilla
Ein Open-Source Standardwerkzeug für Dateitransfers mittels File-Transfer-Protocol (FTP).
Download: http://filezilla-project.org/

4. Kapitel 4 - Grundlegende Orientierung und Verzeichnisübersicht

Dieses Kapitel gibt Ihnen einen Überblick über die Struktur von Clansuite.

4.1. Grundlegende Orientierung

4.1.1. Dateien im Wurzelverzeichnis

Nach der Installation von Clansuite finden Sie die folgende Dateien im Hauptverzeichnis von Clansuite vor:

.htaccess      Beinhaltet Anweisungen für den Apache Webserver
index.php      Der zentrale Applikationseinstieg. Die Datei nimmt alle Anfragen des Browsers entgegen.
robots.txt     Steuerungsdatei für Webcrawler. Sie enthält Anweisung für das Indexieren von Dateien und Verzeichnissen.

4.1.2. Verzeichnisübersicht

Sie finden die folgende Verzeichnisstruktur vor:

clansuite
+---build-tools         Beinhaltet die Phing Build-File und Shell-Scripte für das Builden, sowie Konfigurationsdateien für Werkzeuge.
+---cache               Ist das Verzeichnis für temporär zwischengespeicherte Daten der Anwendung.
+---configuration       Beinhaltet die allgemeine Konfigurationsdatei "clansuite.config.php" und zusätzliche Konfigurationsdateien.
+---core                Beinhaltet den Clansuite Anwendungskern.
+---doc                 Beinhaltet die Dokumentation, sowie diverse rein informative Textdateien, unter anderem die Autorenliste und
¦                       die Lizenztexte von Clansuite. Ein Vorhandensein dieser Dateien ist nicht notwendig, um Clansuite zu betreiben.
+---modules             Beinhaltet alle verfügbaren Module des Systems. Hierher werden neue Module installiert.
+---themes              Beinhaltet alle Themes. Hierher werden neue Themes installiert.
Core
+---core                Beinhaltet den Clansuite Anwendungskern.
¦   +---bootstrap       Beinhaltet die für den Systemstart wesentlichen Kernfunktionen (Loading, Application Start).
¦   +---cache           Das Verzeichnis der Caching-Adapter.
¦   +---cronjobs        Das Verzeichnis für Cronjobs/Crontasks.
¦   +---debug           Das Verzeichnis für Debugging Hilfsfunktionen.
¦   +---events          Das Verzeichnis für Events.
¦   +---factories       Das Verzeichnis der Fabriken (für Cache, Config, Logger und Renderer).
¦   +---filter          Das Verzeichnis für Vor- und Nachfilter.
¦   +---functions       Beinhaltet hilfreiche zusätzliche Funktionen.
¦   +---gettext         Beinhaltet die Unterstützungklassen zur Arbeit mit Gettext.
¦   +---logger          Das Verzeichnis der Logging-Adapter.
¦   +---render          Das Verzeichnis der Renderer-Adapter.
¦   +---viewhelper      Das Verzeichnis für Hilfsfunktionen im View.
¦       +---smarty      Das Verzeichnis der Clansuite Viewhelper für die Renderengine Smarty.
Themes

Das Verzeichnis Themes enthält zunächst die drei Verzeichnisse frontend, backend und core. Frontend-Themes liegen in eigenen Verzeichnissen unterhalb von /themes/frontend. Backend-Themes liegen in eigenen Verzeichnissen unterhalb von /themes/backend. Systemweit verfügbare Bilder, Javascript, CSS, Schriften und Templates werden unterhalb von /themes/core in jeweils eigenen Verzeichnissen abgelegt.

+---themes              Hauptverzeichnis für Themes.
¦   +---frontend        Unterverzeichnis für Frontend-Themes.
¦       +---xyz         Verzeichnis eines Frontend-Themes.
¦   +---backend         Unterverzeichnis für Frontend-Themes.
¦       +---xyz         Verzeichnis eines Backend-Themes.
¦   +---core            Beinhaltet die Themes des Clansuite-Kerns.
¦   ¦   +---css         Verzeichnis für systemweit verfügbare Cascading Style Sheets/Bibliotheken.
¦   ¦   +---exceptions  Beinhaltet Exceptiontemplates.
¦   ¦   +---fonts       Beinhaltet Schriften.
¦   ¦   +---javascript  Verzeichnis für systemweit verfügbares Javascript und Bibliotheken.
¦   ¦   +---templates   Beinhaltet System-Templates.
Modules

Sie finden die folgende Grundstruktur im Bereich Module vor:

+---modules             Beinhaltet alle verfügbaren Module des Systems. Hierher werden neue Module installiert.
¦   +---modulename      Verzeichnis eines Moduls
¦   ¦   +---model       Models (ActiveRecords/UnitsOfWork)
¦   ¦   +---view        View
¦   ¦   +---controller  Controller

5. Kapitel 5 - Das Framework und die einzelnen Core-Komponenten

In diesem Kapitel werden die einzelnen Bestandteile des Clansuite Frameworks erläutert. Dabei ist jeder Komponente des Systems ein eigener Abschnitt gewidmet. Du findest hier auch Definitionen und Erklärungen zu den verwendeten Entwurfsmustern und zum allgemeinen Systemaufbau, insbesondere zur Model-View-Controller Architektur (MVC) des Systems.

5.1. Das Clansuite CMS und das Clansuite Framework

Das Clansuite CMS basiert auf dem Clansuite Framework. Wir schreiben unser eigenes Framework, um den Aufwand zu minimieren, ständig neuen Code für das CMS entwickeln zu müssen. Die Verwendung des Frameworks minimiert die Anzahl der Codezeilen die geschrieben werden müssen, um bestimmte Ziele mit dem CMS zu erreichen. Viele Methoden werden einfach zur "standardisierten" Verwendung bereitgestellt. Das Clansuite Framework dient also dazu, die Standardaufgaben, die ein jedes CMS erledigen muss, vor die Klammern zu ziehen. Das CMS Clansuite ist als nutzerfreundliche fertige Anwendung gedacht, die lediglich konfiguriert werden muss. Dabei werden die einzelnen CMS Dienste werden durch Module bereitgestellt. Es ist für Erweiterungen und Plugins offen. Das Framework vereinfacht also die Entwicklung und gibt auch dem CMS eine bestimmte Struktur und Festigkeit.

Input-Transformation-Output (ITO) oder Eingabe-Verarbeitung-Ausgabe (EVA-Prinzip)

Die Hauptaufgabe einer Webapplikation liegt darin, einen gegebenen Input in einen Output zu transformieren. Der gegebene Input ist dabei regelmäßig eine URL. Der zu erzeugende Ouput ist regelmäßig der vom Webbrowser zu interpretierende und darzustellende Quelltext, beispielsweise im Format XHTML.

Input-Transformation-Output
Abbildung 4. Das Input-Transformation-Output Prinzip
MVC-Muster und die Schichten einer Applikation

Das Clansuite Framework ist dabei als ein einfaches und klassisches Model-View-Controller (auch MVC genannt) Framework konzipiert. Unter dem Model-View-Controller Aufbau versteht man den Einsatz von bestimmten Entwurfsmustern (Design Patterns), um eine Applikation in Schichten (auch Layers oder Tiers) zu trennen. Dieses Muster wurde entwickelt, um die Entwicklung im Bereich der Präsentationsschicht zu verbessern.

Das Model repräsentiert die Datenschicht. Regelmäßig wird innerhalb des Models eine Datenquelle angesteuert und ihre Daten zurückgeliefert. Die Datenquelle kann dabei eine Datenbank und ihre Tabellen oder eine XML- oder gar Textdatei sein.

Der View repräsentiert die Präsentationsschicht. Die Aufgabe der Präsentationsschicht ist es, die Daten, welche sie vom Model bzw. Controller angereicht bekommt, aufzubereiten und auf eine bestimmte Ausgabeart darzustellen. Zumeist arbeitet die Präsentationsschicht dabei mit sogenannten Ansichten (Views) die aus Vorlagen (Templates) bestehen. Das View Objekt lädt dann das vom Controller zugewiesene Template und gibt es aus. Als Ausgabeart kommt z. B. die Einbettung der Daten in XHTML-Quellcode Vorlagen in Betracht. Aber auch eine Ausgabe der Daten im Format PDF oder RSS ist Aufgabe der Präsentationsschicht.

Der Controller ist für die Annahme einer Anfrage an die Webapplikation und damit für die Geschäftslogik zuständig. Er untersucht die eingehenden Daten, welche regelmäßig in Form einer URI vorliegen, daraufhin, welche Ansicht der Präsentationschicht mit Daten bestückt werden muss. Dabei können Controller hierarchisch verbunden sein. Es entscheidet der erste Controller, welcher nachfolgende Controller für die Ansicht und ihre Daten zuständig ist. Der Einstiegspunkt in die Webapplikation ist dabei zumeist die zentrale Datei index.php. Die Datei ruft regelmäßig den Frontcontroller, also den Einstiegscontroller der Applikation auf, der einen Subcontroller, zumeist einen Modulecontroller oder direkt einen Actioncontroller aufruft. Der Modulecontroller repräsentiert die Geschäftslogik für alle Kommandos eines Moduls, also ein ganzes Kommandopaket. Der Actioncontroller repräsentiert die Geschäftslogik für ein einzelnes Kommando innerhalb einer Applikation. Der Frameworkaufbau von Clansuite untergliedert sich demnach in Komponenten der Präsentationschicht (Frontcontroller mit Interception-Filtern, Eventhandler, sowie Template-View und Viewhelper Muster), der Datenschicht (Active- Record Muster und objektrelationales Mapping mittels Doctrine) und der Geschäftslogik. Das besondere Kennzeichen der Schichtenarchitektur ist die Tatsache, dass das Model weder die Views noch den Controller kennt. Die Schichtentrennung ist wünschenswert, um die Hauptaufgaben einer Applikation austauschbar zu machen und getrennt voneinander bearbeiten zu können. Hinzu tritt die Tatsache, dass es sich beim MVC- Muster um eine Konvention, genauer um ein Ordnungsverfahren handelt, um die Arbeit mit komplexen Anwendungen zu erleichtern und beherrschbar zu machen. Bedenkt man, dass Softwaresysteme regelmäßig an geänderte Anforderungen angepasst werden müssen, dann ist der Siegeszug des MVC-Musters nicht verwunderlich. Die Applikationsschichten sind getrennt voneinander wartbar, veränderbar, ergänzbar und austauschbar. Insbesondere können die Schichten gleichzeitig und unabhängig voneinander bearbeitet werden. Dies sichert die benötigte Weiterentwickelbarkeit (Evolvability).

Model-View-Controller
Abbildung 5. Das Model-View-Controller Entwurfsmuster
Die Hilfskomponenten

Beim Framework sind neben den Mustern zur Umsetzung des MVC-Patterns noch die jeweiligen Hilfskomponenten zu nennen. Für jeden MVC Bereich gibt es eigene Hilfskomponenten. Die Hilfskomponenten im Bereich des Controllers sind zumeist Wrapperklassen, die Zugriffsmethoden auf fremde Bibliotheken bereitstellen. Ein Beispiel hierfür wäre die Klasse Clansuite_Mailer, welche den Zugriff auf die Bibliothek SwiftMailer ermöglicht. Das Versenden von Mails ist eine wesentliche, sich wiederholende Aufgabe. Der Mailer ist dafür verantwortlich, die notwendigen Methoden zum Versenden von E-Mails bereitzustellen. Nicht jedes CMS Modul sollte aber diese Funktionalität neu implementieren müssen, wenn das Versenden von E-Mails benötigt wird, daher wurde die Funktionalität (hier Controller-Logik) in die Hilfskomponente ausgelagert. Hilfskomponenten kommen dabei aber nicht nur im Bereich der Controller-Logik, sondern auch im Bereich des Views vor. Hier nennt man sie Viewhelper. Die Viewhelper enthalten, Sie ahnen es bereits, wiederholend einsetzbare Präsentations-Logik. Der Viewhelper "date" wird Sie beispielsweise dabei unterstüzen, den Datumsstring in das richtige Datumsformat umzuwandeln und anzuzeigen. Im Bereich des Models stehen Behaviors und Event-Callbacks über Doctrine zur Verfügung. Mit Behaviors ist es möglich, zwischen zwei oder mehreren Modellen gemeinsame Funktionalitäten bereitzustellen. Mit Event-Callbacks ist es möglich, sich an den Moment, genauer das Ereignis, der Datenablage dranzuhängen und gleichzeitig bestimmte andere Dinge auszulösen. Beispielsweise könnte man an das Ereignis afterDelete($userid) das Loggen der Löschung eines Usersaccounts anhängen.

Clansuite MVC Structure
Abbildung 6. Die MVC-Struktur im Überblick
Der Applikationsfluss im Überblick

Eine Anforderungen an die Applikation nach dem MVC-Modell kann in fünf grundlegende Schritte unterteilt werden:

  1. Ausgangspunkt ist der Empfang einer URL vom Client.

  2. Das Routingsystem analysiert die URL und identifiziert den Controllernamen und sucht das Controllerobjekt.

  3. Der Dispatcher ruft die Controllermethode auf dem Controllerobjekt auf.

  4. Auswählen der Ansicht und Holen der Modelldaten, die von der Controllermethode zu dieser Ansicht generiert werden.

  5. Das Rendern der Ansicht.

5.2. Architektur und Design des Frameworks

Das Framework ist objektorientiert programmiert (OOP) und folgt der Model-View-Controller Architektur (MVC). Es werden Entwurfsmuster eingesetzt (DP). Objekte sollen nach Möglichkeit funktional eigenständig sein (Lose Kopplung). Wir versuchen die Funktionalität der Komponenten mit Funktionstests zu sichern (TDD), siehe dazu auch Kapitel 9. Wir legen Wert auf schrittweises, inkrementelles Wachstum (commit often).

5.2.1. Programmierprinzipien

Lose Kopplung

Unter dem Begriff "Lose Kopplung" vesteht man in der objektorientierten Programmierung, die Verringerung von Abhängigkeiten zwischen Objekten. Abhängigkeiten zwischen Objekten entstehen, wenn ein Objekt auf einem weiteren Objekt eine Methode aufruft. Das Prinzip der "Lose Kopplung" besagt, dass Objekte möglichst eigenständig sein sollen. Die Befolgung dieses Prinzip hilft, Softwarefehler zu vermeiden, die aufgrund von Kopplungs- und Kommunikationsbeziehungen zwischen Objekten entstehen. Im englischen Sprachraum ist dieses Prinzip auch als das Gesetz von Demeter (engl. Law of Demeter) bekannt.

Im Programmierslang ist dieses Prinzip gemeint, wenn von den "schüchternen Objekten" (engl. shy-objects / shy-programming) gesprochen wird oder, im Bezug auf Objekte etwa Satze wie "Sprich nicht mit Fremden!" oder besser noch "Sprich nur mit Deinen Freunden!" (engl. only talk to your friends) fallen. Das Gesetzt von Demeter beinhaltet einige unbedenkliche Fälle von Abhängigkeiten zwischen Objekten. Eine Objektmethode darf demnach immer eigene, aber die Methoden eines anderen Objekts nur in 3 Fällen aufrufen: Fall 1:: Methodenaufruf auf dem eigenen Objekt Fall 2:: Methodenaufruf eines assoziierten/referenzierten Objekts Fall 3:: Methodenaufruf auf einem Objekt, welches durch Parameterübergabe in die Methode oder das Objekt gelangt ist Fall 4:: Methodenaufruf auf einem Objekten, welches die Methode selbst erzeugt hat

/**
 * Fall 1 - Es wird eine Methode auf dem eigenen Objekt aufgerufen.
 */
class KlasseA
{
    public function methode1()
    {
        $this->method2(); # Aufruf der objekteigenen Methode
    }

    public function methode2()
    {

    }
}

/**
 * Fall 2 - Es wird eine Methode auf einem Objekt aufgerufen,
 *          welches durch Parameterübergabe in die Methode oder das Objekt gelangt ist.
 */
class KlasseA
{
    public function methode1(KlasseB $b) # Das Objekt wird per Parameter übergeben.
    {
        $b->methode2(); # auf dem übergebenen Objekt erfolgt der Parameteraufruf
    }
}

class KlasseB
{
    public function methode2()
    {
    }
}

/**
 * Fall 3 - Es wird eine Methode auf einem assoziierten/referenzierten Objekt aufgerufen.
 */
class KlasseA
{
    private $b; # Instanz des Objekts KlasseB

    public function methode1()
    {
        $this->b->methode2(); # Aufruf der Methode methode2() auf Objekt B
    }
}

class KlasseB
{
    public function methode2()
    {
    }
}

/**
 * Fall 4 - Es wird eine Methode auf einem Objekt aufgerufen, welches die Methode selbst erzeugt hat.
 */
class KlasseA
{
    public function methode1()
    {
        $b = new KlasseB(); # Instanzierung von Objekt B
        $b->methode2();     # Aufruf der Methode methode2() auf Objekt B
    }
}

class KlasseB
{
    public function methode2()
    {

    }
}

Das Gesetz von Demeter entstand während des Demeter-Softwareprojekts an der University von Boston und wurde von Karl J. Lieberherr und Ian Holland im Jahr 1989 im Aufsatz "Assuring Good Style for Object-Oriented Programs" erläutert
[http://www.ccs.neu.edu/home/lieber/what-is-demeter.html]
. Wer erfahren will, warum das Gesetz nach der griechischen Göttin für Landwirtschaft und Fruchtbarkeit benannt wurde, der ist eingeladen im besagten Aufsatz nachzulesen.

Wie hoch der Grad an Kopplung ist, kann mittels statischer Quellcodeanalyse festgestellt werden. Regelmäßig gibt die Maßzahl names "LoD" einer Softwaremetrik an, wie hoch die Kopplung zwischen Objekten ist. In der Praxis ist es nicht immer sinnvoll dieses Prinzip vollständig zu beachten, da durch die Verringerung der Abhängigkeiten oft viele Wrapperklassen oder Weiterleitungsmethoden entstehen.

Schrittweises inkrementelles Wachstum

Das Framework wird schrittweise entwickelt. Dieses Verfahren wird auch durch das Demeter-Projekt nahe gelegt, wonach Software sich in ihrem Wachstum an der Natur orientieren sollte.

5.2.2. Dependency Injection und Inversion of Control

Das Dependency Injection Verfahren ist ein Entwurfsmuster zur Abhängigkeitsmittlung zwischen Objekten. Bei diesem Verfahren werden die von einem Objekt abhängigen Objekte erzeugt und in das Objekte injeziiert. Die Kenntnis der Abhängigkeiten wird aus dem Objekt in die Beschreibungsdatei ausgelagert.

Für eine umfassende Beschreibung des Dependecy Injection Verfahrens verweise ich auf den Artikel von Martin Fowler http://martinfowler.com/articles/injection.html.

5.3. Die Komponenten des Frameworks

5.3.1. Clansuite_Bootstrap

Bootstrapping bedeutet umgangssprachlich "Sich an den eigenen Haaren aus dem Sumpf ziehen". Diese Metapher geht auf eine Geschichte des Barons von Münchhausen zurück, der sich und sein Pferd allein durch die inneren Kräfte seines Arms aus dem Morast befreite, indem er sich an den Haaren herauszog.

Ein meiner Meinung nach besseres Bild für den Startprozess ist, das Anstoßen des ersten Dominosteins. Die Beschaffenheit des Dominosteins ist dabei relativ gleichgültig, solange er in der Lage ist seine Kraft an den nächsten Stein weiterzugeben. Es kann ein Buch oder ein Dachziegel sein. Es entsteht eine Kausalkette.

Im Kontext von Softwaresystemen steht Bootstrapping für die Technik hinter dem Startvorgang eines komplexeren Systems. Jeder kennt diesen Vorgang vom Starten des eigenen Rechners. Am Anfang muss dieser "Booten", hierbei werden grundlegende Operationen durchgeführt. Beispielsweise Hardware geprüft und initialisiert, damit diese dem Betriebssystem später zur Verfügung steht. Bootstrapping ist daher kein Anteil der eigentlichen Applikation, sondern bereitet nur deren spätere Lauffähigkeit vor. Läuft die Applikation einmal, braucht sie kein Wissen darüber, wie es eigentlich dazu gekommen ist.

Im Kontext von Webanwendungen beschäftigt sich Bootstrapping mit den zwingenden Systemanforderungen, beispielsweise der Prüfung auf die richtige PHP Version, das Laden von Extensions und Konfigurationsdateien, sowie dem Definieren von Konstanten. Ist dieser Vorgang abgeschlossen, wird die Kontrolle an die Applikation übergeben. Regelmäßig ist dies der Frontcontroller, der sodann mit der Abarbeitung des Requests beginnt.

5.3.2. Clansuite_Autoloader

Was macht überhaupt das Autoloading? Grundsätzlich ist ein Laden der entsprechenden Datei (require/include) mit der entsprechenden Klasse und die Instanzierung dieser Klasse notwendig. Das Autoloading zieht nun den ersten Schritt ab, indem anhand eines Klassennamens die richtige Datei geladen wird. Damit ist das grundlegende Problem beim Autoloading angezeigt: die Pflege einer Zuordnungstabelle (Autoloading-Map), die sowohl Datei- als auch Klassennamen beinhaltet und eine Suche der richtigen Datei anhand des Klassennames ermöglicht. Bei diesem Verfahren steht die Methode des require(dirname(FILE)..php) im Vordergrund. Hierbei wird explizit auf einen bestimmten Ort im Dateisystem verwiesen und dies unabhängig vom Klassennamen.

Für einen Programmierer ist Autoloading in gewisser Hinsicht bequem, da er nicht den Ort der Klasse wissen und sie nicht laden muss.

Regelmäßig enthalten die Klassennamen Unterstriche als logische Trennzeichen und geben damit die Verzeichnisstruktur an. Einfache Autoloadinglösungen verwenden daher im Kern immer str_replace(_,/, $classname). .php; um aus dem Klassennamen einen Dateinamen mit ausreichenden Pfadinformationen zu erzeugen.

    /**
     * An autoload function for MyApp
     * @param string
     */
    public static function MyAppAutoload($classname)
    {
        if (strpos($className, 'MyApp_') === 0)
        {
            $classname = substr($classname, 6);
            $path = str_replace('_', '/', $classname) . '.php';
            if (is_file(dirname(__FILE__) . '/' . $path) === true)
            {
                include dirname(__FILE__) . '/' . $path;
            }
        }
    }

Schwieriger wird es, wenn man Dateien nach ihrer Zugehörigkeit zu einer logischen Komponente ablegen möchte. Nun muss der Name der Komponente mit in den Klassennamen, um ihn in einen Dateinamen umwandeln zu können. Dies führt zu komponentenbasiertem Autoloading.

Ein weiteres Problem ergibt sich, wenn in einer Datei mehrere Klassen untergebracht sind. Hier kann nicht vom Klassennamen auf die Datei geschlossen werden.

Der extensiven Verwendung des Autoloadings mit langen Klassennamen wird nun durch die Einführung der Namespaces etwas entgegengewirkt. Hierdurch werden lediglich wiederkehrende Prefixes vom Klassennamen abgezogen und als Namespaces deklariert. Ebenso wird es nun möglich Slashes in den Namespaces zu verwenden. Dies geht bei Klassennamen nicht.

Die beste Autoloading Lösung besteht darin, im Voraus das komplette Dateisystem auf PHP Dateien und enthaltene Klassen zu scannen und eine Autoloading-Map zu erstellen. Professionelle Systeme integrieren diesen Schritt in den Build-Prozess der Applikation und lagern ihn somit aus der Applikation aus. Das Autoloading besteht bei dieser Lösung aus einem reinen Lookup des Klassennames in einem Array mit Klassennamen als Schlüsseln und Pfad- und Dateinamen als Werten.

Merksatz zum Thema Autoloading: Autoloading ist für Bequeme und Bequemlichkeit bringt Probleme.

Clansuite verwendet ein zweistufiges Autoloading. Im ersten Schritt wird versucht die Datei anhand des Klassennames zu finden. Sollte dies erfolgreich sein, wird die Klassenname-Datei-Beziehung in eine Autoloading Map eingetragen. Bei jedem weiteren Autoloading erfolgt dann nur noch ein Lookup und keine Auflösung des Klassennames in den Dateinamen. Die Namensauflösungsstrategie deaktiviert sich also schrittweise und geht in einen reinen Lookup-Betriebsmodus über.

5.3.3. Clansuite_HttpRequest

Die Klasse Clansuite_HttpRequest abstrahiert den Zugriff auf die Daten einer HTTP-Anfrage. Unter einer HTTP- Anfrage versteht man den gesamten eingehenden Datenstrom (auch Input genannt) einer Anwendung. Bei einer HTTP- Anfrage sind die Daten grundsätzlich über die superglobalen Variablen ($_REQUEST, $_POST, $_GET, $_COOKIE, $_SERVER, $_FILES und $_ENV) zu erreichen. Diese Variablen werden allerdings von PHP unbereinigt und als konkrete Implementierung bereitgestellt. Die Hauptaufgabe der Klasse Clansuite_HttpRequest besteht daher in der Bereinigung der superglobalen Variablen $_POST, $_GET, $_COOKIE, $_SERVER, $_FILES, $_ENV und dem Anbieten von Methoden zum Abruf der bereinigten Arrays, sowie in der Löschung der superglobalen Variable $_REQUEST. Die eingehenden Daten werden nicht direkt aus der PHP- Umgebung, sondern über einen Umweg, nämlich aus dem HttpRequest Objekt geholt. Ein direkter Zugriff auf die unbereinigten globalen Variablen (raw data) ist weiterhin möglich, sollte aber aus Sicherheitsgründen vermieden werden.

Clansuite HttpRequest Object
Abbildung 7. Das Clansuite_HttpRequest Objekt
Sicherheit mittels Clansuite_Doorkeeper

Des weiteren wird mittels der Klasse Clansuite_Doorkeeper (Türsteher) versucht Einbruchsversuche in die Webanwendung zu erkennen und potentiellen Eindringlingen den Zugang zum System zu verweigern. Als System zur Einbruchserkennugn wird das PHP Intrusion Detection System (PHPIDS) eingesetzt. PHPIDS wird seit Mai 2007 von Mario Heiderich, Christan Matthies und Lars Strojny entwickelt. Es untersucht die Benutzereingaben auf schadhafte Zeichen, Zeichenketten oder Skriptanteile. Erkannt werden XSS-Angriffe (Cross-Side-Scripting), SQL- Injektionsversuche (SQLI), Remote File Inclusions, Remote File Executions (RFE) und LDAP-Injektionen.

Bereitstellung der REST-Funktionalität

Eine weitere wesentliche Aufgabe ist die Bereitstellung der REST-Funktionalität. Die Abkürzung REST steht für den Fachbegriff "Representational State Transfer". REST ist ein Softwarearchitekturstil, welcher ein resourcenorientiertes Denken forciert und für verteilte Applikationen entwickelt wurde. Es ist absichtlich sehr einfach gehalten und basiert nur auf wenigen Grundprinzipien und wohldefinierten Methoden. Der Begriff wurde durch die Dissertation von Roy Fielding aus dem Jahr 2000 eingeführt
[Fielding, Roy Thomas: Architectural Styles and the Design of Network-based Software Architectures. PhD Thesis, University of California, Irvine, 2000, http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm]
. Fielding ist einer der Hauptautoren der Spezifikation des HTTP-Protokolls. Er ruft nochmals in Errinerung was die bestehende Mechanismen und Protokolle des WWW (z. B. HTTP) teilweise schon definieren. REST ist neben den Alternativen XML-RPC und SOAP eine Methode zur Umsetzung von Webservices und damit ein Schlüsselwort des Web2.0.

Rest-Grundprinzipien

Nachfolgend werden die Grundprinzipien von REST dargestellt.

1 Alles ist eine Resource

Eines dieser Prinzipien lautet "Alles ist eine Resource". Resource ist dabei jede Datenquelle. Einige werden hier eine Ähnlichkeit zum Linux-Prinzip "Alles ist eine Datei." feststellen.

2 Name (URI)

Jede Resource hat einen eindeutigen Namen.

3 Links

Jede Resource ist mittels eines Hyperlinks ansprechbar.

4 Verben (CRUD)

Die Methoden von REST sind einfache und selbstverständliche Verben. Für den Zugriff auf eine Ressource stehen die folgenden Methoden zur Verfügung: Create (POST), Read (GET), Update (PUT), Delete (DELETE).

5 Representation

Resourcen können mehrere Representationen haben. So kann die Ressource "Benutzerliste" sowohl in HTML, XHTML, CSV oder PDF repräsentiert werden.

6 Zustandslose Kommunikation (Skalierbarkeit)

Die Kommunikation mit dem Server einer Ressource beschränkt sich jeweils auf eine einzelne Anfrage. Der Server erwartet also keinen Kommunikationsvorgang bei dem Daten einer vorherigen Anfrage zwischengespeichert werden müssen. Letzteres würde dazu führen, dass mit steigender Anzahl an Anfragen die Serverlast steigt, da für jeden Client die Daten zwischen zwei oder mehreren Anfragen vorgehalten werden müssen. Berücksichtigt man nun die darunterliegenden zustandslosen Protokolle, wie HTTP und und fördert die Entdeckung und Verwendung der Resourcen. Führt dies dazu, dass wesentlich mehr Clients auf den Server zugreifen können, da die Serverresourcen geschont werden. Eine zustandslose Kommunikation erhöht also die Skalierbarkeit.

7 Schichtenaufbau

REST ist in Schichten aufgebaut. Dabei kann eine beliebige Anzahl an Zwischenebenen oder intelligenten Zwischendiensten, wie z. B. Caches, Proxies oder Gateways eingesetzt werden.


[Atom Publishing Protocol (RFC5023), http://www.ietf.org/rfc/rfc5023.txt]

[HTTP/1.1 Specifiction (RFC 2616), http://www.w3.org/Protocols/rfc2616/rfc2616.html]

[Yahoo! Group: rest-discuss, http://tech.groups.yahoo.com/group/rest-discuss/]

[http://restpatterns.org/]

[Alan Dean, http://www.simplewebservices.org/]

[Stefan Tilkov, http://rest-http.info/, Webseite zum Buch "REST und HTTP".]

[REST URL Conventions, http://microformats.org/wiki/rest/urls/]

Instanzierung

Die Klasse wird bei Systeminitialisierung dem Dependency Injector übergeben und steht sodann in dessen Registry zum Abruf bereit.

Das HttpRequest Objekt kann auf zwei Arten geholt werden. Erstens ist ein systemweiter Zugriff auf das Objekt durch den Zugriff auf den Dependency Injector gegeben.

# Holen des Objekts HttpRequest aus dem Dependecy Injector
$request = $this->injector->instantiate('Clansuite_HttpRequest');

Zweitens kann in einer Klasse sind die sich vom Modulecontroller ableitet (das wird regelmäßig ein ActionController sein) das Objekt mittels der Methode this→getHttpRequest() des ModuleControllers geholt werden. Diese Methode ist eine Befehlsabkürzung (engl. auch Shortcut, Proxy oder Convenience Methode genannt).

# Holen des Objekts HttpRequest innerhalb einer Kindklasse des ModuleControllers
$request = $this->getHttpRequest();
Verwendung
# Holen des Objekts für einmalige Verwendung und holen des Parameters "stadt" (Method Chaining/Fluent Interface)
$stadt = $this->getHttpRequest()->getParameter('stadt');

# Holen des Objekts HttpRequest (für mehrmalige Verwendung)
$request = $this->getHttpRequest();

# Holen des Parameters 'news_category_form' aus dem Request Objekt.
# Der Parameter wird aus dem Array $request_parameters des Request Objekts geholt.
$form = $request->getParameter('news_category_form');

# Holen des Parameters 'news_category_form' aus dem Request Objekt unter Angabe des Arraynames "REQUEST".
# Der Parameter wird aus dem Array $request_parameters des Request Objekts geholt.
$form = $request->getParameter('news_category_form', 'REQUEST');


# Holen des Parameters 'news_category_form' aus dem Request Objekt unter Angabe des Shortcuts "R" für den Arraynamen.
# Der Parameter wird aus dem Array $request_parameters des Request Objekts geholt.
$form = $request->getParameter('news_category_form', 'R');

# Holen des Parameters 'hausnummer' aus dem Request Objekt.
# Der Parameter wird mittels Shortcut "G" aus dem Array $get_parameters des Request Objekts geholt.
$haus_nr = $request->getParameter('hausnummer', 'G');

# Holen des Parameters ['news_form_categories]['cat_id'] unter Verwendung von ArrayAccess.
$cat_id = $request['news_form_categories]['cat_id];

Hinweis: der Zugriff auf mehrdimensionale Arrays wird durch die Verwendung von ArrayAccess erheblich vereinfacht. ArrayAccess bedeutet, dass ein Objekt und seine Eigenschaften auf die gleiche Art und Weise angesprochen werden können, wie ein Array. So können auch Unterarrays und deren Schlüssel einfach angesprochen werden. Bei Übergabe von mehrdimensionalen Formulardaten empfiehlt sich die Verwendung von ArrayAccess besonders.

# Das HTML-Formular beinhaltet ein Name-Attribut mit mehrdimensionalem Aufbau.
# Dadurch werden die Daten als mehrdimensionales Array an den Server geschickt.
<input type="text" name="formular[1][variablename]" value="0"/>

# Das Array hat die folgende Struktur:
array( [formular] => array ( [1] => array( [variablenname] => 'wert' ) ) )

# Der Zugriff auf die Inhalte von $request kann direkt über ArrayAccess durchgeführt werden:
$variablenname = $request['formular']['1']['variablenname'];

5.3.4. Clansuite_Doorkeeper

In unmittelbarem Zusammenhang mit den Sicherungs- und Bereinigungsfunktionen der HttpRequest-Klasse steht die Klasse Clansuite_Doorkeeper.

Instanzierung

Die Klasse wird innerhalb der HttpRequest-Klasse instanziert.

Verwendung

Die Hauptmethode dieser Klasse ist runIDS(). Sie bewirkt die Initialisierung und den Start des Intrusion- Detection-Systems (PHPIDS). Mehr über die Funktionsweise von PHPIDS erfahren sie im Kapitel 10.

5.3.5. Clansuite_HttpResponse

Die Klasse Clansuite_HttpResponse übernimmt die Funktion einer abstrakten Ausgabeklasse. Sie sendet die notwendigen HTTP-Header, aktiviert die GZip-Kompression und gibt den gesamten Content ($body) an den Client aus. Die Klasse ist für den Output zuständig.

5.3.6. Clansuite_Front_Controller

Verwendung

Was ist überhaupt ein Frontcontroller? Der Frontcontroller nimmt die Anfrage (Request) entgegen und leitet sie an den entsprechenden Module-Controller bzw. Action-Controller weiter.
[http://www.martinfowler.com/eaaCatalog/frontController.html, Martin Fowler - FrontController im eaaCatalog]

[http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html, J2EE Pattern FrontController]
Wenn eine Webanwendung nach dem FrontController Muster aufgebaut ist, dann erkennt man das meistens daran, dass zum Starten der Anwendung die zentrale "index.php" aufgerufen wird. Diese "index.php" wird dann mit Parametern ergänzt, die Modulecontroller und Actioncontroller angeben. Etwa "index.php?module=news&action=AlleNewsAnsehen".

Clansuite wird durch Aufruf der zentralen Einstiegsdatei "index.php" gestartet. Der Aufruf des Frontcontrollers erfolgt nach der Initialisierung des Systems in der Datei "/core/bootstrap/clansuite.application.php".

Die beiden Absätze in der Notiz haben wenig bis gar nichts mit dem Clansuite_Front_Controller zu tun. Sie sind vielmehr ein kleiner Exkurs in die Geschichte der Internetanwendungen und der Clanscripte. Wer nicht daran interessiert ist, kann sie daher auch gerne überspringen.

Anmerkung
Exkurs

Eine Alternative zur Verwendung eines Frontcontroller sind dezentrale Controller. Dazu muss eine Anwendung in dezentrale Bereiche untergliedert werden, die jeweils eine eigene Einstiegsdatei anbieten. In den Anfangstagen des persönlichen dynamischen Webs, so zwischen 1998 und 2004, waren dezentrale Controller der Normalfall. In dieser Zeit hat man eine dynamische Webseite zumeist aus mehreren Skripten zusammengestellt. So verwendete man ein Skript für die News und ein Skript für das Gästebuch. Jedes dieser Skripte wurde in einem eigenen Verzeichnis untergebracht und über einen eigenen Controller aufgerufen. Die URL sah typischerweise wie folgt aus: "/news/index.php" oder "/guestbook/index.php". Häufig hat man dann versucht, die verschiedenen Skripte irgendwie miteinander zu verbinden, um sich beispielsweise nicht bei jedem einzelnen Skript zur Administration anmelden zu müssen.

Im Clanbereich war das dezentrale Controller-Musters auch anzutreffen. Ein damals bekanntes Clanscript mit dezentraler Controllerstruktur war das "TClanPortal" von Martin Weitzel (aka TriggerTG). Es war auch bekannt unter dem Namen "TriggerTG’s Clanportal" und stand auf den Domains http://www.clanportal.org/ und http://www.triggertg.de/ zum kostenlosen Download bereit. Das System war, obwohl es zahllose Sicherheitslücken gab, recht begehrt in der Szene und verbreitete sich rasch. Die Entwicklung wurde im Jahr 2004 aus Zeitgründen eingestellt. Die letzten Version war 1.1.3. Frank Hermann (aka Devil) nahm schließlich die Weiterentwicklung des Systems auf. Heute ist es besser bekannt unter dem Namen "Devil’s Clanportal", abgekürzt DZCP. Die dezentrale Controller-Struktur ist auch in der aktuellen DZCP Version 1.5.1 im Jahr 2010 immernoch im Einsatz.

Inzwischen sind dezentrale Controller durch die Verwendung des Frontcontroller-Musters verdrängt worden. Einzelne Skripte sind kaum noch anzutreffen und ihre Funktionalität wird heute zumeist durch die jeweiligen Module einer Webanwendung repräsentiert.

Clansuite Simple Frontcontroller Workflow
Abbildung 8. Ein einfacher Frontcontroller

Was ist ein ModuleController bzw. ApplicationController? Bei Clansuite nennen sich ApplicationController ModuleController. Sie sind zuständig für einen kompletten Teilbereich des CMS. Beispielsweise das Modul zur Verwaltung von Artikeln (News).
[http://www.martinfowler.com/eaaCatalog/applicationController.html]

Was ist ein ActionController? ActionController ist ein Kommando der Applikation. Beispielsweise das Kommando action_show() im Modul News. Wird dieses Kommando ausgeführt, so bewirkt es die Anzeige aller gespeicherten Artikel des News-Moduls.

Clansuite setzt nicht nur einen einfachen FrontController ein. Der FrontController, mit seiner Hauptmethode processRequest(), wird durch Vor- und Nachfilter erweitert. Siehe dazu unter Clansuite_Filtermanager.

Clansuite Frontcontroller Start
Abbildung 9. Das Clansuite Frontcontroller Objekt

Dieses Bild zeigt das Frontcontroller Objekt nach dem Aufruf der Methode Clansuite_CMS::execute_Frontcontroller() innerhalb von /bootstrap/clansuite.application.php.

Dem Frontcontroller werden HttpRequest und HttpRepsonse Objekt übergeben. Die in einem Konfigurationsarray befindlichen Vor- und Nachfilter werden dem Frontcontroller mittels der Methoden addPreFilter() und addPostFilter() hinzugefügt. Durch Aufruf der Methode processRequest($request, $response) werden Request und Response Objekt an den Frontcontroller übergeben. Die weitere Bearbeitung des Requests obliegt nun dem Frontcontroller.

Der Ablauf im Frontcontroller - Clansuite_Front_Controller::processRequest()
1. Vorfilter abarbeiten
2. Event auslösen "onBeforeDispatcherForward"
3. Forward bewirkt den Aufruf des ModuleControllers und ActionControllers
4. Event auslösen "onAfterDispatcherForward"
5. Nachfilter abarbeiten
6. Absetzen der Ausgabe über das HttpRepsonse Objekt

Das Schema verdeutlich, wie die Methode processRequest() des Frontcontroller vorgeht. Funktionaler Kern ist der Aufruf der Methode forward() (3). Der Aufruf wird umlagert von der Ausführung der Vor- und Nachfilter und einer Ereignissteuerung. Die Abarbeitung der Vorfilter (1) bewirkt möglicherweise eine Modifikation des Request Objekts. Die Abarbeitung der Nachfilter (5) bewirkt möglicherweise eine Modifikation der Ausgabe bevor sie ins Response Objekt gegeben wird. Die beiden Ereignisse "onBeforeDispatcherForward" (2) und "onAfterDispatcherForward" (4) stellen Anknüpfunkgspunkte für die ereignisbasierte Steuerung und Veränderung der Objekte bereit.

Ingesamt geht es darum, aus dem eingehenden Request die richtigen Controller herauszufinden und weiterzuleiten. Diese Aufgabe wird jedoch nicht im Frontcontroller erledigt, sondern innerhalb des Vorfilters "routing". Die Abarbeitung dieses Vorfilters ist also zwingend. Nach der Verarbeitung dieses Vorfilters, wurden die richtigen Controller bestimmt und in der TargetRoute abgelegt. Diese kann über das Request-Objekt abgefragt werden.

Um die Ausgabe zu bewirken (6), ruft der Frontcontroller die Methode sendResponse() des HttpResponse Objekts auf.

5.3.7. Clansuite_Filtermanager

Der Filtermanager ist eng mit dem Frontcontroller verwoben. Jedem Aufruf der Hauptmethode processRequest() des Frontcontrollers können ein oder mehrere Vorfilter vorgeschaltet oder ein oder mehrere Nachfilter nachgeschaltet werden. Um diese Funktionalität im Frontcontroller abzubilden wurden die zwei Variablen $preFilters und $postFilters erstellt, welche jeweils eine Instanz des Filtermanager Objekts enthalten. Der Filtermanager stellt nur sehr wenige Methoden bereit. Hauptsächlich geht es darum Filter zu registrieren und auszuführen. Zum einen stellt er die Methode addFilter() bereit. Mit ihr lassen sich neue Filter hinzuzufügen. Sie akzeptiert Objekte, welche das Filter Interface implementieren, und somit vom Typ Filter sind. Die Hauptmethode des Filtermanagers ist processFilters(). Sie iteriert über alle registrierten Filter und führt sie aus. Die Iteration folgt dabei der Reihenfolge der Registrierung.

Entwurfsmuster

Frontcontroller

Die Klasse Clansuite_Filtermanager ergänzt den Frontcontroller. Der Frontcontroller kann eine Anfrage nur an den ModuleController und weitere Untercontroller weiterreichen, um sie zu beantworten. Neue Funktionen könnten nur durch Änderung eines bestehenden oder hinzufügen eines neuen Controllers geschaffen werden.

Interception-Filters

Das Entwurfsmuster Intercepting-Filter hilft weiter.
[http://java.sun.com/blueprints/corej2eepatterns/Patterns/InterceptingFilter.html]
Damit lässt sich die Hauptmethode processRequest() mit einem Vorprozess und einem Nachprozess umhüllen. Ein Vorprozess ist in der Lage die Anfrage zu verändern. Ein Nachprozess ist in der Lage die Ausgabe zu beeinflussen. Dadurch können beliebig viele Filter hinzugefügt oder wieder entfernt werden, ohne den Code des Frontcontrollers ändern zu müssen.

Beim Intercepting-Filter-Musters implementiert jeder Filter das Filterinterface. Die Filter sind wiederverwendbar, sequenziell aufrufbar und lose an die Geschäftslogik und andere Filter gekoppelt. In der Java-Welt gibt es seit Version 2.3 der Servlet Spezifikation, ein Standardinterface Filter
[http://java.sun.com/products/servlet/Filters.html]
. Eine Intercepting-Filter-Implementation als Teil der PHP-SPL sucht man leider vergeblich.

Clansuite Frontcontroller with Interception Filters
Abbildung 10. Der mit Interception-Filtern erweiterte Frontcontroller
Das Filter Interface

Jeder Filter implementiert das Filter Interface (implements Clansuite_Filter_Interface). Damit wird sichergestellt, dass der konkrete Filter alle Methoden eines abstrakten Filters bereitstellt. Dazu gehört inbesondere das Vorhandensein der Hauptmethode executeFilter().

Übersicht zu den Filtern
Vorfilter
  1. Theme_via_get

  2. Language_via_get

  3. Statistic

  4. Startup_checks

  5. Set_modulelanguage

  6. Maintenance

  7. Ajax Request

  8. Get User

  9. Permissions

  10. Php_debug_console

  11. Session security

  12. Process cronjobs

Nachfilter
  1. Html Tidy

  2. Smarty Moves

Tipp Die Erstellung eines Filters um den Output zu komprimieren ist nicht erforderlich. Diese Aufgabe wird durch die Klasse Http_Response gehandhabt.

5.3.8. Clansuite_Configuration

Verwendung
$config = $this->config->readConfig( ROOT_MOD . '/news/news.config.php');
# Der obige Aufruf entspricht dem im Modulecontroller verfügbaren Shortcut-Kommando:
$config = $this->getModuleConfig();
Die Konfigurationsadapter
Der Konfigurationsadapter YAML
Allgemeines zum YAML-Format

Das YAML Konfigurationsformat ist relativ minimalistisch und basiert auf Textdateien. Die offiziellen Webseite definiert YAML (YAML Ain’t Markup Language), als einen menschenlesbaren, programiersprachenübergreifenden Standard zur Datenserialisierung. Es wurde entwickelt, um die Lesbarkeitsschwierigkeiten aufgrund von Klammerung und Verschachtelung bei PHP-Arrays und anderen Ausdrucksmitteln für Konfiguration zu umgehen. Ziel war eine Konfigurationsprache zu schreiben, die auch für Nicht-Programmierer lesbar und einfach einzusetzen ist. Die offizielle Webseite ist http://yaml.org/. Die Spezifikation von YAML Ain’t Markup Language vor finden sie unter http://www.yaml.org/spec/1.2/spec.html. Seit dem 1.Oktober 2009 liegt nunmehr die Version 1.2 der Spec vor.

Beim YAML-Format wird durch Einrückungen des Text eine Struktur erzeugt. Um eine Textdatei des YAML-Formats zu lesen und die in ihr enthaltenen Zeichenketten wieder in eine Arraystruktur mit Schlüsseln und Werten zu verwandeln ist ein Parser notwendig. Der YAML-Parser wertet dabei insbesondere die zur Strukturierung des Konfigurationstextes dienenden Leerzeichen aus.

Vergleich der Konfiguration mittels PHP-Array und YAML
# definition als php-array
$configuration = array(
    'konfigurationssektion' => array(
                                     'element1' => 'wert1',
                                     'element2' => 'wert2',
                                     'element3' => 'wert3'
                                    )
                      );

# definition als yaml

konfigurationssektion:
  element1: wert1
  element2: wert2
  element3: wert3

Das YAML-Format wurde in der PHP-Welt insbesondere mit Aufkommen des PHP-Frameworks Symfony sehr populär, wo es standardmäßig eingesetzt wird. Der dort entstandene Parser implementiert einen Großteil der YAML 1.1 Spezifikation und wird als eigenständige Bibliothek sfYaml weiterentwickelt. Fabien Potencier der Symfony-Gründer wird nicht müde, diese Klasse und das Format zu bewerben.

Ein Serialisierungsformat das auf YAML beruht ist JSON.

Tipp Wer YAML sagt, meint auch oft das von Dirk Jesse entwickelte (X)HTML/CSS Framework mit dem Namen "Yet Another Multicolumn Layout". Es ist ein sehr komfortables Layoutgerüst unter CC-A 2.0 Lizenz. Sie finden das YAM-Layoutprojekt unter http://www.yaml.de/ und weitere Projekte des Autors unter http://www.highresolution.info/webdev/.
Arbeitsweise des Konfigurationsadapters YAML

Der Konfigurationsadapter YAML erweitert die Basisklasse Clansuite_Config_Base und implementiert das ArrayAccess Interface. Die beiden Hauptmethoden sind readConfig() und writeConfig(). Nach erfolgreichem readConfig() kann ein Zugriff per ArrayAccess erfolgen. Es ist ein Wrapper der zwei Parser-Bibliotheken umspannt. Primär untersützt der Wrapper die in C-geschriebene PHP-Extension SYCK. Diese ist über PECL verfügbar. Sollte diese PHP-Extension nicht verfügbar sein, so wird sekundär, auf die PHP-Bibliothek SPYC zurückgegriffen. SPYC muss dazu in das Verzeichnis /libraries/spyc/ installiert werden.

Der Konfigurationsadapter DB
Der Konfigurationsadapter INI
Der Konfigurationsadapter XML

5.3.9. Clansuite_Renderer

Für die Präsentationsschicht ist die Klasse Clansuite_Renderer zuständig. Diese ist Bestandteil des Applikationskerns.

Jeder Rückgabewert des Systems ist ein Output und wird über die Response-Klasse abgewickelt. Nur Fehlerausgaben werden nicht über die Response-Klasse, sondern direkt ausgegeben. Die Contentzuweisung an die Response-Klasse wird durch eine Methode zur Ausgabevorbereitung veranlasst. Diese setzt regelmäßig eine bestimmte RenderEngine ein, um den Output aufzubereiten. RenderEngines umfassen dabei Ausgabeformate und TemplateEngines. Hinzu kommt die direkte Ausgabe mit PHP und über den HTTP-Header.

Folgende Ausgabeformate werden zur Zeit von Clansuite unterstützt: CVS, JSON, PDF, Serialized.

Folgende Template-Engines werden unterstützt: PHPTAL, Smarty, XSLT, Xtemplate. Die standardmäßige Template-Engine ist Smarty.

Es ist möglich die PHP Renderer Klasse zu verwenden, um ohne eine TemplateEngine zu arbeiten. Desweiteren ist es möglich Einfluß auf den HTTP-Header zu nehmen, um Daten zu senden. So beispielsweise beim Logger Firebug.

Ausgabetypen
Abbildung 11. Ausgabemöglichkeiten
Entwurfsmuster

Das zugrundeliegende Entwurfsmuser für das Ausgabeverhalten von Clansuite nennt sich Two-Step-View. Dabei werden zuerst Inhalte gerendert und diese danach in das Layout eingesetzt. Dieses zweischrittige Verfahren ermöglicht, dass zusätzliche Elemente wie JavaScript und CSS in das Layout in Abhängigkeit vom Inhalt eingebunden werden können.

Die einzelnen RenderEngines werden über eine Fabrikmethode aufgerufen. Eine Schnittstelle sichert, dass die Klassen im Kern die gleichen Methoden bereitstellen.

Die RenderEngine Adapter
Der Renderer CVS

Der Renderer CVS nimmt Daten auf und gibt sie in der Form als komma-getrennte Werte zurück. CVS steht für die Abkürzung für Comma-Separated Values und ist ein Dateiformat (.csv). Es wird in der Spezifikation RFC 4180
[http://tools.ietf.org/html/rfc4180]
näher beschrieben, aber ein Standard exisitert nicht. Gerade dies macht das Wiedereinlesen einer CVS-Datenstruktur relativ schwer, da jeder auf seine Weise strukturieren kann.

Der Renderer JSON

Der Renderer JSON nimmt Daten auf und gibt sie serialisiert im Format JSON zurück. Die Serialisierung erfolgt mittels der PHP Extension JSON, die nunmehr seit PHP-Version 5.2.1 standardmäßig vorhanden ist.

Allgemeines zu JSON (JavaScript Object Notation)

JSON steht für JavaScript Object Notation und ist ein Datenaustauschformat. Es ist eine Untergruppe des YAML-Formats und beschrieben in RFC 4627
[http://www.ietf.org/rfc/rfc4627.txt?number=4627]
. Populär wurde es durch die Verbindung und Nutzung mit Ajax. Zwar kommt auch XML als ein Tauschmittel für Ajax in Betracht, doch sind XML-Baumstrukturen nur schwer lesbar und größer. JSON kann eine Vielzahl von Datenstrukturelementen aufnehmen und abbilden. Das entstehende Objekt eignet sich zum Transport und die enthaltenen Daten können einfach addressiert werden.

Tipp Ein oft gemachter Fehler ist, JSON mit einem JavaScript Array gleichzusetzen. Der feine Unterschied besteht darin, dass JSON eine Objekt-Notation ist, die wie ein Array addressiert werden kann.

Es gibt in der PHP-Welt zahlreiche Klassen um JSON zu parsen. Aber man braucht sich nicht wundern, dass der PHP eigene Parser schneller ist, als alle in PHP geschriebenen Parser. Schließlich ist er in C implementiert. Ein Vergleich zahlreicher Parser-Klassen bestätigt diesen Fakt.
[http://gggeek.altervista.org/sw/article_20061113.html]

[http://gggeek.altervista.org/sw/article_20070425.html]

Der Renderer PDF
Der Renderer PHP

Die Meinungen über natives PHP Rendering sind vielfältig. Für einige ist die direkte Ausgabe mit PHP der heilige Gral der PHP-Welt, den es zu behüten gilt. Andere sehen die Sache weniger glaubensverklärt und konstatieren, dass man es wohl auf "die alte Art" oder aber auf "die Neue" machen könne. Wieder andere sind aufgeklärt und vertreten ein vollständiges Trennungsprinzip und betrachten "die alte Art" als altmodisch.

PHP wurde einst als Templateskriptsprache entwickelt, um statische Seiten mit dynamischen Elementen anzureichern. Und eine Reihe anderer Sprachen, wie ColdFusion, ASP und JSP sind zeitgleich entstanden und verwenden das gleiche Prinzip. Wenn man so will, dann war die Templateengine PHP der Versuch, die Lücke zwischen C und HTML zu verkleinern. Doch im Laufe der Zeit wurde PHP um immer mehr Sprachmerkmale und Funktionen erweitert. Je mehr Sprachfeatures und Funktionen eine Skript- bzw. Programmiersprache bereitstellt, desto mächtiger ist sie. Fraglich ist, ob man diese Macht auf Templateseite haben möchte.

Wer von Templateseite spricht, hat das Trennungsprinzip zwischen Programmseite (PHP) und Templateseite (HTML) im Hinterkopf. Wer dieses Prinzip nicht kennt oder kennt und ablehnt, vertritt die Ansicht, dass HTML und PHP stets vermischt werden sollten, um die Ausgabe zu erzeugen. Dies ist die ursprüngliche, alte Art und Weise mit PHP zu entwickeln. Wer das Trennungsprinzip von HTML und PHP verinnerlicht hat, der mag beim Anblick einer Vermischung von HTML und PHP erhebliche Qualen empfinden. Bei Manchen gilt letzteres als eine spezielle Form des Spagetticodes mit Webgeschmack.

Wer von Templateseite spricht, kann aber auch das Trennungsprinzip zwischen Geschäftslogik (business logic) und Präsentationslogik (presentation logic) meinen. Diese Trennung bedeutet nicht unbedingt die Trennung von PHP und HTML. Denn Präsentationslogik ist alles, was nicht Geschäftslogik ist. Für das Trennungsprinzip zwischen Geschäfts- und Präsentationslogik sprechen die Arbeitsteilung zwischen Programmierer und Webdesigner, sowie die Wiederverwendbarkeit, Kapselung, Klarheit und Bearbeitbarkeit mit einem HTML-WYSIWYG Werkzeug. Der Quellcode wird zudem besser wartbar, leichter austauschbar und kann parallel bearbeitet werden.

Eine Template Engine sollte die Trennung von Geschäftslogik und Präsentationslogik untersützen. Was bedeutet dabei eigentlich "unterstützen"? Unterstützen bedeutet, dass zu jeder Zeit die Möglichkeit besteht, die Trennung zu beachten und mehr PHP Funktionen zum Einsatz zu bringen. Doch warum sollte man eine Template Engine einsetzen? Weil Template Engines den Bereich der Präsentationslogik von Haus aus und ohne weiteres Zutun abdecken. Es sind fertige, einsatzbereite und erweiterbare Präsentationsframeworks.

Gegen die Verwendung von Templateengines gibt es zahlreiche Argumente. Oft wird entgegengehalten, dass man alles, was man mit einer Templatesprache machen könne, auch mit PHP selbst machen kann. Und zwar viel besser, weil man mehr Funktionen zur Verfügung hat. Eine Templatesprache, wie z.B. Smarty, ersetzt die PHP-Kommandos lediglich durch andere, nämlich Smarty-Befehle. Diese Templatesyntax zu lernen sei lästig und zeitraubend. Oft gehört ist daher auch das faktisch richtige Argument, dass eine Templatesprache doch eigentlich nur unnötigen Overhead erzeugt. Trefflich streiten, lässt sich allein über die Frage, ob dieser Overhead nötig ist.

Eine Templateengine schränkt den zur Verfügung stehenden Befehlssatz ein. Für einen Webdesigner ist sie daher immer einfacher einzusetzen als natives PHP. Das wichtigste Argument für eine Templateengine ist daher: Sicherheit durch einen eingeschränkten Befehlssatz.

Ich vertrete die Auffassung, dass PHP von Haus aus einen Template-Modus mitbringen sollte. Der Template-Modus könnte beispielsweise durch die Verwendung des Tokens <?phpt aktiviert werden. Hierdurch würde ein deutlich reduzierter, sicherer Befehlssatz für den Einsatz in Templates verfügbar. Den entsprechenden Befehlssatz könnte man in der php.ini durch Whitelisting festlegen.

Dieses Verfahren hat einige Vorteile. Erstens wäre dieser Ansatz in C-implementiert und daher sehr schnell. Zweitens ist dies ohne großen Aufwand zu erreichen, denn es werden lediglich bereits vorhandene Konfigurationskommandos eingesetzt, um den Befehlssatz einzuschränken. Drittens könnte dadurch eine bessere Standardisierung von PHP-Templates erreicht werden, als durch ständige Rewrites bekannter Engines oder überflüssige Neuerfindungen des Rades (zuletzt beispielhaft dafür Symfonys Twig).

<?phpt
 /**
  * PHP im Template Modus mit eingeschränktem Befehlssatz
  */
?>

Nebenbei: Diese Diskussionslinie existiert zwischen nativem PHP Rendering und Templateengines, als auch zwischen Templateengines und XSLT Rendering.

Der Renderer PHPTAL

PHPTAL ist eine kompilierende und cachende Templateengine. Die Abkürzung PHPTAL steht für "PHP Template Attribute Language". Es ist eine PHP-Portierung der Templatesprache des Zope-Servers (Zope Page Templates, ZPT)
[http://zope3.mpg.de/cgi-bin/twiki/view/Zope/PageTemplate]

[http://docs.zope.org/zope2/zope2book/AppendixC.html]
. Im Vordergrund steht dabei die Generierung von XML und XHTML.

Die TAL-Syntax wird in der Template Attribute Language Expression Syntax (TALES) beschrieben
[http://wiki.zope.org/ZPT/TALESSpecification13]
. Die Besonderheit von TAL liegt in der Verschiebung von Viewhelper-Actions in XHTML Attribute
[http://zope3.mpg.de/cgi-bin/twiki/view/Zope/TaLes]
. Bei anderen Templatesprachen verwendet man hingegen immer Tags oder Elemente. Es ist theoretisch möglich eine andere Syntax als TAL zu verwenden, denn die als Attributwerte verwendbaren Ausdrücke werden durch METAL (Macro Expansion Template Attribute Language) beschrieben. In der Praxis erweitert man TALES einfach.

Der Quellcode von PHPTAL wird stetig verbessert und ist unter der GNU/LGPL lizensiert.

Der Renderer Serialized

Der Renderer Serialized bewahrt den Typ und die Struktur der übergebenen Werte und ermöglicht so eine speicherbare Repräsentation der Ausgabe. Die Ausgabe ist eine reine Byte-Stream-Repräsentation und kann durch Unserialisierung wieder in den PHP-Wert zurückverwandelt werden.

Der Renderer Smarty
Der Renderer XSLT

XSLT steht für XSL Transformations und ist in der gleichnamigen W3C Recommendation vom 16 November 1999
[http://www.w3.org/TR/xslt]
beschrieben. XSLT beschreibt die Semantik zur Transformation von XML Dokumenten in andere XML Dokumente. PHP stellt die Transformationsfunktionalität in der Erweiterung XSL bereit. Eine PHP-Bibliothek zur Transformation ist daher nicht erforderlich. Der Clansuite_Renerer XSLT stützt sich auf diese PHP XSL Erweiterung.

Sie bietet die Möglichkeit PHP–Funktionen im XSL–Template aufzurufen. Die PHP-Funktionen lassen sich mit der Methode registerPHPFunctions() festlegen. Somit können eigene Viewhelper auch nachträglich problemlos hinzugefügt werden. Wer mit Smarty entwickelt hat, der wird dieses Verfahren wiedererkennen. Es entspricht der Registrierung von Smarty-Plugins.

Das der XSL Transformation zugrundeliegende Entwurfsmuster nennt sich daher auch Transform View. Der Unterschied zwischen Template View und Transform View besteht darin, dass ein Template View direkt mit den Elementen des Outputs arbeitet, während der Transform View indirekt, nämlich mit den zu transformierenden Elementen arbeitet und diese erst noch in direkten Output umwandeln muss.

Zuerst wird ein DomDocument erstellt, wobei die Formatierungsdaten aus einer XSL-Datei kommen. Dann wird das DomDocument mit einer XML-Datei zusammengeführt und zur Ausgabe transformiert. Letzteres erfolgt mittels der Methode transformToXML().

Durch Verwendung von PHP in XSLT erhöht sich die Flexibilität im View. Gleichzeitig bietet dieses Verfahren Sicherheit, da nur bestimmte, vorher registrierte PHP-Funktionen zur Verfügung stehen.

Der Renderer Xtemplate

5.3.10. Clansuite_Cache

Die Klasse Clansuite_Cache ermöglicht die Zwischenspeicherung von Daten im Rahmen eines Applikations-Caches. Eine Zwischenspeicherung bietet sich bei Daten an, die in ihrer Herstellung rechenintensiv sind oder sehr häufig verwendet werden. Durch das Vorhalten im System sind sie bei Bedarf schnell erneut abrufbar. Dazu kann auf verschiedene Cache-Adapter zurückgegriffen werden. Die unterschiedlichen Cache-Adapter dienen einerseits dazu unterschiedliche PHP-Extensions zu unterstützen, andererseits aber auch dazu die Art und den Ort des Zwischenspeichers genauer zu bestimmem. Als Ablageorte kommen der Hautpspeicher und Festplatte in Betracht.

Überblick PHP Caching-Extensions

Für PHP lassen sich inzwischen verschiedene Caching-Extensions finden. Anzuführen sind beispielsweise die Standardbibliotheken Alternative PHP Cache (APC) und WinCache, sowie Memcached, eAccelerator, XCache, ionCube Loader (früher PHP Accelerator) und Zend Optimizer. Gemeinsam ist diesen Erweiterungen, dass sie in C implementiert sind und direkt an der ZendEngine ansetzen, um eine Leistungssteigerung zu bewirken. Die Leistungssteigerung bewirkt regelrechte Performcesprünge. Dabei sind Performcesprünge von 200% bis 500% durchaus mess- und beobachtbar.

Zudem bewirkt der Einsatz dieser Caches, dass sich die Load des Webservers deutlich spürbar mindert. Der leistungssteigernde Caching-Effekt lässt sich durch einfaches Aktivieren der Erweiterung herbeiführen. In wenigen Fällen sind umfangreiche Konfigurationsmaßnahmen nötig, zumeist bewirkt schon der Betrieb mit Standardeinstellungen einen deutlichen Performaceboost. In der Regel ergibt sich kein Grund dafür, auf eine solche Erweiterung zu verzichten. Dennoch ist bei vielen Webhoster dieses Feature deaktivert und erst auf Nachfrage verfügbar.

Das Gegenteil zu Caches, die als PHP-Extension eingebunden werden, sind die sogenannten Userland-Caches. Dabei handelt es sich um Caching-Verfahren die vom Nutzer selbst erstellt wurden und daher in PHP implementiert sind. Es lassen sich beispielsweise generierte Grafiken oder Rückgabewerte von Funktionsaufrufen zwischenspeichern.

Sowohl ZendGuard, als auch ionCube Loader bieten neben der Caching-Funktionalität auch die Möglichkeit, den Sourcecode in einer geschützen, verschlüsselten Form abzulegen. Bei einem quellcode-offenen Produkt wie Clansuite, steht der Einsatz dieser Techniken aber außer Frage.

Überblick Caching-Mechanismen

Grundsätzlich lassen sich mehrere Anknüpfungspunkte für Caching-Systeme in PHP finden. Zu den bekannteren Verfahren gehört das Opcode Caching.

Was macht ein OpCode-Cache?

Normalerweise wird bei jedem Aufruf eines PHP-Skriptes zuerst das Skript kompiliert (d.h. es wird aus der Skriptsprache in Maschinencode überführt) und dann ausgeführt. Das kostet Zeit und verbraucht wertvolle Rechenleistung. Dieses Verhalten ist eine Eigenart der in PHP geschriebenen Webanwendungen. Webanwendungen auf Basis anderer Architekturen, beispielsweise Java implementierte, halten die Anwendung und auch komplexe Objektmodelle und Daten persistent verfügbar (siehe Java-EE-Server; Enterprise JavaBeans).

Verwendet man hingegen einen OpCode Cache, so wird ein Skript zuerst kompiliert und danach kompiliert im Speicher (shared memory / RAM) gehalten. Dieser "PHP Zwischencode" wird zumeist heftig optimiert abgelegt. Jeder weitere Aufruf des Skripts wird danach aus dem Speicher bedient und spart Kompilierungszeit. Man kann Programmquellcode, aber auch die zur Laufzeit des Programms anfallenden Dateninhalte, zumeist Variablen, im Cache ablegen.Wenn Variablen vom Nutzer im Cache abgelegt werden, spricht man vom User-Cache.

Daneben gibt es weitere Caching-Mechanismen, beispielsweise das File Caching. Beim File Caching werden eine oder mehrere Dateien zusammengefasst und für einen schnelleren späteren Zugriff abgelegt. Des Weiteren gibt es das sogenannte "Resolve File Path Caching", hierbei kommt ein Mapping Verfahren zum Einsatz, bei dem für den relativen Dateipfade der jeweilige absolute Dateipfad abgelegt wird, so dass später eine erneute Pfadauflösung entfallen kann. Ein sogenannte "Session Handling Cache" legt die Sessiondaten, genau wie der User Cache, im Shared Memory ab.

Der optimale Wert für die Größe des Cache-Speichers hängt natürlich vom tatsächlich verfügbaren RAM ab. Wer zu hohe Cachewerte einstellt, zwingt den Server möglicherweise dazu, andere Sachen aus dem Speicher auszulagern.

Bevor in letzter Instanz auf die Leistungssteigerung durch einen vorkompilierenden Cache zurückgegriffen wird, sei allen Entwicklern geraten, zunächst die eigene Applikation und Datenbank auf den Prüfstand zu bringen, um Leistungsbremsen zu erkennen und zu beheben.

Entwurfsmuster

Als Entwurfsmuster kommt eine Fabrik zum Einsatz. Die Fabrik liefert lediglich den Cache-Adapter aus, den der Nutzer in der Konfiguration festgelegt hat.

Die Cache-Adapter

Die Cache-Adapter sind dabei einfache Wrapper, die lediglich den Zugriff auf die Methoden der Caching- Extensions abstrahieren und standadisieren. Die Unterstützung für ein neues Caching-System ist durch einfaches Hinzufügen eines entsprechenden Adapters problemlos möglich.

Der Cache-Adapter APC

Der Alternative PHP Cache (APC) ist ein Opcode Cache. Er cached und optimiert den PHP Quellcode und stellt ihn als "Zwischencode" bereit.

Der Cache-Adapter eAccelerator
Der Cache-Adapter File
Der Cache-Adapter Memcached

Der Cache-Server Memcache wurde von der Firma Danga Interactive für den Multiblog-Hoster LiveJournal entwickelt. http://memcached.org/

Der Cache-Adapter Redis

Memcached kann nur mit Keys von einer Große bis zu 250 Bytes und Values bis zu 1MB umgehen. Wer einen Key-Value Store sucht, der auch mit größeren Datensätzen umgehen kann, der ist mit Redis gut beraten.

Der Cache-Adapter xcache

XCache wurde als OpCode Cache für den Webserver "lighttpd" (lighty) entwickelt. Eine Featureliste findet sich unter http://xcache.lighttpd.net/wiki/FeatureList. http://xcache.lighttpd.net/

5.3.11. Clansuite_Cronjobs

Allgemeines

Die Klasse Clansuite_Cronjobs (auch Pseudocron genannt) ermöglicht eine intervallgebundene Ausführung von selbst bestimmbaren Kommandos. Beispielsweise kann man wöchentlich die Datenbank sichern, stündlich Feeds aktualisieren oder täglich den Template-Cache leeren oder die Sitemap neu generieren lassen. Dabei kann jedes PHP-Skript ausgeführt werden, wobei das Ausführungsintervall periodisch, also wiederkehrend oder zeitgesteuert sein kann. Die ausgeführten Cronjobs werden in einem Log gespeichert. Aus einem Cronjob können Nachrichten ins Log gespeichert werden. Unter Crontab versteht man die Cron-Tabelle. Sie enthält die Zeitangaben und die auszuführenden Kommandos. Die Notation eines Cronjob in der Crontab erfolgt im Unix Cron Syntax.

Ein zulässiger Crontabeintrag könnte wiefolgt aussehen:

2   1,15    *   *   beispiel.cronjob.php

Dieser Eintrag hätte zur Folge, das "beispiel.cronjob.php" um 2 Uhr am ersten und fünfzehnten jedes Monats ausgeführt werden.

PHP5-Portierung von pseudo-cron v1.3

Clansuite_Cronjobs ist ein Fork, genauer eine PHP5-Portierung, der bekannten PHP-Klasse pseudo-cron von Kai Blankenhorn (http://www.bitfolge.de/pseudocron). Die letzte Version, pseudo-cron v1.3, wurde am 15.06.2004 veröffentlicht. Die Veröffentlichung der PHP5 Portierung erfolgte am 10.05.2008 als Minor-Release mit der Versionsnummer v1.4. Dabei wurden die globalen Variablen entfernt, sowie Handler für datei- sowie datenbankbasiertes Crontab-Scheduling hinzugefügt.

Möglichkeiten des Cronjob Triggerings

Es gibt mehrere Möglichkeiten Cronjobs zu triggern.

Die Vorfilter Methode

Beispielsweise kann eine Kontrolle auf anstehende Cronjobs als ein Vorfilter des Systems angelegt werden.

Die Image-Tag Methode

Der Cronjob kann auch über den HTML Tag <img> ausgelöst werden. Beide Möglichkeiten hätten zur Folge, dass jeder Webseitenbesuch auch eine Prüfung des Crontabs auf anstehende Aufgaben auslöst.

Die Kopplung an den "echten" Cronjob des Betriebssystems

Im Gegensatz zum normalen, betriebssystemgesteuerten Cronjob ist mit Clansuite_Cronjob jedoch keine exakte zeitliche Ausführung der Kommandos möglich, da das Cronjobsystem immer an Ereignisse der Webanwendung geknüpft ist. Finden keine Ereignisse statt, werden die Cronjobs auch nicht ausgeführt. Wenn Sie beispielsweise einen stündlichen Cronjob registriert haben, der aktuelle News einholt und sie in ihrer Newsdatenbank speichert, jedoch im Zeitraum von 23Uhr bis 7Uhr keinen Besucher auf ihrer Webseite, dann wird der Cronjob erst wieder durch den Besucher nach um 7Uhr getriggert. Ihnen entgeht dabei die Newsaktualisierung zwischen 23Uhr und 7Uhr. Um sich einer exakten zeitlichen Ausführung anzunähern, kann man die Ausführung der Clansuite_Cronjobs an die Cronjobs des Betriebssystem koppeln. Dazu fügt man einfach den Aufruf der Clansuite_Cronjob in die Crontab des Betriebssystems ein (crontab -e).

Ereignisse der Webanwendung werden natürlich auch von Suchmaschinencrawlern ausgelöst. Crawler sind reguläre Besucher, wenn sie nicht durch Konfigurationsanweisung in der ".htaccess" oder "robots.txt" ausgeschlossen wurden. Webseitenbetreiber mit guter Besuchsfrequenz von Crawlern brauchen sich also keine Sorgen um die Cronjob-Auslösung machen. Die Kopplung von Web-Cronjobs an den Cronjob-Dienst des Betriebssystems bietet sich immer dann an, wenn man unabhängig von Besuchern und Ereignissen der Webanwendung, seine Cronjobs regelmäßig ausgelöst wissen möchte.

* * * * * php /srv/www/clansuite/cronjobs.php
Verwendung

Innerhalb eines Cronjobs kann mittels der Methode logMessage("Ihre Nachricht"); eine Nachricht in das Cronjob- Logbuch geschrieben werden.

Übersicht zu Crontab und Cronjobs
Die Crontab Datei

Das Format der Crontab-Datei entspricht in Aufbau und Syntax dem von Linux bekannten Cronjob-Format.

5.3.12. Clansuite_Eventhandler

Die Klasse Clansuite-Eventhandler stellt Methoden bereit, um einen ereignisbasierten Programmablauf zu ermöglichen. Um dies umzusetzen, werden an bestimmten Stellen im Ablauf der Applikation Ereignisse definiert. Auf den Eintritt dieser Ereignisse wartet ein Beobachter. Dem Beobachter wird ebenfalls eine Liste mit Unterprogrammen vorgelegt, die ausgeführten werden sollen, wenn bestimmte Ereignisse eintreten. Stellt der Beobachter den Eintritt eines Ereignisses fest, löst er alle für dieses Ereignis angemeldeten Unterprogramme aus.

Den Beobachter nennt man auch Observer oder EventListener. Den Teil des Beobachters, der das Unterprogramm ausführt, nennt man EventHandler (so auch der Klassenname). Nicht verwunderlich ist der Name des zugrunde liegenden Entwurfsmusters. Es ist das Subject-Observer Muster. Manchmal wird es auch nur Signal-Slot genannt.

Durch den Einsatz ereignisbasierter Programmierung ist es möglich, die Applikation dynamisch zu erweitern ohne am Quelltext etwas zu ändern. Man fügt lediglich eine Datei mit dem neuen Unterprogramm ein und registriert es für das gewünschte Ereignis beim Beobachter. Um nun eine ganze Reihe von Unterprogrammen einzubinden, kann man auf die magische PHP-Methode __autoload() zurückgreifen. Clansuite verwendet diesen Mechanismus und lädt ereignisbasierte Unterprogramme aus einem dafür eingerichteten Verzeichnis (/core/events/) und registriert sie automatisch. Das Verfahren fördert die Losekopplung. Gleichzeitig werden die Hauptcontroller etwas verkleinert, indem Quellcodeanteile in die Unterprogramme ausgelagert werden. Der Nachteil besteht allerdings darin, dass die Komplexität durch diese Dezentralisierung wieder ansteigt. Leicht kann der Überblick über verfügbare Ereignisse und registrierbare Unterprogramme verloren gehen.

Intanzierung

Es erfolgt eine automatische Instanzierung beim Systemstart. Der Eventdispatcher wird bei der Initialisierung des Systems automatisch instanziert bzw. gestartet, wenn in der Konfigurationsdatei (/confuguration/clansuite.config.php) in der Sektion "eventsystem" der Wert "eventsystem_enabled" auf "true" oder "1" gesetzt ist. Das gesamte Eventsystem kann also in der Konfiguration ein- und ausgeschaltet werden. Danach ist das Eventhandler Objekt systemweit über den Dependency Injector verfügbar.

Einschalten des Eventsystems in der Konfiguration
;----------------------------------------
; eventsystem
;----------------------------------------
[eventsystem]
eventsystem_enabled = 1

Möglich ist auch die direkte Instanzierung (Singleton).

$eventhandler = Clansuite_Eventhandler::instantiate();

Zumeist ist eine Instanzierung jedoch nur zum Aufruf der Methode triggerEvent() gewollt. Um die Instanzierung abzukürzen kann direkt Clansuite_CMS::triggerEvent() eingesetzt werden.

Verwendung

Ein neues Ereignis kann folgendermaßen registriert werden.

$eventhandler->addEventHandler($eventName, Clansuite_Event $event);

Konkretes Beispiel:

$logger = new Clansuite_Logger();
$authlogger = AuthenticationLogging($logger);
$eventhandler->addEventHandler('onUserLogin', $authlogger);
# Systemweit
Clansuite_CMS::triggerEvent();

# Innerhalb eines Modulecontrollers
@todo
Entwurfsmuster

Die Klasse Clansuite_Eventdispatcher ist ein Kontainer für alle Eventhandler. Sie ist eine Hilfsklasse für ereignisbasierte Entwicklung. Ereignisse können unter einem Ereignisnamen registriert werden. Wenn ein Ereignis durch den Programmablauf ausgelöst bzw. getriggert wird, erfolgt eine Suche nach dem Ereignisnamen unter allen registrierten Ereignissen. Wird ein entsprechendes Ereignis gefunden, so wird es ausgeführt. Werden mehrere entsprechende Ereignisse gefunden, so werden sie in der Reihenfolge ihrer Registrierung ausgeführt. Auf diese Art und Weise können Objekte sich sehr flexibel untereinander verständigen und es kann sehr leicht neue Funktionalität nachträglich hinzugefügt werden.

Die Klasse Clansuite_Event ist die Basisklasse für alle Events. Mittels der Methoden getName(), getContext(), getInfo() können Kontextinformationen über das Ereignis eingeholt werden. Mittels der Methode cancel() kann ein Abbruch erfolgen. Um zu überprüfen, ob ein Abbruch innerhalb einer Ereigniskette stattfand, kann die Methode getCancelled() eingesetzt werden.

Der Name des Entwurfsmusters ist mit dem Klassennamen identisch. Es ist das "Event-Dispatcher" Muster. Häufiger ist es auch nur unter dem Namen Event oder Eventsystem anzutreffen. Alternativ wird es auch als "Hooksystem" (für Haken bzw. Aufhänger) bezeichnet. Geläufig sind auch die Muster-Bezeichnungen "Subject-Observer-Muster" und "Notification Queue".

Übersicht zu Eventhandlern
Hooks im Bereich Benutzerregistrierung, Login, Logout
onRegisterAccount

wenn neuer Useraccount angelegt wird (Daten können bei fremdem System eingetragen werden)

onAccountActivation

wenn ein neuer Useraccount aktiviert wird

beforeLoginValidation

bevor die Prüfung der Eingaben erfolgt, kann ein fremdes System damit befragt werden (Bridges)

afterLogin

nach einem erfolgreichen Login

afterLogout

nach einem erfolgreichen Logout

onDeleteAccount

bevor die Löschung eines Useraccounts durchgeführt wird (Daten können aus fremdem System ausgetragen werden)

resetPassword

bevor das Passwort zurückgesetzt/erneuert wird

Hooks im Bereich Dateihandling
onDownload

nachdem eine Datei heruntergeladen wurde (Update des Downloadcounters in der Statistik)

  1. Hooks innerhalb von Doctrine Records

Die Hooks innerhalb von Doctrine Record Objekten an 5 Aktionen an. Diese 5 Aktionen sind Save, Update, Insert, Delete und Validate. Jede dieser Aktionen wird nochmals gemäß der zeitlichen Anknüpfung unterteilt. So gibt es einen Haken vor der Aktion (Pre-Hook) und einen Haken nach der Aktion (Post-Hook). Innerhalb von Doctrine Records stehen also die folgenden 10 Hooks zur Verfügung.

  • preSave, postSave

  • preUpdate,postUpdate

  • preInsert, postInsert

  • preDelete, postDelete

  • preValidate, postValidate

Um einen dieser Hooks zu verwenden, wird das Doctrine Record Object einfach um eine nach dem gewünschten Hook benannte Methode erweitert.

class Mein_Doctrine_Record_Object extends Doctrine_Record
{

    public function setTableDefinition()
    {
        # Definition der Tabelle
    }

    public function setUp()
    {
        # Setup und Relationen
    }

    public function postInsert()
    {
        # Wenn diese Stelle des Quellcodes aufgerufen wird, befinden wir uns zeitlich nach dem Einfügen eines neuen Datensatzes.
        # An dieser Stelle können Sie den Quellcode einfügen, der nach diesem Ereignis ausgeführt werden soll.
    }
}

5.3.13. Clansuite_Errorhandler

Die Behandlung von Programmfehlern erfolgt mittels der Klasse Clansuite_Errorhandler.

Zahlreiche Webanwendungen machen von der Möglichkeit Gebrauch, das Errorhandling an den Exceptionhandler zu übertragen. Dies führt zu einer Vereinfachung des Systems, da nicht mehr zwei Handler-Klassen gepflegt werden müssen. Clansuite nutzt diese Möglichkeit nicht. Dies hat zwei Gründe. Zum einen müsste der Exceptionhandler intern prüfen, ob ein Error die Exception ausgelöst hat, womit eigentlich Logik des Errorhandlers in den Exceptionhandler verschoben wird. Zum anderen soll es bei Clansuite möglich sein, dem jeweiligen Handler ein eigenes Aussehn durch Templates zu geben.

Fehlerbehandlung für strikte Typen

Auch PHP in der Version 5.2+ hat immernoch ein großes Problem im Bereich Typen. Die Sprache PHP kennt keine strikten Typen (engl. Strict Types). PHP ist eine schwach typisierte Sprache. Der Typ einer Variablen wird durch den Kontext bei ihrer konkreten Verwendung bestimmt. Demnach können Variablentypen während der Laufzeit einer Typänderung unterliegen. Dies bezeichnet man als automatisches bzw. dynamisches Type-Casting oder Type-Juggling
[http://php.net/manual/en/language.types.type-juggling.php]
). Es ist es möglich Variablen zu verwenden, ohne sie vorher zu deklarieren.

PHP stellt eine Möglichkeit bereit, um festzustellen, ob eine Variable initialisert wurde. So lässt sich der Level der Fehlerberichterstattung mittels der Methode error_reporting() auf E_NOTICE setzen. Nicht initialsierte Variablen werden dann als Fehler des Typs Notice angezeigt und man erhält zumindest einen Hinweis. Clansuite wird seit Anfang der Entwicklung mit dem Fehlerberichterstattungslevel E_STRICT and E_NOTICE entwickelt. Eine Alternative dazu, wäre der Einsatz eines externen Quelltext-Prüfwerkzeugs wie PHP Lint, um diese Fehler hervorzuheben. Viele Editoren und IDEs integrieren ein solches Prüfwerkzeug bereits.

Die Verwendung von strikten Typen bringt einige Vorteile mit sich. Fehler treten schneller hervor und die Ausdrucksstärke der Variablenverwendung in Funktionen und Methoden wird erhöht. Beispielsweise kennt PERL ein "use strict", doch ein solches fehlt bei PHP noch immer.

Die Weiterentwicklung von PHP im Hinblick auf die Unterstützung strikter Typen

Gegenwärtig wird sowohl auf der PHP-Mailingliste als auch im PHP-Wiki über die Unterstützung strikter Typen diskutiert. Lukas Smith hat am 03.06.2009 eine PHP-RFC zum Thema "Typechecking"
[http://wiki.php.net/rfc/typechecking, PHP RFC Typechecking Vorschlag von Lukas Smith]
verfasst, sein Entwurf ist unter http://wiki.php.net/rfc/typecheckingstrictandweak abrufbar. Ein weiterer Vorschlag
[http://wiki.php.net/rfc/typecheckingstrictonly, PHP RFC Typechecking Vorschlag von Ilia Alshanetsky]
von Ilia Alshanetsky zum Thema Typechecking befasst sich mit der Ergänzung der Reflection-Erweiterung um typdefinierende ReflectionParameter Methoden. Er führt zum Beispiel Methoden wie ReflectionParameter::isInt() oder ReflectionParameter::isBool() zur Typprüfung mittels Reflektion ein.

Die Clansuite Errorcodes

Um Fehler auszulösen kann der PHP-Befehl trigger_error() eingesetzt werden.

trigger_error('Auslösen eines USER_ERRORS!', E_USER_ERROR);

Es stehen die folgenden Fehlerlevel für den Programmierer zur Verfügung:

Fehlerlevel für trigger_error()
E_USER_WARNING
E_USER_NOTICE
E_USER_ERROR

PHP verfügt über weitere Fehlerlevel
[http://php.net/manual/en/errorfunc.constants.php]
. Diese können jedoch nicht manuell, d.h. über die Funktion trigger_error() ausgelöst werden.

Fehlerlevel von PHP
Catchable Fatal Error
    E_RECOVERABLE_ERROR
Parser-Fehler
    E_PARSE
    E_ERROR
    E_WARNING
    E_NOTICE
Compiler-Fehler
    E_COMPILE_ERROR
    E_COMPILE_WARNING
PHP Code-Errors
    E_CORE_ERROR,
    E_CORE_WARNING
Runtime Notices
    E_STRICT

Statt der Verwendung von Errors bitte grundsätzlich Exceptions verwenden.

Zu jeder Regel gibts eine Ausnahme: keine Exceptions in Templates werfen. Bei Verwendung von Smarty unbedingt trigger_error() verwenden, denn die auf diese Art geworfenen Fehler werden automatisch abgefangen und im Template zur Bearbeitung markiert.

Wichtig In Smarty Plugins und Funktionen immer trigger_error() einsetzen.
Übersetzung von Fehlermeldungen

Derzeit findet keine Übersetzung von Fehlermeldungen statt. Die Sprache der Fehlermeldungen ist Englisch.

5.3.14. Clansuite_Exceptionhandler

Die Exceptionbehandlung ist ähnlich der Behandlung von Errors. Die Klasse Clansuite_Exception erweitert die normale PHP Exception Klasse.
[http://php.net/exceptions, PHP Handbuch - Kapitel Exceptions]
Die Erweiterung besteht dabei einerseits in verbesserter Darstellung der Exceptions, andererseits in dem automatischen Auffangen aller nicht abgefangenen Exceptions, z.B. denen fremder Bibliotheken.

Kern der Klasse ist die Methode yellowScreenOfDeath(), mit der eine Darstellungsmethode für Exceptions eingeführt wird. Sie zeigt Exceptionmessage und Code, sowie die Ausgabe der nicht abgefangenen Exception an. Erweitert wird die Anzeige durch Debuginformationen, wie z.B. dem Debug-Call-Stacktrace, welcher die zuletzt ausgeführten Methodenaufrufe vor dem Exceptioneintritt aufführt und der Anzeige von Direktlinks zum Support und zu den Handbüchern.

Normalerweise, also ohne einen eigenen Exceptionhandler, werden nicht abgefangene Exceptions als "Fatal Errors" ausgegeben. Mittels der PHP Funktion set_exception_handler wird ein systemweiter Exceptionhandler registriert. Er sorgt dafür, dass nicht abgefangene Exceptions nun behandelt und mittels der eigenen Darstellungsmethode anzeigt werden können. Dies erfolgt bei Initialisierung des Systems innerhalb der Methode initialize_Errorhandling() in der Datei "bootstrap/clansuite.application.php".

Behandlung von Exceptions

Es gibt 3 bzw. 4 Sprachelemente für den Umgang mit Ausnahmen. Dies sind "try", "catch", "throw" und "finally".

throw

Bewirkt das Werfen einer Ausnahme.

try

Das Sprachelement try umklammert den Quelltext, in welchem möglicherweise eine Ausnahme geworfen wird.

catch

Das Sprachelement catch umklammert den Quelltext, der ausgeführt wird, wenn eine Ausnahme im try-Block geworfen wurde.

try
{
    throw Exception();
}
catch (Exception $e)
{
    # Behandlung der Exception
    echo $e->Message;
    exit();
}

Eine im try-Block geworfene Exception steigt bis zum ersten Catch-Block auf.

Kaskadierung von Exceptions
try
{
    throw Exception();
}
catch (SpezielleException $e)
{
    # Behandlung der Exception
    echo $e->Message;
    exit();
}
catch (Exception $e)
{
    # Behandlung der Exception
    echo $e->Message;
    exit();
}
Verwendung: Das Werfen von Exceptions

Exceptions kann man als Kontrollstrukturen, vergleichbar mit if-else, foreach oder while verstehen. Dennoch sind sie denkbar ungünstig für diesen Einsatzzweck, denn sie sind langsamer und verbrauchen mehr Speicher, als normale Kontrollstrukturen.

Der Clansuite_Exceptionhandler wirft durch Aufruf der Methode throwException() eine neue Clansuite_Exception. Es stehen die folgenden Möglichkeiten zum Werfen einer Clansuite_Exception zur Verfügung:

# Hier wird eine normale Exception geworfen.
# Diese wird durch den Exception Handler gefangen und in eine Clansuite Exception umgewandelt.
throw new Exception('Meine Exception');

# Es wird eine Clansuite Exception mit der Exceptionnummer 60 geworfen.
# Sollte ein Exception Template für die Nummer 60 existieren, wird sein
# Inhalt innerhalb des Exception-Kontext dargestellt.
# Der Unterstrich vor dem Exception-Text bewirkt die Übersetzung.
throw new Clansuite_Exception( _('Meine Exception') , 60);

# Werfen einer Exception
Clansuite_Exception->throwException(),

# Verwendung bei Methoden, die einen Wert des Typs Boolean zurückliefern
someBooleanMethod() or throwException();

# Beispielsweise
isFileandReadable('filename.txt') or throwException('File not found or not readable!');
Die Exceptionhandler Templates

Der Exceptionhandler bietet die Möglichkeit mit Exceptiontemplates zu arbeiten. Das sind Templates die zu einer Exception einen ausführlicheren Beschreibungstext anbieten und somit den Kontext der Exception erläutern, um den Fehler zu überwinden. Jeder Exception ist eine Identifikatonsnummer zugewiesen, anhand dieser wird ein entsprechendes Template geladen.

Dabei unterscheiden wir zwei Arten von Exceptiontemplates. Zum einen normale Exceptiontemplates. Die angezeigt werden, wenn das System im Debugmodus betrieben wird. Zum anderen Entwickler-Exceptiontemplates. Die angezeigt werden, wenn das System im Debug- und Developermodus betrieben wird. Die Exceptionstemplates befinden sich im Verzeichnis "themes\core\exceptions".

Der Unterschied zwischen der beiden Arten von Templates findet seinen Ausdruck in der Benennung der Templatedateien. Der Dateiname normaler Exceptiontemplates lautet "exception-x.tpl". Der Dateiname von Entwickler-Exceptiontemplates lautet "dev-exception-x.tpl". Hierbei steht das "x" jeweils für den Exceptioncode, die eindeutige Identifikationsnummer. Wenn für einen Excpetioncode beide Templates existieren, dann werden auch beide nacheinander innerhalb der Exceptionanzeige angezeigt. Die Reihenfolge der Darstellung ist dabei Normaltemplate vor Entwicklertemplate.

Die Exceptionhandler Codes

Nachfolgende Tabelle schlüsselt die bisher vergebenen Exceptioncodes auf. Eine entsprechende Datei befindet sich auch im Verzeichnis der Templates /themes/core/exception/errorcodes.txt.

Exceptioncode    Exceptionname                                        Used in File               Method
dev-1   Database Connection Information invalid              /core/doctrine.core.php    prepareDbConnection()
dev-2   Action Missing. Create now.
dev-3   Module Missing. Create now.
dev-4   Config Missing. Create now.                          /ini.config.php            readConfig()

09      Smarty Template Directories do not exist.            startup_checks.filter.php
10      Smarty Template Directories not writable.            "

12      The copyright tag is missing.                        Smarty.renderer.php
        {include file='copyright.tpl'} in your layout/wrapper template file.
13      The header notice tag is missing.                    "
        {include file='clansuite_header_notice.tpl'} in your layout/wrapper template file.
14      The content variable {$content} must be within       "
        the wrapper template
30      Ensure that all obligatory formelements are present. /core/viewhelper/formgenerator __construct()
Übersetzung von Ausnahmemeldungen

Derzeit findet keine Übersetzung von Ausnahmemeldungen statt. Die Sprache der Ausnahmemeldungen ist Englisch.

5.3.15. Clansuite_Feed

5.3.16. Clansuite_Form

Verwendung

Clansuite Forms verwendet Filter und Validatoren automatisch, wenn sie für ein Formelement definiert wurden.

Schutz vor Cross Site Request Forgery (CSRF) durch Token (Shared-Secret)

Der Fachbegriff Cross-Site-Request Forgery (CSRF) lässt sich nur schwer in die deutsche Sprache übertragen. Man kann darunter einen Angriff verstehen, bei dem durch einen untergeschobenen Aufruf auf eine Fremdseite eine Datenveränderung innerhalb einer Webanwendung durchgeführt wird. Dabei wird dem Angriffsopfer in seinem Webbrowser ein URL-Aufruf untergejubelt, der einen veränderten HTTP-Request ausführt. Der veränderte Request führt nun die vom Angreifer gewünschte Aktion aus. Dies hat regelmäßig Erfolg, wenn der Nutzer bei der Webanwendung angemeldet ist und aus Bequemlichkeits- und Komfortgründen ein Cookie gespeichert hat. Eine bestehende Anmeldung oder der Zugriff auf Cookie-Daten ist Voraussetzung für einen erfolgreichen Angriff.

Die Angriffsvektoren bei Cross Site Request Forgery (CSRF) sind regelmäßig das URL-Unterschieben und das Cross-Site- Scripting (XSS).

Ein URL-Unterschieben kann auf vielfältige Art erfolgen. So beispielsweise durch das Verteilen einer URL während eines IRC Chats oder durch Zusenden einer E-Mail.

Bei Cross-Site-Scripting (XSS) wird HTML-Code an die Webanwendung übermittelt. Dies erfolgt häufig durch Ausnutzen von Sicherheitslücken im JavaScript-Bereich. So kann beispielsweise jeder <img> oder <frame> Tag zum Nachladen von Angriffselementen eingesetzt werden. Zuerst wird also ein HTML-Tag Element mittels JS eingeschleust, sodann wird die Seite vom Opfer aufgerufen. Beim Aufruf wird der eingeschleuste Tag vom Browser interpretiert und der schadhafte Link aufgerufen.

Um sich davor zu schützen, verwendet man ein einfaches serverseitiges Verfahren. Ein Zugriff auf die Applikations wird mittels eines Sicherheitstokens (Shared-Secret) erreicht. Der Sicherheitstoken wird als verstecktes Feld zusätzlich zu jedem Formular hinzugefügt. Beim Übermitteln des Formulars wird automatisch überprüft, ob der Sicherheitstoken des Formulars mit dem intern (in der UserSession) vorliegenden übereinstimmt. Die eingehenden Daten sind valide, wenn der Token übereinstimmt. Liegt kein Token vor oder stimmt er nicht überein, werden die eingehenden Daten des Requests verworfen.

Instanzierung
/**
 * Instanzierung von Clansuite_Form mittels Übergabe eines Attribute Array als Parameter
 */
$formattributes = array( 'name'   => '1',
                         'method' => '2',
                         'action' => '3');
$form = new Clansuite_Form($formattributes);

/**
 * Instanzierung von Clansuite_Form mittels der drei Parameter name, method, action.
 */
$form = new Clansuite_Form('name','method','action');

# Übergabe des Formular HTML-Quelltextes an das Template
# Beachte: Es sind keine Formularelemente verwendet worden!
$view->assign('form', $form);
Entwurfsmuster
Übersicht zu den einzelnen Formelementen

5.3.17. Clansuite_Flashmessages

Verwendung

Die Klasse Clansuite_Flashmessages dient der Speicherung von Einmal-Nachrichten in der Session und damit über einen Request hinweg. Man kann sich die Klasse Clansuite_Flashmessages als Erweiterung der Klasse Clansuite_Session denken. Tatsächlich ist sie es aber nicht. Flashmessages können beispielsweise Kurznachrichten, Statusmeldungen, sowie Erfolgs- oder Misserfolgsmeldungen nach Aktionen sein. Daher kann man die Flashmessages in die Typen error, warning, notice, success, debug einteilen.

Grundsätzlich gibt es ein Nachrichtenübermittlungsproblem an den Benutzer nach GET oder POST Requests. Das Absetzen von Meldungen nach einem GET-Request ist sehr einfach, denn man kann sie per echo oder im Template ausgeben. Bei POST-Requests, die zumeist von einem Redirect begleitet werden, wird es schwieriger. Im Allgemeinen gibt es dazu 3 Lösungsansätze. Flashmessages sind eine Art dieses Problem zu lösen.

Erstens kann man kann die Nachricht an die URL anhängen. Das bedeutet, dass man zu einer POST Übergabe auch Daten über GET übergibt. Es kann auch bedeuten, dass die URL unter Umständen (je nach Nachrichtenlänge) sehr lang werden kann, wie z.B. header(Location: http://www.example.com/index.php?message=.urlencode($message));.

Zweitens kann eine Doppelweiterleitung einsetzen. Stellen Sie sich dazu die folgende typische Situation vor: Nachdem Sie ein ein Formular ausgefüllt und es abgesendet haben, werden sie auf eine neue Seite weitergeleitet. Diese Seite zeigt Ihnen zunächst eine Erfolgsmeldung der Art "Ihr Datensatz wurde eingetragen." an. Sodann werden sie entweder automatisch oder nach Klick auf die Ausgangsseite zurückgeleitet. Es erfolgte eine Doppelweiterleitung, wobei die erste Weiterleitung nur der Erfolgsmeldung (engl. successview) diente u nd die zweite Weiterleitung die Zielseite war.

Drittens kann Flashmessages verwenden, um die Nachrichten über einen Request in der Session zu speichern. Diese Klasse setzt genau diesen Lösungsweg um. Mit Flashmessages umgeht man diese Doppelweiterleitung (engl. two-step-redirect) auf elegante Art und Weise. Nachdem die Daten des Formulars empfangen und in die Datenbank eingetragen wurden, setzen Sie eine Flashmessage ein, um die Erfolgsmeldung in der Session zu speichern. Danach leiten Sie auf die Zielseite weiter. Mit dem Erreichen der Zielseite wird geprüft, ob eine Flashmessage in der Session enthalten ist. Wenn es so ist, wird Sie nun dem Benutzer angezeigt und danach aus der Session gelöscht.

Flashmessages haben also einige Vorteile. Bei diesem Verfahren brauchen Sie keine Weiterleitungsseiten anlegen, die nur den Zweck haben Statusmeldungen anzuzeigen. Auch müssen Sie sich nich um die Länge der Nachricht kümmern, wie es bei einer Nachrichtenübergabe mittels GET der Fall wäre. Sie können die Darstellung und die Position der Anzeige der Flashmessages flexibel an Ihren View anpassen.

Instanzierung

Eine Instanzierung der Klasse ist nicht nötig. Alle Methodenaufrufe erfolgen statisch. Die Klasse steht systemweit über den Autoloading-Mechanismus zur Verfügung und muss nicht gesondert geladen werden.

Verwendung
/**
 * Das Setzen einer Flashmessage erfolgt mittels der Methode setMessage().
 * Diese erwartet die Angabe eines Nachrichtentyps und die Nachricht als Parameter.
 * Folgende Nachrichtentypen sind zulässig: error, warning, notice, success, debug.
 */

# abstrakt
Clansuite_Flashmessages::setMessage($type, $message)
# konkret
Clansuite_Flashmessages::setMessage('success', 'Die Aktion war erfolgreich.');
Clansuite_Flashmessages::setMessage('notice', 'Es sind nicht alle Formularfelder richtig ausgefüllt.');
Clansuite_Flashmessages::setMessage('warning', 'Die Dateirechte sind nicht ordnungsgemäß (read-only) gesetzt.');

/**
 * Die Ausgabe der Flashmessages erfolgt mittels der Methode render().
 */
Clansuite_Flashmessages::render();

5.3.18. Clansuite_Localization

5.3.19. Clansuite_Logger

Verwendung

Die Klasse Clansuite_Logger dient dem Logging von Nachrichten und Fehlern, die sich während des Applikationsablaufs erreignen.

Instanzierung
$logger = new Clansuite_Logger();
a) Übergabe eines Strings als Loggername
$logger->addLogger('firebug');
b) Übergabe eines Loggerobjekts
$logger->addLoger(new Clansuite_Logger_Firebug);
c) Übergabe mehrerer Loggerobjekte
$logger_array = array();
$logger_array[] = new Clansuite_Logger_Firebug();
$logger_array[] = new Clansuite_Logger_File();
$logger->addLoger($logger_array);
Entwurfsmuster

Das Entwurfsmuster für diese Klasse ist ein Kompositum (auch compositum order composite genannt). Die Klasse repräsentiert also eine Zusammenstellung eines oder mehrerer Logger. Ein neues Logger-Objekt wird dem Kompositum mittels addLogger() hinzugefügt und mittels removeLogger() wieder entfernt. Das Kompositum wird durch die Methode writeLog() ausgelöst.

====== Die Logging-Adapter

Die folgenden Logger Adapter stehen für die Komposition zur Verfügung.

====== Der Logger /dev/null

Der Logger /dev/null sendet die Lognachrichten direkt in den Papierkorb.

====== Der Logger E-Mail

Der Logger E-Mail sendet die Lognachrichten via E-Mail.

====== Der Logger File

Der Logger File schreibt die Lognachrichten in die Logdatei.

====== Der Logger Firebug

Der Logger Firebug sendet die Lognachrichten in die Firebug Konsole des Firefox Webbrowsers.

5.3.20. Clansuite_Mailer

Die Klasse Clansuite_Mailer ist eine einfache Wrapper- und Initialisierungsklasse für SwiftMailer. SwiftMailer wurde ursprünglich von Chris Corbyn entwickelt. Seit der Version 4.0.0 ist Fabien Potencier vom Symfony-Team als weiterer Entwickler hinzugekommen.

Webseite des SwiftMailer Projekts: http://swiftmailer.org/

Konfiguration

Clansuite_Mailer benötigt einige Konfigurationseinstellungen. Diese sind in der clansuite.config.php im Abschnitt [email] zu finden.

Erforderlich sind:

$config['email']['mailmethod']
$config['email']['mailerhost']
$config['email']['mailerport']
$config['email']['mailencryption']
Instanzierung

$mailer = new Clansuite_Mailer();

Verwendung
# Senden einer E-Mail mittels der Methode sendmail()
$mailer->sendmail($to_address, $from_address, $subject, $body);

# Holen des SwiftMailer Objekts aus dem Wrapper
$swiftmailer = $mailer->getMailer();
Entwurfsmuster

Wrapper.

5.3.21. Clansuite_Module_Controller

5.3.22. Clansuite_Router

Entwurfsmuster

Die Klasse Clansuite_Router sorgt für die Zuordnung (engl. mapping) einer URI zu einem Controller, seiner Action und, wenn vorhanden, auch zusätzlicher Parameter. Eine eingehende URL wird zunächst in ihre Bestandteile zerlegt. Dabei wird der anfängliche URL Teil ("http://www.xy-domain.com") vom URI Teil ("/index.php" oder "/index") abgetrennt. Die Bestandteile der URI dienen als Abfrageparameter an eine Zuordungstabelle (engl. mapping- table). Die Zuordnungstabelle ist ein Nachschlagewerk für alle Informationen über aufrufbare Controller und Actions und ihre möglichen Parameter. Sie liefert anhand der URI-Bestandteile die nötigen (Aufruf-)Informationen für den Dispatcher. Der Dispatcher instanziert mit diesem Wissen den richtigen Controller und ruft die richtigen Methode mit den richtigen Parameters auf.

Eine Routingklasse muss also Methoden für die Zerlegung der URL und die Verwaltung von Einträgen und die Suche in einer Zurordnungstabelle bereitstellen. Hinzu tritt eine zusätzliche Aufgabe, die darin besteht, den umgekehrten Weg zu gehen: nämlich eine URL zu generieren. Die URL Generierung ist insbesondere bei Formularen sehr hilfreich. Anstatt die URL der Zielseite im "action" Attribut eines "form" Elements manuell festzulegen, kann diese nun automatisch aus Modulenamen und Actionnamen generiert werden.

Debbuging des Routings auf lokalem Apache Webserver Um das Routing und insbesondere die Rewrite Conditions

und Rewrite Rules zu testen und anschließend zu debuggen, empfehle ich die nachfolgende Einstellungen in die globale Serverkonfiguration (httpd.conf) oder die spezifische VirtualHost-Konfiguration (vhost.conf) aufzunehmen. Das Setzen dieser Einstellungen in der ".htaccess" im Anwendungspfad wird nur bis zur Apache Version 1.3 unterstützt. Für Apache Version 2 sind die Einstellungen also zwingend in der globalen Konfigurationsdatei zu machen (siehe dazu auch http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritelog).

Die Klasse bestimmt zunächst den RewriteMode. Der RewriteMode entscheided darüber, welcher URL-Parser eingesetzt wird, um die URL zu zerlegen. Dazu wird geprüft, ob das Apache Modul ModRewrite verfügbar ist und die RewriteEngine in der ".htaccess" aktiviert wurde. Bei Verfügbarkeit von ModRewrite wird die URL (etwa "news/show/77") mittels der Methode UrlParser_Rewrite() zerlegt. Sollte ModRewrite nicht verfügbar sein, so wird die URL (etwa "index.php?mod=news&action=show&id=77) mittels der Methode UrlParser_NoRewrite() zerlegt.

Notwendige Angaben in der ".htaccess" um URL-Rewriting zu aktivieren
Options -MultiViews

# Einschalten der RewriteEngine
RewriteEngine On

# Bedingungen für das Rewriting
RewriteCond %{REQUEST_FILENAME} !-d # physisch existierende Verzeichnisse ausschliessen
RewriteCond %{REQUEST_FILENAME} !-f # physisch existierende Dateien ausschliessen

# Anzuwendende Regel für das Rewriting
RewriteRule ^(.*)$ index.php [QSA,L]
# Pfadangabe für Linux:
RewriteLog /var/log/apache2/clansuite-rewrite.log
# Pfandangabe für Windows:
RewriteLog D:/xampplite/htdocs/work/clansuite/trunk/logs/clansuite-rewrite.log

# Angabe des Detailgrades der Meldungen bei der Abarbeitung der Rewrite Anweisungen.
# Die Parameterangabe reicht von 1 für spärliche Angaben, bis 9 für sehr detailierte Ausführungen.
RewriteLogLevel 9

5.3.23. Clansuite_Trail

5.3.24. Clansuite_Security

Entwurfsmuster

Die Klasse Clansuite_Security stellt den Zugriff auf Streuwert-Methoden (hashing) bereit. Die drei Methoden der Klasse ermöglichen eine Zeichenkette zu hashen, zu salzen und zu vergleichen. Die Methode build_salted_hash() erstellt einen gesalzenen Hash. Die Methode generate_hash() erstellt einen Hash einer Zeichenkette. Die Methode generate_salt() erstellt eine zufällige Zeichenkette (genannt Salz).

Allgemeines zum Thema-Hashing

Streuwert-Methoden oder Hashing-Methoden sind Funktionen zur Abbildung einer Zeichenkette auf eine eindeutige (zumeist aus Buchstaben und Zahlen bestehende) Zeichenkette.

Man muss sich hierbei zwei Dinge vergegenwärtigen. Erstens, dass Eindeutigkeit bedeutet, dass eine Ausgangszeichenkette immer genau einen Hash hat.

Eindeutigkeit von Hashes
Beispiel
$passwort_zeichenkette = 'meinPasswort';
$md5_hash_der_passwort_zeichenkette = md5($passwort_zeichenkette);
echo $md5_hash_der_passwort_zeichenkette; # = f14a298bc87fff2cd757f71054fdd94d
# Die Zeichenkette 'meinPasswort' entspricht dem MD5 Hash 'f14a298bc87fff2cd757f71054fdd94d'.

Zweitens, dass ein Hash nicht umkehrbar ist. Man kann nicht von einem Hash auf die Ausgangszeichenkette schließen. Die Unumkehrbarkeit von Hashes ist der Unterschied zur Verschlüsselung. Bei einer verschlüsselten Zeichenkette, existiert ein Schlüssel und eine Methode, um sie in ihre Ausgangszeichenkette (regelmäßig den Klartext) umzuwandeln.

Das Hashing-Verfahren wird beispielsweise eingesetzt um zwei Dateien auf ihre Gleichheit zu überprüfen. Anstatt nun einen zeichen- oder zeilenweisen Dateivergleich durchzuführen, wird für beide Dateien ein Hash, also eine eindeutige Zeichenkette erzeugt. Man nennt diese Zeichenkette daher auch Identifikator oder Fingerabdruck (engl. Fingerprint). Der Vergleich der Fingerabdrücke der beiden Dateien gibt nun Auskunft über ihre Gleichheit oder Ungleichheit.

Im Bereich der Webanwendungssicherheit hat sich das Hashing für die Absicherung von Passwörtern als sinnvoll erwiesen. Anstatt Benutzerpasswörter im Klartext in der Datenbank zu speichern werden sie nun gehashed abgespeichert. Damit wird die Einsehbarkeit des Klartextes durch Administratoren oder Dritte, etwa bei einem Datenbankeneinbruch oder -diebstahl, unterbunden. Der Angreifer erhält nun "nur" den Hash des Passworts.

Angriffsmethoden auf gehashte Passwörter

Es gibt aber auch bei gehashten Passwörtern Angriffsmethoden. Eine Methode besteht darin, einfach alle Varianten auszuprobieren. Eine weitere Methode setzt vorbereitete Tabellen als Nachschlagewerk ein.

Die erste Methode, die Brute-Force-Methode (Methode roher Gewaltanwendung) besteht darin, Passwörter zusammenzusetzen und die erstellten Hashes nacheinander auszuprobieren. Brute-Force-Algorithmen sind sehr einfach zu implementieren aber heillos ineffizient. Der Rechenaufwand steigt proportional mit der Menge an zu probierenden Passwörtern. Die Anzahl zu probierender Passwörter unterliegt dabei einem expotentiellen Wachstum. Die Rechenleistung heutiger CPUs erlaubt es dennoch sehr viele Passwort-Möglichkeiten pro Zeiteinheit auszuprobieren. Die Bedrohungslage im Bereich der Brute-Force Angriffe hat sich durch das Aufkommen von extrem rechenstarken Grafikkarten nochmals verschärft.

In Sachen Gleitkommaoperationen (also Additionen und Multiplikationen) pro Sekunde kann eine normale Mehrkern-CPU einer GPU, dem Rechenprozessor der Grafikkarte, niemals das Wasser reichen. Ein Vergleich der Gleitkommaoperationen pro Sekunde (engl. Floating Point Operations per Second, abgekürzt FLOPS) bei aktuellen Produkten (Januar 2010) mag dies verdeutlichen. Ein Intel Core i7 965 XE Prozessor mit aktiviertem Hyper-Threading verfügt über 4 Kerne mit 3,2Ghz und kostet rund 1000 Euro. Er erreicht in der Spitze 50 bzw. im Schnitt 33 GigaFlops. Laut eines TechRadar Benchmarks sogar 69 GFlops.
[http://mos.techradar.com/techradar-corei7-benchmarks.pdf]
Die Grafikkarte Nvidia GeForce GTX 295 ist bereits für unter 500 Euro im Handel erhältlich und schafft rund 1750 GigaFlops. Die AMD Radeon HD 5970 knackte als erste Grafikkarte sogar die 1-TeraFlops-Grenze und ist für rund 550 Euro im Handel erhältlich.

Für die Ermittlung dieser Rechenleistung wird zumeist auf das Programm "linpack" zurückgegriffen. Eine webbasierte Linpack-Version findet man unter http://www.netlib.org/benchmark/linpackjava/.

Die Brute-Force-Programme greifen daher oftmals nicht mehr nur auf die CPU sondern insbesondere auf die GPU zu. Webanwendungen müssen auf diese Bedrohung angemessen reagieren und mit der Zeit gehen. Dazu gehört, dass Passwörter niedriger Stärke abgelehnt und neuere Hashverfahren und Salting eingesetzt werden.

Vorteile von gesalzenden Hashes

Für gesalzene Hashes spricht, dass ein Angriff mittels einer Streuwerttabelle relativ nutzlos wird.

Streuwerttabellen beinhaltet eine vorgenerierte Liste an Hashes für eine Vielzahl von Wörtern und Zeichenkombination. Man versucht bei einem solchen Angriff durch einen Vergleich des Hashes in der Datenbank mit dem Hash in der Hash-Tabelle auf das eingesetzte Wort zu schließen. Da eine solche Streuwerttabelle unter Umständen mehrere Terabyte an Daten enthält, ist sie erstens kaum zu verarbeiten und zweitens würde ein vergleichender Rückschluß sehr lange dauern.

Um die Menge an Daten einer Streuwerttabelle zu verkleinern und sie somit in kurzer Zeit durchsuchbar zu machen, wurde eine spezielle Form einer solchen Streuwertabelle entwickelt. Diese Datenstruktur nennt man Regenbogentabelle (engl. Rainbow-Tables) und wurde vom Schweizer Informatiker Philippe Oechslin im Jahr 2003 entwickelt
[http://lasecwww.epfl.ch/pub/lasec/doc/Oech03.pdf]
, wobei der Ansatz schon im Jahr 1980 durch Martin Hellman
[M. E. Hellman. A cryptanalytic time-memory trade off. IEEE Transactions on Information Theory, IT-26:401–406, 1980]
beschrieben wurde. Rainbowtables sind in gewisser Weise stark verkleinerte Streuwert-Tabellen, in denen viele Passwörter mit den dazugehörigen Hashes gespeichert sind. Bei Regenbogentabellen werden nicht alle Ausgangswerte und Hashes gespeichert, sondern der Wert wird zuerst gehashed und anschließend reduziert. Die Reduktion erzeugt eine Zeichenkette mit der Länge des Ausgangswerts und ist damit also ein mögliches Passwort. Dieser Prozess der Reduktion wird mehrmals durchlaufen, um eine bestimmt Menge (eine Kette) an möglichen Passwörtern zur Verfügung zu haben (= ein Spektralbereich des Regenbogens). In die Regenbogentabelle wird regelmäßig nur der Ausgangswert und der letzte Hashwert gespeichert (Start und Ende des Spektralbereichs bzw. der Kette). Das Nachschlagen in einer solchen Regenbogentabelle ist zweischrittig. Der erste Schritt ist die Bestimmung der Kette. Fällt ein Hash in den Spektralbereich, dann berechnet man diese Kette (diesen Teil des Spektralbereichs) neu. Dabei hat man soviele Chancen den Ausgangswert zu finden, wie diese Kette lang ist. Wenn der Hash in der Tabelle steht findet man das Passwort also viel schneller als mit einem normalen Brute-Force Programm.

Daraus resultiert, dass unter Verwendung eines gesalzenen Hashes ein solcher Angriff nur auf ein einzelnes Nutzerkonto ausgeführt werden kann, denn jeder Hash ist aufgrund einer zufällige vorangestellten Zeichenkette erstellt worden. Damit wird ein Problem behoben, dass entsteht, wenn mehrere Nutzerkonten das gleiche Passwort verwenden, also identische Hashes haben. Anstatt zwei identischer Hashes wird durch den zufälligen Salzanteil nun jeweils ein unterschiedlicher Hash erzeugt.

Nachteile von gesalzenen Hashes

Die Passworter können wegen der Zufälligkeit nicht angefordert werden. Man kann sie nur neu generieren. Das mag einerseits einen Useability-Nachteil bedeuten, andererseits bietet es einen deutlichen Sicherheitsvorteil.

Die Bibliothek "phpass" und ein Blick auf andere CMS/CMF

Seit 2004 gibt es die Bibliothek "Portable PHP password hashing framework"
[http://www.openwall.com/phpass/]
geschrieben von Solar Designer <solar[at]openwall.com> unter einer Public Domain Lizenz. Diese Bibliothek reimplementiert als Kernmethode den in PHP verfügbaren CRYPT_BLOWFISH Hashing-Algorithmus. Der Blowfish Algorithmus wurde 1993 (im Jahr 2010 ist er 17 Jahre alt) durch Bruce Schneier entwickelt und beschrieben
[http://www.schneier.com/paper-blowfish-fse.html]
. Das Blowfish Verfahren ist nicht patentiert und lizenzfrei verfügbar.
[http://www.schneier.com/blowfish.html]
Diese Open-Source Verfügbarkeit bewirkte eine rasche Verbreitung in der Open-Source Szene. Blowfish bietet auch heute noch (2010) eine mit aktuellen Algorithmen vergleichbare Sicherheit und Geschwindigkeit. Als weitere Fallbacks bietet phpass ein CRYPT_EXT_DES und ein MD5-basiertes Hashing. Diese Bibliothek wird von Backpress/Wordpress
[http://backpress.automattic.com/browser/tags/1.0.2/includes/class.passwordhash.php]
Drupal und TYPO3
[http://typo3.org/extensions/repository/view/t3sec_saltedpw/current/, Typo3 Extension T3Sec_SaltedPW]
eingesetzt.

Instanzierung

Durch Autoloading kann jederzeit auf die Klasse zugegriffen werden. Auch eine Constructor Injection ist möglich.

# systemweites autoloading
$security = new Clansuite_Security();

# Holen des Objekts aus dem Dependency Injector
$config = $this->injector->instantiate('Clansuite_Security');

# Automatisches holen bei Verwendung der Constructor Dependency Injection
public function __construct(Clansuite_Security $security)
Verwendung

Die Methode build_salted_hash() Die Methode nimmt als ersten Parameter eine Zeichenkette entgegen und als zweiten Parameter die Abkürzung eines Hashing-Algorithmus. Diese Zeichenkette wird am Anfang mit einer zufällige Zeichenkette versehen. Dieses Voranstellen einer zufälligen Zeichenkette nennt man salzen (engl. salting). Die neu entstandene Kombination aus Salz+Zeichenkette wird dann der Hashing Methode generate_hash() übergeben, um von ihr einen Hash als Rückgabewert zu erhalten.

Die Methode generate_hash() Die Methode generiert einen Hash aus einer Zeichenkette unter Verwendung eines Hashing-Algorithmus. Dabei wird auf die PHP-Funktion hash() zurückgegriffen. Somit stehen beispielsweise die Hashing-Algorithmen md5, sha1, sha256 zur Verfügung. Als das Standardverfahren ist sha1 festgelegt. Um eine komplette Liste der verfügbaren Hashing Algorithmen des Kommandos hash() zu erhalten, eignet sich die PHP-Kommandokombination print_r(hash_algos()); . Falls hash() nicht verfügbar sein sollte, wird als Fallback auf die PHP-Kommandos md5() bzw. sha1() zurückgegriffen. Falls sie die PHP Extension "skein" installiert haben und in der Konfiguration als Hash-Algorithmus skein festgelegt haben, dann wird ein 512-bit Skein-Hash erstellt. Sie finden die PHP Extension auf Skein Webseite unter http://www.skein-hash.info/downloads.

Die Methode generate_salt() Diese Methode erzeugt einen Zufallsstring der gewünschten Länge. Der Zufallsstring besteht Zahlen, sowie Groß- und Kleinbuchstaben und den Sonderzeichen . und /. Die "Zufälligkeit" von Zeichen wird mittels mt_srand() and mt_rand() erzeugt.

5.3.25. Clansuite_Session

Das PHP Sessionhandling ist ein sicherheitskritischer Bereich. Die normalen PHP Sessions sind ungeschützt.

Sicherung von Session-Cookie

a) Sicherung von Session-Cookies mittels SSL und Secure Flag Wenn Clansuite mit SSL verwendet wird, ist das Cookie "secure" flag zu setzen. Dies sorgt dafür, dass der Cookie nicht unverschlüsselt gesendet wird, sondern so verschlüsselt, sodass niemand den Cookie stehlen kann.

b) Cookie HTTPONLY Das Session-Cookie kann mittels der Konfigurationseinstellung "cookie_httpOnly" gegen XSS geschützt werden. In diesem Fall werden Javascripte wirksam davon ausgeschlossen die Session ID zu stehlen.

Zufällige SessionID für jede Clansuite Installation

Falls zwei Clansuite Applikationen sich auf dem gleichen Server befinden und sich einen Sessionspace teilen, ist es möglich das beide Applikationen gegenseitig Sicherheitslöcher in das Sessionhandling reißen. Es gibt zwei Methoden um dies zu unterbinden: Erstens, wenn sie Clansuite_Session (DB) verwenden, legen Sie für jede Installation eine Datenbank an. Installieren sie nicht zwei Clansuite Versionen (eine für ein Blog) die andere für den Clan. Zweitens, wenns die Session im save_path abgespeichert wird, dann ist jeder Clansuite Installation ein eigenes Sessionverzeichnis zu geben. So kommen die zwei Versionen sich nicht in die Quere.

Niedrigen Session Timeout ansetzen (maxlifetime)

Je weniger Zeit ein Session Fenster hat, desto sicherer ist es. Die Session Lifetime kann in der Clansuite Konfiguration eingestellt werden.

Schutz vor Session Fixierung (Session Fixation)

Einer Session Fixation kann man nur durch Erneuerung der SessionID bei Änderung des Userstatus (login/logout) begegnen. Die Erneuerung der Session erfolgt mittels Clansuite_Session::regenerateID(). Sie ist direkt mit der Login-Funktion verknüpft.

Session Hijacking

Session Hijacking bedeutet, dass ein Dritter sich den Inhalt der Session zu eigen machen kann. Häufig geschieht dies über Man-in-the-middle Attacken oder Sniffing/XSS. Guten Schutz bietet nur die Verwendung von "cookie_httpOnly" und SSL-Verschlüsselung.

Session Validation

Clansuite hat für die Sessionvalidierung den Filter Session Security. Doch die Session Validierungsregeln, z. B. die Überprüfung, ob die Session von der gleichen IP oder der Request vom gleichen User-Agent kommt, halten einem Session Hijacking nicht stand. Zusätzlich bereiten Session-Überprüfungen eine Menge Probleme. a) Man schließt bestimmte IPs aus. Bei bestimmten Providern hat jeder Request eine neue IP (AOL). Stichwort: Proxy Farming. b) User-Agent HTTP Header Checks c) Accept Header Check Aus vorgenannten Gründen wird vom Einsatz des Sessionfilters abgeraten.

5.3.26. Clansuite_Upload

5.3.27. Clansuite_Download

Verwendung

Die Klasse Clansuite_Download stellt die Methode send() bereit, mit der eine Datei an den Client gesendet werden kann. Dabei ist es möglich die Downloadgeschwindigkeit zu beschränken und bestimmte Teilbereiche (ranged) auszuliefern, sowie abgebrochene Downloads an alter Stelle wieder aufzunehmen (resume). Die Beschränkung der Downloadgeschwindigkeit ist von diversen Downloadportalen bekannt, wo zwischen beschränktem, aber freiem Gast-Zugang und unbeschränktem Mitgliederzugang, welcher dann oftmals kostenpflichtig ist, unterschieden wird. Die Auslieferung von Teilbereichen einer Datei macht es möglich, gleichzeitig mehrere Connections zu öffnen und unterschiedliche Dateisegmente herunterzuladen. Diese Funktionalität kommt Downloadmanagern sehr entgegen. Durch die Aufteilung in Segmente kann auch der Fortsetzungpunkt für einen abgebrochenen Dateitransfer bestimmt werden. Die Klasse verwendet die PHP-Erweiterung fileinfo
[http://php.net/manual/en/book.fileinfo.php]
. Diese gehört seit PHP 5.3 zum Standardfunktionsumfang.

Instanzierung und Verwendung

Die Klasse kann sowohl statisch als auch dynamisch eingesetzt werden. Die Verwendung statischer Methoden wird empfohlen.

Beispiel für die Verwendung von Clansuite_Download
# Beide Beispiele senden die Datei "datei.zip" mit 10 KB/s an den Client

# dynamische Verwendung
$download = new Clansuite_Download();
$download->sendFile('datei.zip', 10);

# statische Verwendung
Clansuite_Download::send('datei.zip', 10);

5.3.28. Clansuite_Staging

Die Klasse Clansuite/Staging ermöglicht, dass eine bestimmte Staging-Konfigurationsdatei in Abhängigkeit vom Domainnamen zusätzlich zur allgemeinen Konfigurationsdatei geladen und mit dem allgemeinen Konfigurationsarray verbunden wird. Beim Verbinden der beiden Konfigurationen zum allgemeinen Konfigurationsarray werden bestehende Werte der allgemeinen Konfiguration durch die besonderen Konfigurationseinstellungen der Staging-Konfiguration überschrieben. Die Konfigurationseinstellungen aus der Staging-Konfiguration gehen also immer denen der allgemeinen Konfiguration vor.

Das Staging muss in der allgemeinen Konfiguration aktiviert werden. Dazu den Parameter "staging = 1" setzen.

clansuite.config.php

Das Staging ist vom Domainnamen abhängig. Eine Beispielkonfiguration der virtuellen Domains könnte wie folgt aussehen:

hosts ergänzen (C:\WINDOWS\system32\drivers\etc\hosts)

Danach sind die virtuellen Hosts in der Webserverkonfiguration einzustellen. Beim XAMPP findet sich die Datei im Verzeichnis: D:\xampp\apache\conf\extra.

httpd-vhosts.conf ergänzen (D:\xampp\apache\conf\extra)

6. Kapitel 6 - Die Konfigurationseinstellungen

In diesem Kapitel lernst du die Konfigurationseinstellungen, Variablen und Konstanten von Clansuite kennen und einsetzen.

Anfangs besprechen wir was Konfigurationseinstellungen, Variablen und Konstanten sind und welche es gibt. Du erfährst aus welchen Dateien die Konfigurationseinstellungen geladen, welche Bedeutung sie haben und in welchen Dateien sie verwendet werden.

Sodann werden die allgemeinen Konstanten, sowie die absoluten und relativen Pfadkonstanten dargestellt. Absolute Pfade bezeichnen die Verzeichnispfade des Betriebsystems. Relative Pfade bezeichnen die Verzeichnispfade mit Bezug zur Webumgebung (URL). Es schließt sich die Darstellung der Versionierungskonstanten an. Sie geben Auskunft darüber, in welchem Entwicklungsstadium sich Clansuite gerade befindet.

Das Kapitel schließt mit der Erläuterung der sogenannten Rendererkonstanten. Bei Rendererkonstanten handelt es sich um Platzhalter für Pfad-, Metatag-, Versions-, und Seitenangaben, die in allen Renderern verfügbar sind.

6.1. Was sind Konfigurationseinstellungen, Konstanten und Variablen?

Was sind Konfigurationseinstellungen?

Konfigurationseinstellungen sind Variablen, die in der allgemeinen Konfigurationsdatei von Clansuite ("/configuration/clansuite.config.php") oder in einer Modulkonfigurationsdatei (z.B. "/modules/news/news.config.php") gesetzt wurden. Diese Konfigurationsdateien entsprechen dem INI-Format. Sie werden mit dem entsprechenden Konfigurationswerkzeug für INI-Dateien geladen und dabei in Variablen überführt.

Die allgemeine Konfiguration beinhaltet unter anderem Pfadeinstellungen und die Verbindungsdaten zur Datenbank.

Was sind Variablen?

Variablen sind benannte Speicherplätze für Werte.
[PHP Handbuch - Kapitel "Variablen"]
Sie sind nur im jeweiligen Sichtbarkeitsbereich
[PHP Handbuch - Kapitel "Geltungsbereich von Variablen"]
verfügbar und in ihrem Zuweisungsgehalt änderbar. Es ist zu beachten, dass einige der Variablen der allgemeinen Konfigurationsdatei bei der Initialisierung des Systems verwendet werden, um daraus Konstanten zu bilden.

Was sind Konstanten?

Konstanten sind im Gegensatz zu Variablen systemweit verfügbar. Sie werden nur einmal definiert und sind dann in ihrem Zuweisungsgehalt nicht änderbar.
[PHP Handbuch - Kapitel "Konstanten"]
Um auf die grundsätzlich wichtige Bedeutung für das gesamte System aufmerksam zu machen, schreibt man Sie immer groß!

Was sind Arrays und Objekte?

Unabhängig vom Wissen über Konstanten und Variablen zur Konfiguration des Systems sind an dieser Stelle zwei weitere Dinge wissenswert, da sie auf dem vorher gesagten aufbauen. Zum einen, dass ein Array eine Liste von Variablen ist. Diese Listen können mehrdimensional, also verschachtelt sein. Dabei wird einem Schlüssel ein Wert zugeordnet. Zum anderen, dass ein Objekt ein Behälter mit Struktur und Funktionen (dann Methoden genannt) ist.

6.2. Konfigurationseinstellungen

6.2.1. Allgemeine Konfigurationsdatei

Die allgemeine Konfigurationsdatei von Clansuite befindet sich im Ordner "/configuration". Sie trägt den Namen "clansuite.config.php".

Inhalt der allgemeinen Konfigurationsdatei "/configuration/clansuite.config.php"

Die Nummerierung in den Sektionsüberschriften dient der Zuordnung der Verwendungsorte dieser Einstellungen. Eine entsprechende Legende finden Sie nach der Konfigurationsdatei. Die entsprechende Übersicht findet sich nach dem Quelltext.

;----------------------------------------
; database                           01
;----------------------------------------
[database]
db_host = "localhost"
db_type = "mysql"
db_username = "clansuite"
db_password = "toop"
db_name = "clansuite"
db_prefix = "cs_"
db_cache = "APC"

;----------------------------------------
; config                             02
;----------------------------------------
staging = 0

;----------------------------------------
; email                              03
;----------------------------------------
[email]
mailmethod = "mail"
mailerhost = ""
mailerport = ""
mailencryption = "SWIFT_OPEN"
smtp_username = ""
smtp_password = ""
from = "system@website.com"
from_name = "Clansuite CMS - HAL 9000"
to_sysadmin = ""

;----------------------------------------
; template                           04
;----------------------------------------
[template]
pagetitle = "Team Clansuite"
favicon = ""
theme = "standard"
backend_theme = "admin"

;----------------------------------------
; switches                           05
;----------------------------------------
[switches]
themeswitch_via_url = 0
languageswitch_via_url = 0

;----------------------------------------
; defaults                           06
;----------------------------------------
[defaults]
module = "index"
action = "show"
dateformat = "l, d.m.Y H:i"

;----------------------------------------
; language                           07
;----------------------------------------
[language]
language = "de"
outputcharset = "UTF-8"
timezone = "Europe/Berlin"
gmtoffset = 3600

;----------------------------------------
; login                              08
;----------------------------------------
[login]
login_method = "nick"
remember_me_time = 90
max_login_attempts = 5
login_ban_minutes = 30
min_pass_length = 6
hash_algorithm = "sha1"
salt = "1-3-5-8-4-1-7-2-4-1-4-1"
registration_term = ""

;----------------------------------------
; openid                             09
;----------------------------------------
[openid]
trustroot = "http://www.clansuite.com/openid/"
showloginbox = 1

;----------------------------------------
; upload                             10
;----------------------------------------
[upload]
max_upload_filesize = 1048576

;----------------------------------------
; session                            11
;----------------------------------------
[session]
session_expire_time = 30
session_name = ""
check_ip = 1
check_browser = 1
check_host = 1

;----------------------------------------
; error                              12
;----------------------------------------
[error]
debug           = 0
xdebug          = 0
development     = 0
debug_popup     = 0
webdebug        = 0

;----------------------------------------
; cache                              13
;----------------------------------------
[cache]
adapter = "apc"
caching = 0
cache_lifetime = 90

;----------------------------------------
; maintenance                        14
;----------------------------------------
[maintenance]
maintenance = 0
maintenance_reason = "SITE is currently undergoing scheduled maintenance.<br />Sorry for the inconvenience. Please try back in 60 minutes."

;----------------------------------------
; meta                               15
;----------------------------------------
[meta]
description = "Clansuite - just an e-sport content management system."
language = "de"
author = "Jens-André Koch & Clansuite Development Team"
email = "system@clansuite.com"
keywords = "Clansuite, open-source, eSport, cms, clan,content management system, portal, online gaming"

;----------------------------------------
;                                    16
;----------------------------------------


;----------------------------------------
; locale                             17
;----------------------------------------
[locale]
dateformat = "l, d.m.Y H:i"
timezone = 0

;----------------------------------------
; statistics                         18
;----------------------------------------
[statistics]
enabled = 1

;----------------------------------------
; updater                            19
;----------------------------------------
[updater]
enabled = 1
interval = 604800

;----------------------------------------
; logging                            20
;----------------------------------------
[logs]
rotation = 1
1 Die Zugangsdaten für die Datenbank. Diese sind wichtig für Doctrine.
2 Staging
3 Die Emaileinstellungen. Diese sind relevant innerhalb des Mail-Wrappers und für das Versenden von Mails.
4 Template- und Layoutgrundkonfiguration.
5 Verfügbare Konfigurationsschalter als URL Parameter, sogenannte Switches.
6 Defaults. Grundeinstellungen für Modulecontroller und Actioncontroller.
7 Sprache
8 Login
9 OpenID
10 Upload
11 Session
12 Fehlerbehandlung.
13 Cache
14 Warungsmodus
15 Die Meta-Tag Angaben für den Head-Bereich der HTML Seiten.
16 --
17 Locale
18 Statistik.
19 Updater.
20 Logging.

6.2.2. Konfigurationsdatei eines Moduls

Die Konfigurationsdatei eines Moduls befindet sich im jeweiligen Modulverzeichnis. Sie trägt den Namen des Moduls und die Dateiendung ".config.php".

Pfadbeispiele
konkret: /news/news.config.php
konkret: /forum/forum.config.php
abstrakt: /modulname/modulname.config.php

6.2.3. Die Konfigurationseinstellungen von PHP

Um eine Liste aller Konfigurationseinstellungen der PHP-Umgebung zu erhalten, kann der Befehl phpinfo() oder alternativ ini_get_all() eingesetzt werden. Alternativ kann man den Inhalt einer Variablen auch mittels des Befehls ini_get() oder get_cfg_var() ermitteln. Um zur Laufzeit der Anwendung neue Werte zu setzen, verwendet man ini_set().

Dabei ist auf die Konfigurationsdirektiven, welche die Sichtbarkeitsbereiche festlegen zu achten (PHP_INI_ALL, PHP_INI_PERDIR, oder PHP_INI_SYSTEM). Eine vollständige Übersicht über die Direktiven findet sich im PHP-Handbuch (http://php.net/manual/de/ini.list.php). Insbesondere die Konfigurationsdirektiven für den Sprachkern von PHP sind von erheblicher Bedeutung (http://www.php.net/manual/de/ini.core.php). Performancerelevant sind unter anderem die Schlüssel "memory_limit", "realpath_cache_size" und "realpath_cache_ttl".

6.2.4. Checkliste für die Einführung von neuen Konfigurationseinstellungen

Anmerkung
Checkliste für die Einführung von neuen Konfigurationseinstellungen
  1. Entscheiden, in welchem Sichtbarkeitsbereich die neu einzuführende Einstellung eingesetzt werden soll.

    1. Für das ganze System verfügbar.

    2. Für den Bereich eines Moduls verfügbar.

  2. Die entsprechende ".config.php" Datei ändern. Dabei die Namenskonventionen für die Bezeichnung von Konstanten und Variablen beachten.

    1. Wichtig: Wenn eine Einstellung für das ganze System eingeführt wird, dann ist diese auch immer in die Vorlagedatei für die Konfiguration des Installationsprogramms einzuführen.

  3. Bei Bedarf die Eingabemaske (templateseitig) um die neue Einstellung ergänzen.

  4. Die neue Einstellung dokumentieren.

6.3. Überblick über Konstanten

6.3.1. Allgemeine Konstanten

Allgemeine Konstanten
IN_CS

Diese Sicherheitskonstante wird zu Beginn der index.php gesetzt und definiert den Applikationsinnenbereich. Sie ist allen Clansuite Klassen vorangestellt und verhindert den direkten Aufruf der PHP Datei via URL. Dabei wird in der ersten Zeile geprüft, ob "IN_CS" gesetzt ist, andernfalls wird die Ausführung beendet.

PS

Abkürzung für das Pfadtrennzeichen (PATH_SEPARATOR ";")

DS

Abkürzung für das Verzeichnistrennzeichen (DIRECTORY_SEPARATOR - "/" oder "\", je nach Betriebssystem)

PROTOCOL

Abkürzung für das Serverprotokoll (entweder http:// oder https://)

SERVER_URL

Abkürzung für die Webadresse des Servers. (PROTOCOL . $_SERVER [SERVER_NAME])

DB_PREFIX

Der Präfix der Datenbanktabellen. ($config[database][db_prefix])

NL

Abkürzung für eine neue Zeile mit HTML-Zeilenumbruch ein. Enspricht "<br />\r\n"

CR

Fügt einen HTML Zeilenumbruch (engl. Carriage Return) ein. Enspricht "\n".

DEBUG

Konstante für die Aktivierung und Deaktivierung des Debugmodus wird über die Konfiguration [error][debug] gesetzt

DEVELOPMENT

Konstante für die Aktivierung und Deaktivierung des Applikationsentwicklungsmodus wird über die Konfiguration [error][development]

XDEBUG

Konstante für die Aktivierung und Deaktivierung der XDEBUG Unterstützungsfunktionen wird über die Konfiguration [error][xdebug]

6.3.2. Absolute Pfadkonstanten

Absolute Pfade bezeichnen die Verzeichnispfade des Betriebsystems. Sie enden immer mit einem Directory-Separator Slash.

Absolute Pfadkonstanten
ROOT

Arbeitsverzeichnis der index.php getcwd()

ROOT_CACHE

Verzeichnis für das Caching = ROOT . cache . DS

ROOT_CONFIG

Verzeichnis für die Konfiguration = ROOT . configuration . DS

ROOT_CORE

Verzeichnis des Clansuite Cores = ROOT . core . DS

ROOT_LANGUAGES

Verzeichnis der Sprachen = ROOT . languages . DS

ROOT_LOGS

Verzeichnis für das Logging = ROOT . logs . DS

ROOT_LIBRARIES

Verzeichnis der Bibliotheken = ROOT . libraries . DS

ROOT_MOD

Verzeichnis der Module = ROOT . modules . DS

ROOT_THEMES

Verzeichnis der Themes = ROOT . themes . DS

ROOT_UPLOAD

Verzeichnis für den Upload = ROOT . uploads . DS

6.3.3. Relative Pfadkonstanten (Webpfade, URLs)

Relative Pfade bezeichnen die Verzeichnispfade mit Bezug zur Webumgebung (URL). Sie enden immer mit einem abschließenden Directory-Separator Slash.

Relative Pfadkonstanten (Webpfade, URLs)

6.3.4. Clansuite Versionskonstanten

Sie geben Auskunft darüber, in welchem Entwicklungsstadium sich Clansuite gerade befindet.

Clansuite Versionskonstanten
CLANSUITE_VERSION

Gibt die Versionnummer zurück.

CLANSUITE_VERSION_STATE

Gibt das Entwicklungsstadium (alpha, beta, rc, final) zurück.

CLANSUITE_VERSION_NAME

Gibt den Namen der Version zurück.

CLANSUITE_VERSION_REVISION

Gibt die aktuelle Revisionnummer des Versionsverwaltungssystems (Subversion) zurück.

CLANSUITE_URL

Gibt den Link zur Clansuite-Webseite http:://www.clansuite.com zurück (relevant für Updates).

6.4. Rendererkonstanten

Die folgenden Konstanten und Variablen sind in allen Renderern als Platzhalter verfügbar. Sollte natives PHP Rendering eingesetzt werden, so sind sie direkt verfügbar. Der Syntax zur Verwendung der Variablen ist vom jeweiligen Renderer abhängig.

6.4.1. Verwendung der Platzhalter in Smarty-Templates

Für den Renderer Smarty können die nachfolgenden Variablen als Platzhalter in den Templates verwendet werden.

konkret:  {$www_root}
abstrakt: {$variablenname}

6.4.2. Webpfade

Webpfade
www_root

Dies ist der allgemeine Webpfad des Systems. Er entspricht der Konstante WWW_ROOT. Beispiel: http://www.yourdomain.com/clansuite/

www_root_upload

Webpfad zum Uploadverzeichnis. Er entspricht der Konstante WWW_ROOT ergänzt um das Upload Verzeichnis.

www_root_mod

Der Webpfad zum aktuell angeforderten Modul. Er entspricht WWW_ROOT ./modules/ . Clansuite_TargetRoute::getModuleName() . /

www_root_theme

Der Webpfad zum Frontend-Theme der jeweiligen User-Session.

www_root_themes

Der Webpfad zum Verzeichnis aller Themes.

www_root_themes_frontend

Der Webpfad zum Verzeichnis "/themes/frontend".

www_root_themes_backened

Der Webpfad zum Verzeichnis "/themes/backend".

www_root_themes_core

Der Webpfad zum Verzeichnis "/themes/core", in welchem Templates und Styles für den Clansuite Core zu finden sind.

Achtung Bitte beachte den kleinen Unterschied (das "s") zwischen "www_root_theme" und "www_root_themes".

6.4.3. Meta-Tags

Meta Tags geben einer Suchmaschinen Auskunft über den Inhalt der Seite. Das Meta-Array entspricht der Definition in der Konfiguration ( $this→config[meta] ) und hat somit nachfolgende Struktur.

Meta-Tags
meta.description

Meta-Beschreibung

meta.language

Meta-Sprache

meta.author

Meta-Autor

meta.email

Meta-Email

meta.keywords

Meta-Keywords / SEO-Schlüsselwörter

6.4.4. Clansuite Version

Clansuite Version
clansuite_version

Gibt die Versionnummer zurück.

clansuite_version_state

Gibt das Entwicklungsstadium (alpha, beta, rc, final) zurück.

clansuite_version_name

Gibt den Namen der Version zurück.

clansuite_version_revision

Gibt die aktuelle Revisionnummer des Versionsverwaltungssystems (Subversion) zurück.

6.4.5. Platzhalter mit Bezug zur aktuellen Seite

Platzhalter mit Bezug zur aktuellen Seite
pagetitle

Gibt den Seitentitel zurück.

css

Gibt das standardmäßig eingestellte Cascading Style Sheet zurück. $this→config[std_css]

javascript

Gibt das standardmäßig eingestellte Javascript zurück. $this→config[std_javascript]

trail

Gibt die Brotkrümmelspur (Breadcrumb) Navigation zurück.

templatename

Gibt den Namen des angeforderten Templates zurück.

modulename

Gibt den Modulenamen zurück. Clansuite_TargetRoute::getModuleName()

actionname

Gibt den Actionnamen zurück. Clansuite_TargetRoute::getActionName()

6.4.6. Hinzufügen von Rendererkonstanten

Rendererkonstanten können auf zwei verschiedene Arten hinzugefügt werden. Erstens kann man die abstrakte Klasse Clansuite_Renderer_Base erweitern. Die ergänzten Werte stehen dann allen RenderEngines zur Verfügung. Zweitens kann man die konkrete Render_Engine erweitern. Dann stehen die ergänzten Werte nur innerhalb der jeweiligen RenderEngine zur Verfügung.

Von Konstanten zu sprechen ist eigentlich nicht ganz richtig. Es sind Variablen die an den View assigned werden. Wir sprechen aber von Konstanten, weil sie im Sicherbarkeitsbereich des Views immer zur Verfügung stehen.

Ergänzen von allgemeinen Rendererkonstanten durch Erweiterung von Clansuite_Renderer_Base

Die allgemeinen Rendererkonstanten werden in der abstrakten Klasse Clansuite_Renderer_Base festgelegt. Alle RenderEngines erweitern diese abstrakte Basisklasse und übernehmen somit ihre Methoden und Eigenschaften. Die Klasse Clansuite_Renderer_Base befindet sich im Verzeichnis "/core/renderer/" und hat den Dateinamen "renderer.base.php". Innerhalb dieser Klasse gibt es eine Methode mit dem Namen getConstants(). Diese Methode ist für das Zurückliefern der Konstanten in der Form eines Arrays zuständig. Um einen Zugriff auf die Konstanten innerhalb des Views zu ermöglichen, wird dieses Array durch die jeweilige RenderEngine an den Sichtbarkeitsbereich des Views (RendererScope) übergeben (assigned). Regelmäßig implementiert dabei die RenderEngine Klasse das assign-Kommando bevor eine Ausgabe erfolgt.

Für die RenderEngine Smarty gestaltet sich der Ablauf folgendermaßen: Zunächst erweitert der Renderer_Smarty die Basisklasse. Vor dem Rendern der Ansicht wird dann die Methode $this→getConstants(); der Basisklasse aufgerufen. Innerhalb des Smarty Renderers erfolgt dies in der Methode assignConstants().

Übernahme der Rendererkonstanten aus der Basisklasse am Beispiel von Smarty
# class declaration
class Clansuite_Renderer_Smarty extends Clansuite_Renderer_Base

# fetch the general clansuite constants from Clansuite_Renderer_Base->getConstants()
$this->renderer->assign($this->getConstants());
Ergänzen von speziellen Rendererkonstanten durch Erweiterung einer RenderEngine

Die speziellen Rendererkonstanten werden nur für den Sichtbarkeitsbereich einer bestimmten RenderEngine festgelegt. Dazu ist zunächst eine Methode innerhalb des Renderers erforderlich, welche die Konstanten und Variablen definiert und als Array zurückliefert. Als nächstes ist die Übergabe des Arrays an den View erfoderlich (assignen).

Für die RenderEngine Smarty sieht das folgendermaßen aus. Vor dem Rendern der Ansicht wird die klasseneigene Methode $this→getSmartyConstants(); aufgerufen. Innerhalb des Smarty Renderers erfolgt dies in der Methode assignConstants().

Übernahme der Rendererkonstanten aus einer klasseneigenen Methode am Beispiel von Smarty
# fetch the specific smarty constants from Clansuite_Renderer_Smarty->getSmartyConstants()
$this->renderer->assign($this->getSmartyConstants());

7. Kapitel 7 - Der Aufbau eines Clansuite Moduls

Das Kapitel erläutert den Aufbau eines Clansuite Moduls. Im ersten Abschnitt des Kapitels beschäftigen wir uns mit der Frage, was ein Clansuite Modul ausmacht. Im zweiten Abschnitt gehen wir der Frage nach, was für Techniken uns die objektorientierte Programmierung anbietet, um Module zu erstellen, miteinander zu verbinden und eine Applikation daraus aufzubauen. Im dritten Abschnitt gehen wir einen Schritt weiter und fragen nach den konkreten Techniken und Hilfsmitteln die das Clansuite Framework bereitstellt, um ein Modul schnell und einfach zu erstellen. Das Kapitel schließt mit dem vierten Abschnitt, indem die Arbeit mit dem Clansuite_ModuleBuilder erklärt wird.

7.1. Was ist ein Clansuite Modul?

Ein Entwicklungsziel von Clansuite war, den Application Layer so zu gestalten, dass sich Module schnell und einfach schreiben und anpassen lassen.

Module können als die Bausteine einer Applikation verstanden werden. Wir wissen aber immernoch nicht, wie ein solcher Baustein beschaffen ist. Um einer Beliebigkeit im Modulaufbau entgegenzuwirken, bedarf es einer genauen Definition, einer Konvention für Module. Zunächst werden wir daher feste Regeln für ein Modul aufstellen. Diese Regeln definieren also, wann etwas im Rahmen des Clansuite CMS ein Modul ist.

Konventionen für ein Clansuite Modul
a) Verzeichnisstruktur
b) Dateien
c) Schnittstellen
d) Klassen
e) Basisklasse
f) Templates
g) Metainformationen
h) Übersetzung

7.1.1. Verzeichnisstruktur

Die Verzeichnisstruktur eines Moduls wiederspiegelt die MVC-Schichtentrennung. Es gibt ein Verzeichnis für jeden Schichtenbereich (also "controller", "model" und "view"). Diese Verzeichnisstruktur wird erweitert, um das Verzeichnis mit den Übersetzungsdaten "languages". Hier werden die Gettext-Lokalisierungsdaten abgelegt. Optional ist das Verzeichnis "events", es dient zur Ablage der Ereignisobjekte eines Moduls .

clansuite                     Applikationsverzeichnis von Clansuite
 +--modules                   Wurzelverzeichnis aller Module.
     +--modulename            Verzeichnis eines Moduls.
         +--controller        Verzeichnis für die Geschäftslogik (engl. business logic).
             +--actions       Optionales Verzeichnis für die Ablage einzelner ActionController.
         +--events            Optionales Verzeichnis für die Ablage von Ereignisobjekten des Moduls.
         +--languages         Verzeichnis für die Lokalisierungsdaten des Moduls (Gettext).
         +--model             Verzeichnis für die Datenzugriffslogik.
             +--records       Verzeichnis für Doctrine Records
         +--view              Verzeichnis für die Präsentationslogik. Zumeist befinden sich dort Templates.

7.2. Objektorientierte Techniken zur Erstellung von Modulen

Die Mechanismen der Objektorientierung sollen uns helfen, diese Module zu definieren und interagieren zu lassen. Fraglich ist also, was für Techniken uns die objektorientierte Programmierung anbietet, um Module zu erstellen, miteinander zu verbinden und eine Applikation daraus aufzubauen.

7.2.1. Vererbung und Bildung einer Klassenhierarchie

Zuerst können wir an die Vererbung denken. Klassen können von anderen Klassen erben. Dadurch entsteht eine Klassenhierarchie.

Basisklasse erweitern

Beispielsweise kann ein Modul eine bestehende Basisklasse für Module erweitern. Sie wissen an dieser Stelle bereits, das jedes Clansuite_Module die Basisklasse Clansuite_Module_Controller erweitert. Am Beispiel des News-Moduls sei die dabei entstehende Klassenhierarchie verdeutlicht:

Clansuite_Module_Controller (Basisklasse)
 |
 +--- Clansuite_Module_News (Erweiterung)

Alle Methoden der Basisklasse auch in der Erweiterung zur Verfügung. Oder anders formuliert, die Erweiterung bringt möglicherweise neue Eigenschaften und Methoden für die Basisklasse mit oder überlädt bereits bestehende.

Erweiterung einer Moduleklasse (Erweiterung der Erweiterung)

Des weiteren ist es möglich die Klasse zu erweitern, welche die Basisklasse erweitert.

Clansuite_Module_Controller (Basisklasse)
 |
 +--- Clansuite_Module_News (Erweiterung)
       |
       +--- Clansuite_Module_News_Extension (Erweiterung der Erweiterung)

In der Klasse Clansuite_Module_News_Extension stehen alle Methoden und Eigenschaften der Erweiterung und der Basisklasse zur Verfügung.

7.2.2. Dekorieren von Modulen

Beim Dekorieren von Modulen, sprich Klassen, werden diese zur Laufzeit um neue Funktionalitäten erweitert. Anders formuliert: ein bestehendes Objekt wird mit neuen Eigenschaften oder Methoden umhüllt.

7.2.3. Dependency Injection

Zur Technik der Abhängigkeitsauflösung durch die verschiedenen Dependency Injection Methoden verweise ich auf den Abschnitt "Lose Kopplung" im Kapitel 5.

7.3. Techniken das Clansuite Framework zur Erstellung von Clansuite Modulen

Im zweiten Abschnitt gehen wir der Frage nach, welche konkreten Techniken das Clansuite Framework bereitstellt, um ein Modul zu entwickeln.

7.4. Hilfsmittel zur Erstellung von Clansuite Modulen

Dieser Abschnitt behandelt Techniken und Hilfsmittel zur Erstellung von Clansuite Modulen.

Im Vordergrund steht die Konzentration von Methoden und Eigenschaften in der allgemeinen Klasse Clansuite_Module_Controller. Jeder Modulcontroller erweitert die Klasse Clansuite_Module_Controller. Damit stehen die allgemeinen Methoden und Eigenschaften dieser Klasse jedem Modulcontroller zur Verfügung. Unnötige Quelltextdopplung in den Modulen wird so vermieden und ein Modul, sowie insbesondere eine Modulaction, besteht nur noch aus den wichtigsten Informationen.

Durch die Trennung in Applikationssschichten werden Datenbankenabfragen aus der Moduldatei in das jeweilige Model des Moduls verlagert. Dadurch kann das Model geändert werden, ohne die Moduldatei ändern zu müssen.

Ein Entwicklungsziel von Clansuite war, den Application Layer so zu gestalten, dass sich Module schnell und einfach schreiben und anpassen lassen. Module können als die Bausteine einer Applikation verstanden werden. Fraglich isy

Clansuite definiert Modularität wie folgt: Ein Modul ist eine Einheit von zusammengehöriger Funktionalität, die

Das Verwaltungsmenü eines Moduls (modulenavigation)

Grundanliegen ist ein einheitliches Verwaltungsmenü für alle Module. Die Menüstruktur innerhalb eines Moduls wird durch den Smarty Tag Dort werden einige feste Slots mit standardisierten Benennungen definiert. Diese haben gleichbleibende Name wie "Overview", "Create", "Settings". Es ist auch weiterhin möglich individuelle Navigationen für die Verwaltung eines Moduls zu verwenden.

Wird kein Template mittels setTemplate() gesetzt, wird der Methodenname automatisch als Templatename eingesetzt. Eine Action namens "action_admin_show" hat daher das Template "action_admin_show.tpl".

# Set Layout Template
$this->getView()->setTemplate('directory/index.tpl');

# Prepare the Output
$this->prepareOutput();

7.5. Der Inhalt eines Modulverzechnisses

7.6. Info - Die Informationsdatei (modulename.info.php)

Jedes Modul verfügt über eine Metainformationsdatei. Die Metainformationen werden z. B. im Bereich der Moduleverwaltung angezeigt, um das Modul korrekt zu identifizieren. Die "modulename.info.php" Datei stellt Clansuite Metainformationen des Moduls zur Verfügung. Die Datei folgt der Dateinamenskonventions "modulename"+".info.php". Das Dateiformat ist das normale .ini Format. Die Dateiendung ist aus Sicherheitsgründen zwingend ".php". Die Einträge sind Schlüssel/Wert Paare. Sie werden durch das Zeichen "=" getrennt. Wenn man die Werte in Anführungeszeichen (") setzt, dann ist es auch möglich Zeilenumbrüche einzufügen. Es ist ebenfalls möglich Kommentare einzufügen. Dazu wird das Semikolon der zu kommentierenden Zeile vorangestellt. Aus Sicherheitsgründen ist es ebenfalls wichtig, dass die ersten Zeilen der Konvention entsprechen.

7.7. Routes - Die Routingdatei eines Moduls (modulename.routes.php)

Die Routingdatei namens "modulename.routes.php" enthält eine Auflösungstabelle für die URL Action Paare. Ein solches Paar besteht auf Schlüsselseite aus einer URL und ihren Teilelementen, auf der Wertseite aus den passende Methodenaufrufen des jeweiligen Modulcontrollers. Damit definieren Routes also sogenannte Resourcen- Zielseiten. Diese Relationstabelle kann man sich wie eine Sitemap des Moduls vorstellen. Je Modul wird eine URLs Auflösungstabelle geführt. Bei der Installation werden sie mit der Hauptauflösungstabelle des Systems verschmolzen. So wird beim Systemstart eine einzige Definitionsdatei namens "clansuite.routes.php" für das Routing geladen. Eine Veränderung des Modulroutings führt zu einer automatischen Anpassung des allgemeinen Routings.

7.8. Events - Die Ereignisdefinitionsdatei eines Moduls (modulename.events.php)

Ein Modul kann Ereignisobjekte mitbringen. Um beim Durchlaufen der Applikation an den definierten Ereignisstellen ein Ereignis auszulösen, müssen wir bereits beim Applikationsstart wissen, welche Ereignisobjekte eines Moduls aktiviert sind und geladen werden müssen. Dazu wird die Ereignisdefinitionsdatei des Moduls herangezogen. Die "modulename.events.php" Datei stellt dazu ein entsprechendes Konfigurationsarray bereit.

Um beim Applikationsstart nicht jedesmal alle Modulverzeichnisse zu durchlaufen, um einzelnen Ereignisdefinitionsdateien zu laden, wird eine allgemeine Eventkonfigurationsdatei erstellt. Diese fast alle verfügbaren und aktivierten Ereignisse alle Module zusammen. Sie wird ergänzt durch die vom Core mitgebrachten Ereignisse. Diese zentrale Eventkonfigurationsdatei wird beim Systemstart geladen. Eine Veränderung der Eventkonfiguration eines Moduls führt zu einer automatischen Anpassung der allgemeinen Eventkonfiguration.

7.9. Die Controllerdateien

Clansuite unterstützt zwei Arten von Controllern. Einerseits Modulecontroller. Diese Dateien stellen eine Bündelung von ActionControllern dar. Dieses Verfahren der Bündelung von ActionControllern wird auch vom Zend Framework eingesetzt. Andererseits ActionController. Diese Dateien stellen einzelne Kommandos/Tasks dar. Clansuite unterstützt zwei Arten von Controllern: Modulecontroller und Actioncontroller. Modulecontroller sind Dateien, die eine Bündelung von Actioncontrollern beinhalten. ActionController sind Dateien, welche ein einzelnes Kommandos bzw. eine Action beinhalten.

Es gibt eine Reihenfolge beim Suchen nach ActionControllern. Zuerst wird immer der ModuleController nach dem ActionController durchsucht. Sollte er nicht gefunden werden, wird nach einem einzelnen ActionController gesucht. Sollte auch dieser nicht zur Verfügung stehen, wird eine Exception ausgelöst.

Wenn Sie im Debug und Development Modus des Systems sind, wird zu dieser Exception der Schnellentwicklungslink angeboten. Damit können sie den nicht verfügbaren ActionController erstellen.

7.10. Erweiterung eines Moduls zur Laufzeit (Module-Plugins)

Ein Modul kann zur Laufzeit des Programms durch den Moduledecorator um weitere Methoden ergänzt werden.

7.11. Erstellung von Modulen mit dem Clansuite Modulebuilder

In diesem Abschnitt wird der Clansuite Modulebuilder, ein Assistent (engl. wizard) für die Erstellung der Modulstruktur eines Clansuite Moduls beschrieben. Diese Modulstruktur besteht aus bestimmten Verzeichnissen und Dateien, die ein Clansuite Modul immer benötigt. Eine genaue Beschreibung der Anforderungen an ein Clansuite Modul finden Sie im ersten Abschnitt dieses Kapitels. Der Assistent dient also dazu, den Entwickler beim Einhalten dieser genauen Modulstruktur zu unterstützen und ihm einige wiederkehrende Tätigkeiten abzunehmen.

Grundsätzlich läuft dieser Vorgang so ab, dass sie zunächst den Bauplan des Moduls beschreiben. Die Beschreibung erfolgt dabei schrittweise unter Verwendung der grafischen Oberfläche des Clansuite_Builders. Aus der Beschreibung wird dann automatisch ein Rahmen bzw. Gerippe für das Modul erstellt. Dieser Modulrahmen ist bereits funktionstüchtig und kann anschließend manuell weiterentwickelt werden, bis die von Ihnen angezielte Funktionalität vollständig bereitsteht. Aus dem Modulrahmen entsteht so ein vollständiges funktionstüchtiges Modul.

7.11.1. Programmiertechnik und Entwurfsmuster

Die Skeleton-Programmierung und die Schablonenmethode

Diese Art der Programmiertechnik nennt man auch Skeleton-Programmierung. Skeleton-Programmierung bezeichnet ein Programmierungsverfahren, bei dem zunächst eine automatisch generierte Programmgrundstruktur erzeugt wird, um später auf diese Grundstruktur zurückzugreifen und sie weiterzuentwickeln. Die automatisch generierte Programmgrundstruktur setzt sich dabei zumeist aus Vorlagen zusammen. Im Bereich der objektorientierten Programmierung wird für das Vorhalten von Vorlagenzumeist auf die Schablonenmethode (engl. Template-Method) als Entwurfsmuster zurückgegriffen.

Das Stumpf-Entwurfsmuster

Ein weiteres Entwurfsmuster welches im Zusammenhang mit Skeletons häufig eingesetzt wird, ist das Stumpf- Muster (engl. stub). Im Bereich der Programmierung bezeichnet ein Stumpf den Anknüpfungspunkt für eine spätere Entwicklung. Dabei ist ein Stumpf regelmäßig eine Vereinfachung. Wenn sie beispielsweise den Rückgabewert einer Funktion aus Gründen der Vereinfachung festsetzen, dann können sie bereits mit der Methode arbeiten, ohne etwa den Algorithmus zur Berechnung des Rückgabewerts implementieren zu müssen.

Ein konkretes Beispiel mag die Programmiermethode Stumpf erläutern. Sie wollen eine grafische Darstellung Ihres Außenthermometers auf dem Bildschirm erzeugen. Derzeit haben sie allerdings keine Temperaturdaten als Anknüpfungspunkt für eine Visualisierung zur Verfügung, weil sie die Datenstruktur der vom Thermometer gelieferten Werte noch nicht kennen. Sie erhalten das entsprechende Handbuch mit der Spezifikation erst in einigen Tagen. Um dieses Problem erstmal zu umgehen und zu einer Visualisierung zu gelangen, definieren Sie eine Methode getThermometerTemperature(), die einen festen Temperaturwert von beispielsweise 18,5 Grad Celsius zurückliefert. Auf diese Methode können sie nun in den Visualisierungsmethoden zurückgreifen, um eine vorläufige Anzeige zu erhalten und die Darstellung schonmal auszuarbeiten.

Später steht Ihnen die Spezifikation der Datenstruktur des Thermometers zur Verfügung. Sie sind nun in Lage die Datenstruktur zu verstehen und einen Parser dafür zu entwickeln. Damit verfügen Sie nun über dynamische Temperaturdaten und können den festen Temperaturwert in getThermometerTemperature() durch einen Zugriff auf den Temperaturwert innerhalb der geparsten Datenstruktur ersetzen. Die Programmiermethode Stumpf hat Ihnen also geholfen, erstmal mit der Entwicklung fortzufahren und später daran anzuknüpfen.

Das Mock-Objekt

Im Kontext von objektorientieren Design gibt es einen weiteren Begriff der eng mit der Stumpf-Methode verwandt ist. Es ist das sogenannte Mock-Objekt. Ein Mock-Objekt ist eine Objekt-Attrappe, die Methoden und Eigenschaften des echten Objekts lediglich vortäuschend bereitstellt und somit vorgibt das echte Objekt zu sein. Mock-Objekte werden im Bereich der testgetriebenen Softwareentwicklung eingesetzt, um die Interaktion eines Objekts mit seiner Umwelt zu testen. Dazu ist es erforderlich auch das innere des Objekts nachzubilden. Nachgebildet werden zumeist die Kommunkationsschnittstellen des Objekts, die dann zum Testszenario passende Werte zurückliefern. Mehr zu Mock-Objekten und testgetriebener Entwicklung erfahren Sie im Kapitel 14. Als weiterführende Literatur empfehle ich aber auch den Artikel "Mocks aren’t Stubs" von Martin Fowler.

8. Kapitel 8 - Der View - von Render-Engines, Themes und Templates

Der View stellt die Daten des Modells dar und nimmt Nutzeraktionen entgegen. Es ist das V in MVC. Es handelt sich also um die Präsentationsschicht der Anwendung.

Wir wissen bereits, dass die Module im Idealfall so programmiert sind, dass sie Logik soweit wie möglich von der Darstellung trennen. Ein Modul bezieht seine Daten aus der Datenbank. Anschließend werden sie eventuell noch weiterbearbeitet und dann für die Ausgabe vorbereitet und schließlich der Präsentationsschicht übergeben. Folgt man diesem Trennungsprinzip, dann darf ein Modul im Logikbereich keine direkte HTML-Ausgabe bewirken.

Die Präsentationsschicht arbeitet mit Templates. Alle Ansichten eines Moduls werden durch Template-Implementierungen ermöglicht. In der Realität gibt es einige wenige Ausnahmen. So werden bei Clansuite die Exception- und Fehlerbehandlungsseiten, sowie stark verschachtelte Baumstrukturen nicht vollständig als Templates implementiert. Bei ersteren könnte ein Fehler im Bereich des Views die Darstellung des Fehlers behindern. Clansuite verwendet allerdings Templates, um die direkte Fehlerausgabe zu ergänzen. Mehr dazu erfahren sie im Kapitel über das Fehler- und Exceptionhandling. Bei letzterem würde man die Schleifenanweisung unnötig wiederholen: einmal für die Aufbereitung der Baumstrukturen und einmal für die Darstellung im Template.

Achtung: manchmal wird leider fälschlicherweise von "die View" gesprochen. Mein Sprachgefühl mag trügen, aber ich halte das für falsch. Es scheint neuerdings eine Tendenz zu geben, das deutsche Geschlecht für das englische Wort zu verwenden. Insbesondere scheint dies für die "Verweiblichung" der Wörter zuzutreffen. Ins Deutsche übersetzt heißt es zwar "die Ansicht", aber in Verbindung mit einer englischen Vokabel ist der deutsche Artikel in diesem Fall maskulin, also "der View", und nicht feminin "die View". Ähnlich auch der Duden für den(!) "Ad-View"
[http://www.duden.de/rechtschreibung/Ad_View]
, bei dem man nicht von "die Ad-View", sondern von "der Ad-View" spricht, obwohl man "die Werbeansicht/anzeige" sagt.

Ein lesenswerter Artikel über das Für und Wider Templateengines ist http://articles.sitepoint.com/article/beyond-template-engine.

Für Entwickler gilt die Faustregel: Ein Modul ist dann gut geschrieben, wenn nur Templatedateien geändert werden müssen, um die Ansichten vollständig zu verändern.

Platzhalter

Im Bereich der Präsentationsschicht werden Platzhalter verwendet. Ein Platzhalter ist ein Zeichen oder eine Zeichenkette, die stellvertretend für etwas steht. Es ist eine Positionsmarke für die später an dieser Stelle anzuzeigenden Daten. Als Beispiel für Funktion und Nutzen von Platzhaltern, soll der Serienbrief dienen. Bei einem Serienbrief wird ein Text an eine Vielzahl von Personen versandt. Dabei möchte man aber den Brieftext nicht jedesmal neu schreiben müssen, nur weil sich im Briefkopf Name und Anschrift geändert haben. Regelmäßig wird nun ein Platzhalter für die Adresse eingesetzt und die einzelnen Empfängeradressen in einer Datenbank abgelegt. Beim Druck des Serienbriefs wird nun über die Empfängeradressen iteriert und diese werden in den Briefkopf eingesetzt.

Push-View und Pull-View Strategie

Grundsätzlich lassen sich zwei Wege unterscheiden, wie die anzuzeigenden Daten in den View gelangen. Wir unterscheiden die "Push-View" von der "Pull-View" Strategie. Beim Push View werden die anzuzeigenden Daten durch den Controller an den View übergeben. Beim Pull View werden die anzuzeigenden Daten durch den View vom Model erfragt. Clansuite setzt beide Varianten ein.

Vorrang hat die Push-View Strategie. Dazu wird die allgemeine Geschäftslogik eines Moduls im ModuleController und ActionControllern implementiert. Diese Geschäftslogik wird möglicherweise auf ein oder mehrere Models zurückgreifen, um Daten zu beziehen und diese aufzubereiten. Danach werden die aufbereiteten Daten an den View übergeben. Die Push-View Strategie hat Vorteile und Nachteile. Nachteilig ist der Verlust an Flexibilität. Denn die Daten die gepushed werden sollen, müssen im Vorraus definiert werden. Die Definition erfolgt durch Abruf der Daten über Geschäftslogik des Models und Übergabe an den View mittels der Methode $view→assign(data). Zum anderen vermittelt die Push-Strategie eine erhöhte Sicherheit, denn die Geschäftslogik entscheidet, welche Daten angezeigt werden.

Nachranging ist das Pull-View Verfahren. Dazu wird die allgemeine Geschäftslogik eines Moduls im ModuleController und ActionControllern implementiert. Diese Geschäftslogik wird ein oder mehrere Model-Objekte holen. Doch anstatt aus diesen Models Daten zu holen. Wird das Model einfach an den View übergeben. Die Datenextraktion und Aufbereitung aus dem Model obliegt also nun dem View.

Modultemplates

Ein Modul bringt regelmäßig Templates mit. Diese kann man als Moduletheme bezeichnen. Sie stellen die Basisausgabe des Moduls dar. Das Verzeichnis der Templates ist "/modulename/templates". Die Dateiendung der Templates ist ".tpl".

Templatenamenskonvention

Templates haben eine Namenskonvention. Der jeweilige Actionname ist auch der Dateiname des Templates. Lautet der Name der Action beispielsweise action_news_show(), so wird ein Template names action_news_show.tpl erwartet. Die Templateautomatik wird im Bereich der Modullogik durch Verwendung der Methode $this→prepareOutput() ausgelöst. Abbedingen kann man sie durch explizites setzen eines anderen Templates mittels der Methode setTemplate(meinAlternativesTemplate.tpl) innerhalb der jeweiligen Action.

# Modulecontroller (/modules/demonstration/demonstration.module.php)
class Clansuite_Module_Demonstration extends Clansuite_Module_Controller implements Clansuite_Module_Interface
{
    # Actioncontroller namens "action_eine_demonstration"
    public function action_show()
    {
        $this->prepareOutput();
    }
}

# Das zugehörige Template der Methode Clansuite_Module_Demonstration->action_show() ist im Modulverzeichnis:
/modules/demonstration/templates/action_show.tpl
# Es wird geladen, wenn kein gleichnamiges Template im aktiven Theme gefunden wird.
Erstellen eines Modulethemes

Diese Modultemplates kann man als Vorlage verwenden, wenn sie eine andere Art der Ausgabe bevorzugen. Das geht sehr einfach, indem sie die das Template-Verzeichnis des Moduls mit samt den Templates in einen Themeordner kopieren und dem Ordner den Namen des Moduls geben.

8.1. Unterstützung von Render Engines

Clansuite unterstützt mehrere Render Engines.

8.2. Ablaufplan bis zum View eines Widgets

Smarty->trigger_error('Error! Failed t...')
smarty_function_load_module(Array, Object(Smarty), Object(Smarty_Internal_Template))
call_user_func_array('smarty_function...', Array)
Smarty_Internal_Plugin_Handler->__call('load_module', Array)
Smarty_Internal_Plugin_Handler->load_module(Array, 'function')
include('D:\xampplite\ht...')
Smarty_Internal_Template->renderTemplate()
Smarty_Internal_Template->getRenderedTemplate()
Smarty->fetch('index.tpl')
Clansuite_Renderer_Smarty->render('action_show.tpl')
Clansuite_Module_Controller->prepareOutput()
Module_News->action_show()
Clansuite_Front_Controller->forward(Object(Clansuite_HttpRequest), Object(Clansuite_HttpResponse))
Clansuite_Front_Controller->processRequest(Object(Clansuite_HttpRequest), Object(Clansuite_HttpResponse))
Clansuite_CMS::execute_Frontcontroller()
Clansuite_CMS::run()

8.3. Ablaufplan bis zum Aufruf einer bestimmten RenderEngine am Beispiel von Smarty

Clansuite_CMS::run()
Clansuite_CMS::execute_Frontcontroller()
Clansuite_Front_Controller->processRequest( object(HttpRequest)[30], object(HttpResponse)[31] )

Module_Index->execute( object(HttpRequest)[30], object(HttpResponse)[31] )
ModuleController->processActionController( object(HttpRequest)[30] )
Module_Index->action_show( )
ModuleController->prepareOutput( )
ModuleController->getView( )
ModuleController->getRenderEngine( )

Clansuite_Renderer_Factory::getRenderer('smarty', Object(Phemto))
Clansuite_Renderer_Smarty->__construct(Object(Phemto), Object(Clansuite_Config))
Clansuite_Renderer_Smarty->initializeEngine()

Smarty_Internal_Template->renderTemplate()
Smarty_Internal_Template->getRenderedTemplate()
Smarty->fetch('index.tpl')

Clansuite_Renderer_Smarty->render('action_show.tpl')

8.3.1. Viewhelper

Templates enthalten hauptsächlich HTML und Platzhalter. Jedoch gibt es auch in Templates bestimmte Stellen, an denen wiederholend einsetzbare Präsentations-Logik nötig ist. Diese unterstützenden Funktionen der Präsentations-Logik sind in sogenannten Viewhelpern enthalten. Das View-Helper-Pattern ergänzt also das MVC- Pattern in der View-Schicht. Der Viewhelper "date" wird Sie beispielsweise dabei unterstüzen, den Datumsstring in das richtige Datumsformat umzuwandeln und anzuzeigen.

Arten von Viewhelpern

Es gibt mehrere Arten von Viewhelpern. Zum einen gibt es die Block-Tag Viewhelper. Block-Tags benötigen immer einen öffnenden und schließenden Tag. Beispielsweise benötigt der öffnende Tag <a> auch immer den schließenden Tag </a>. Regelmäßig wird die Transformationsfunktion des Viewhelpers auf dem eingeschlossenen Inhalt ausgeführt. Neben den Block-Tag Viewhelpern gibt es Tag Viewhelper und Platzhalter Modifizierer. Tag- Viewhelper sind einfache Aufrufe von Funktionen der Präsentations-Logik. Beispielsweise wird der Tag- Aufgabe direkt auf den Platzhalterdaten aus. Ein Beispiel für die Verwendung eines Modifizierer ist {$name|@uppercase}. Hier wird der Inhalt der Variable $name der Modifierfunktion mit Namen "uppercase" unterzogen. "Uppercase" sorgt dafür, das alle Zeichen in $name als Großbuchstaben formatiert ausgegeben werden.

Verzeichnisse der Viewhelper

Die offiziellen Smarty Viewhelper befinden sich im Verzeichnis /libraries/smarty/plugins. Sie werden bereits mit Smarty ausgeliefert. Die Clansuite Viewhelper für Smarty befinden sich im Verzeichnis /core/viewhelper/smarty. Es ist auch möglich, dass ein Modul ein Viewhelper-Plugin mitbringt.

Die oben genannten Pfade werden bei Initialisierung des Smarty Renderers als Plugin-Verzeichnisse registriert. Damit kann aus jedem Verzeichnis neue Funktionalität geladen werden.
[http://www.smarty.net/manual/de/tips.componentized.templates.php, Smarty Handbuch - Template/Script Komponenten]

Der Viewhelper zur Übersetzung innerhalb von Templates

Module sollten immer darauf achten, übersetzbar zu sein; für Templates gilt dasselbe. Leute, die Themes erstellen benötigen den blanken Text, um damit arbeiten zu können und Übersetzer erwarten, dass sämtlicher Text durch die Funktion t() geschleust wurde.

# Die Verwendung des Block-Tags {t} bewirkt die Übergabe des Textes an die Übersetzungsfunktion t().
{t}Der zu übersetzende Text.{/t}
Konfigurationsdateien in der Präsentationsschicht

Diese Funktionalität kann mittels Smarty erreicht werden. Smarty bietet dazu den Tag {$smarty.config}, um auf Konfigurations-Variablen zuzugreifen. Geladen werden kann eine Konfigurationsdatei mit dem Tag {config_load file=beispiel.conf}. Die Konfigurationsvariablen referenziert man im Template mit umschliessenden
[http://www.smarty.net/manual/de/language.function.config.load.php]

An dieser Stelle sei auch ein Vergleich zu Typo3’s TypoScript gestattet. TypoScript ist, entgegen dem Namen, keine Skriptsprache, sondern eine Anzahl von Konfigurationseinstellungen die als Baumstrukturen abgelegt sind und eine Veränderung der Präsentation bewirken. Im wesentlichen entspricht die Konfigurationsdatei dem INI Format mit Sektionen und Untersektionen entspricht. Nichts anderes stellen die Konfigurationsdateien von Smarty dar. Letztlich wird hier nochmals im Präsentationsbereich abstrahieren und die Veränderungsnotwendigkeit der Templatedateien selbst eingeschränkt, indem man die Konfigurationsdatei bearbeitet.

8.4. Debugging im View

8.4.1. Smarty

Der Befehl "debug"

Der Smarty Befehl "debug" kann eingesetzt werden, um den Umgebungsbereich eines Templates anzusehen. Es öffnet sich die Smarty Debug Console und sie erhalten einen Überblick über eingebundene Templates und die Übersicht über die Templatevariablen und ihren Inhalt.

{debug}
Der Modifier "firebug"

Der Modifier "firebug" kann an jede Variable angehängt werden, um die Ausgabe des Variableninhalts in die Firebug-Console zu bewirken. Oft ist dies die bessere Debugginglösung, da die Ausgabe von Inhalten nicht durch Debugging-Ausgaben unterbrochen oder gestört wird.

{$variable|firebug} oder {$variable|@firebug}

8.5. Der Viewhelper Datagrid

Der Viewhelper Datagrid ist datenbindungsfähig und erzeugt den HTML Quelltext für eine Tabelle. Er vereinfacht die tabellarische Anzeige von Daten eines Models erheblich und trägt zu einer standardisierten Ausgabe bei.

Es ist einstellbar, ob auch Navigations-, Sortierungs-, Such- sowie Paginierungselemente in die Ansicht eingefügt werden sollen. Wenn mehr als die Darstellung der an das Datagrid übergebenen Daten erfolgen soll, also interaktive Elemente zur Steuerung der Tabelle und ihrer Daten hinzukommen, dann muss die Tabelle immer auch in ein Formular eingebettet werden.

8.5.1. ResultsPerPage einstellen

Um das Drop-Down Element "ResultsPerPage" anzupassen, kann die Methode setResultsPerPageItems() verwendet werden.

$datagrid->getRenderer()->setResultsPerPageItems(array ( 3, 5, 10, 25, 50));

8.5.2. Einzelne Anzeigemerkmale der Tabelle einstellen

Die Anzeigemerkmale können mittels der Methoden enableFeature(), disableFeature() einzeln ein- und ausgeschaltet werden. Sie können sowohl einzelne, als auch gleich mehrere Merkmale ein- oder ausschalten. Übergeben Sie den Methoden dazu entweder einen String oder ein Array mit mehreren Strings.

# Ausschalten eines Anzeigemerkmals mittels String
$datagrid->disableFeature('Label');

# Ausschalten mehrerer Anzeigemerkmale des Datagrids mittels Array
$datagrid->disableFeature(array('Label', 'Caption', 'Description'));

9. Kapitel 9 - Die Fehlersuche und das Testen

Das Kapitel gliedert sich in zwei thematisch zusammenhängende Teile. Der erste Abschnitt beschäftigt sich mit Methoden und Werkzeugen der Fehlersuche (engl. debugging) in Clansuite. Bei der Fehlersuche geht es darum, den Ursprung eines Fehlers in der Software zu finden und zu beheben. Der zweite Abschnitt beschäftigt sich mit einer speziellen Form der Fehlervorbeugung, dem Testen. Beim Testen geht es darum, Fehler zu finden und es gar erst zu einem Fehler kommen zu lassen.

9.1. Methoden und Werkzeuge zur Fehlersuche

Clansuite stellt eine Reihe von Debugging Tools zur Verfügung, die dem Entwickler einen Einblick in einen Problembereich eröffnen und somit beim Lösen von Fehlern und Entwickeln zur Seite stehen. Grundsätzlich kann man die Aufgabe von Debugging Tools beschreiben, als das Bereitstellen von zusätzlichen Informationen, die bei normaler Nutzung der Anwendung nicht eingesehen werden können. Sie erweitern also den Wahrnehmungsbereich des Entwicklers. Die Erweiterung des Wahrnehmungsbereichs ist ebenfalls ein wichtiger Punkt im Bereich des Fehler- und Exceptionshandlings. Eine abgeschaltete oder unterdrückte Fehlerbehandlung, bewirkt dass sich so mancher Fehler unterhalb der Wahrnehmungsgrenze für den Entwickler bewegt. Für beide Bereiche gilt, dass sie jeweils nur im Entwicklungsmodus eines Systems verfügbar sein sollten, da sie ansonsten Tür und Tor für eine unbestimmte Vielzahl von Angriffen eröffnen.

Dies führt zur Feststellung das das Fehlerhandling teilweise automatisiert ist und teilweise durch den Entwickler gesteuert werden kann. So wird PHP automatisch einen Fehler werfen, wenn sie eine Syntaxregel misachten. Das Exceptionhandling und der Einsatz von Debugging-Befehlen sind hingegen vollständig vom Entwickler steuerbar.

Die Problembereiche können dabei an mannigfaltigen Stellen auftreten, so z. B. im Bereich des Zuweisungsgehalts einer Variablen oder einer Konstante oder bei komplexen mehrdimensionalen Arraystrukturen. Man sollte meinen, dass eine Skript- bzw. Programmiersprache wie PHP5, die speziell als Sprache entwickelt wurde, um Webanwendungen zu erstellen, ein funktional ausreichendes Angebot an Debuggingwerkzeugen bereitstellt. Doch leider ist dies nicht der Fall. PHP bietet keine integrierten Debugging Werkzeuge. Das Angebot im Bereich der Fehleranalyse ist spärlich und meiner Ansicht nach sträflich vernachlässigt worden. Dies gilt sowohl für den Bereich des Highlevel-, wie auch des Lowlevel-Debuggings. Mit Highlevel-Debugging bezeichne ich die Verwendung von PHP Umgebungserweiterungen, die einen tieferen Einblick in die Vorgänge des Systems ermöglichen. Zu diesen Highlevel-Tools gehört Beispielseweise das Debugger-Projekt "xdebug". Mit Lowlevel-Debugging meine ich PHP Syntaxelemente, die es ermöglichen auf einfache Art und Weise eine Fehleranalyse durchzuführen.

9.1.1. Einfache Debugging-Elemente des PHP Syntax

Als einfache Elemente des PHP Syntax, die sich zum Debuggen eignen, kommen grundsätzlich die Ausgabefunktionen "echo", "print", "print_r", "var_export", "var_dump" und die Abbruchfunktionen "exit" und "die" in Betracht.

Verwenden Sie bitte "var_dump();" anstelle von "print_r();", um den Inhalt einer Variablen zu prüfen. Hilfreich ist oft auch "var_export();". Sollte eine bestimmte Stelle in der Applikation zu debuggen sein, kann wahlweise mit einem anschießenden "exit();" oder einem "die();" der Applikationslauf gestoppt werden.

9.1.2. Erweitertes Debugging mit dem Clansuite_Logger

9.1.3. Erweitertes Debugging mit der FirePHP Debugkonsole

FirePHP ist eine Erweiterung für FireBug. Beides sind Addons für Firefox. Die Funktionsweise von FirePHP ist trivial. Die anzuzeigenden Daten werden einer PHP Methode übergeben. Diese setzt sie in den Antwortheader (X- FirePHP-Data). Dort werden sie von der FirePHP Erweiterung ausgelesen und in der FireBug-Konsole dargestellt. Auf diese Art und Weise vermischt sich der Debugoutput nicht mit dem eigentlichen Seiteninhalt.

Das Firefox Addon FireBug erhalten sie unter
https://addons.mozilla.org/en-US/firefox/addon/1843

Das Firefox Addon FirePHP erhalten sie unter
https://addons.mozilla.org/en-US/firefox/addon/6149

Methode 1 - Direkte Verwendung der FirePHP Klasse

# Laden der FirePHP Klasse
require ROOT_LIBRARIES.'firephp/FirePHP.class.php');
# Instanzierung über Singleton
$firephp = FirePHP::getInstance(true);

# Loggen in die Konsole
$firephp->log('Hello World');
$firephp->dump('Key', 'Value');
$firephp->fb('Schreiben in die Konsole');

Methode 2 - Indirekte Verwendung über die Methode Clansuite_Xdebug::firebug()

Wenn Sie Clansuite_Debug verwenden, dann können Sie sich die Zeilen zur Initalisierung von FirePHP sparen, denn die statische Methode Clansuite_Debug::firebug() erledigt dies für Sie. Die Methode übergibt der Konsole ebenfalls den Ort an dem sie eingesetzt wird. Dies erleichtert das Wiederfinden der Debugging-Position im Quellcode.

# Gibt den Inhalt von $variable in der FireBug Konsole aus und verwendet dabei das Kommando log().
Clansuite_Debug::firebug($variable);

# Folgende String-Werte sind als zweiter Parameter verwendbar: info, log, warn, error.
# Gibt den Inhalt von $variable in der FireBug Konsole aus und verwendet dabei das Kommando error().
Clansuite_Debug::firebug($variable, 'error');
Tipp Setzen Sie Codevervollständigung ein, um dieses oft benötigte Kommando nicht ständig tippen zu müssen. Ich schlage Ihnen die Verwendung der Zeichenkette "fbg" für den Textschnippsel "Clansuite_Debug::firebug($variable);" vor. So brauchen Sie nur noch den Variablennamen ersetzen und sparen sich Zeit und Tipparbeit.

9.1.4. Clansuite_Debug und Clansuite_Xdebug

Mich hat das Funktionsangebot von PHP im Bereich des Debugging nicht zufrieden gestellt. Clansuite setzt daher eine eigene Debugging Klasse ein, um die Programmierung des Systems einfacher und komfortabler zu gestalten. Es gibt die Klasse Clansuite_Debug, welche verschiedene Hilfsfunktionen, wir printR()und firebug() bereitstellt. Desweiteren gibt es die Klasse Clansuite_Xdebug. Sie stellt Start und Stop Methoden bereit, um mit dem Debugger "Xdebug" zu interagieren. Diese Methoden setzen also eine installierte PHP Erweiterung "Xdebug" voraus. Grundsätzlich empfehle ich für das Debugging XDebug. Als Highlevel-Debugging Extension verschafft Xdebug, im Gegensatz zur normalen Debugging-Anzeige, eine Steigerung der Übersichtlichkeit bei Fehler- und Debugdumps durch verbesserte Darstellung der Debuginformationen. Mit Xdebug lassen sich sehr einfach Funktionsaufrufe nachverfolgen, Abhängigkeiten erkennen und die Laufzeit von Codeabschnitten ermittlen.

Hint: Den Debug-Modus können sie aktivieren, indem sie in der Konfiguration (/configuration/clansuite.config.php) die Einstellung [error] debug = 1 setzen. Für den XDebug-Modus setzen sie [error] xdebug = 1.

Die Methode Clansuite_Debug::printR()

Wenn Sie den Debug-Modus des Systems aktiviert haben, ist zusätzlich der Befehl "Clansuite_Debug::printR($assoc_array);" verfügbar. Der Befehlt hat drei Vorteile. Erstens verbessert er die Anzeige von Variablen und assoziativen Arrays. Diese werden übersichtlich aufbereitet und farblich hervorgehoben. Zweitens zeigt er den genauen Ort seiner Verwendung an. Somit ist ein schnelles Wiederfinden des Debug-Statements innerhalb des Quellcodes gewährleistet. Dies ist insbesondere dann hilfreich, wenn sie mehrere Debug-Statements einsetzen. Drittens wird die Applikation an dieser Stelle automatisch gestoppt. Ein Nachschieben der Anweisungen exit; oder die; entfällt. Die Verwendung ist trivial und analog zum PHP-Kommando print_r().

9.1.5. Konfigurationseinstellungen für das Debugging

Weitere hilfreiche Debugging Einstellungen sind:

[error]
suppress_errors = 0
debug = 1
xdebug = 1
debug_popup = 0

[switches]
phpdebug = 1
# Verwendung der statischen Methode printR() der Klasse Clansuite_Debug
Clansuite_Debug::printR($var);

# Verwendung der statischen Methode xd_varDump() der Klasse Clansuite_Xdebug
Clansuite_Xdebug::xd_varDump($var);

9.1.6. Debugging im Bereich der Präsentationsschicht

Für die Fehleranalyse im Bereich der Präsentationsschicht stehen eigene Kommandos zur Verfügung.

Verwendet man Smarty als RenderEngine, dann eignen sich die folgenden drei, die Variablenausgabe modifizierenden Smarty Befehle (Smarty Modifiers), um den Inhalt einer Variable oder eines Arrays angezeigt zu bekommen.

# Zeigt ein strukturiertes Array innerhalb des Templates.
{$array|@var_dump}

# Die Ausgabe mit dem Modifier @dump zeigt ein strukturiertes Array in einer Box innerhalb des Templates.
{$array|@dump}

# Der Modifer @dump kann auch auf mehrdimentsionale Arrays und deren Schlüssel angewandt werden.
{$array.subarray|@dump:schlüssel}

/**
 * Zeigt nur das Array an.
 * Die restlichen Ausgaben werden unterdrückt und das Programm zu Debbuging-Zwecken abgebrochen.
 */
{$array|@debug}

9.1.7. Profiling

Profiling mit XDebug

Das Profiling mit XDebug gestaltet sich sehr einfach. XDebug protokolliert im Hintergrund die Funktionsaufrufe und die relevanten Daten der Systemumgebung (Speicherverbrauch, Zeit) in eine Logdatei. Diese Logdatei kann anschließend mittels eines Analysewerkezugs wie wie KCachegrind oder Webgrind ausgewertet und visualisiert werden. Grundlegende Voraussetzung ist, dass die PHP-Erweiterung XDebug geladen ist. Als weitere Voraussetzung kommt das Aktivieren des XDebug Profilers hinzu.

Es gibt zwei Möglichkeiten den XDebug-Profiler zu aktivieren. Einerseits kann man ihn dauerhaft aktivieren. Hierfür setzt man in der php.ini die Einstellung "xdebug.profiler_enable = 1". Alternativ dazu, kann man eine Aktivierung des Profilers über einen den GET/POST Requestparameter XDEBUG_PROFILE veranlassen, beispielsweise durch den GET-Aufruf http://localhost/clansuite/index.php?XDEBUG_PROFILE. Denn unter Umständen soll nicht jede Scriptausführung durch den Profiler mitgeloggt werden, denn dies verursacht schließlich zusätzliche Last. Hierfür setzt man in der php.ini die Einstellung "xdebug.profiler_enable_trigger = 1".

Profiling mit XHProf

XHProf wurde ursprünglich als Profiler für Facebook entwickelt und im März 2009 als Open-Source verfügbar gemacht. Facebook setzt XHProf im Rahmen der hauseigenen closed-source Monitoring-Lösung XHProfLive ein. Es ist ein hierarchischer Profiler, der in C implementiert wurde und als Zend Extension zur Verfügung steht.

Der Profiler arbeitet auf Ebene der Funktionsaufrufe. Er misst deren Verarbeitungszeit (Wall Time), die CPU-Last und den Speicherverbrauch, sowie die Anzahl der Aufrufe pro Funktion. Die während des Profilings gesammelten Daten sind über ein einfaches Webinterface (PHP) einsehbar. Die Aufrufreihenfolge wird mittels eines Call-Graphen visualisiert. Die Visualisierung mittels Call-Graphen trägt dazu bei, den Überblick über größere Applikationen und Frameworks zu bewahren und ermöglicht so ein besseres Verstehen des Systems.

9.2. Das Testen

9.2.1. Warum eine Testsuite?

Wer vorher testet, muss später weniger Fehler beheben. Das Ziel des Testens ist Fehler zu entdecken.

Glenford J. Myers definiert das Testen wie folgt: "Testen ist der Prozeß, ein Programm mit der Absicht auszuführen, Fehler zu finden.".
[Glenford J. Myers, Methodisches Testen von Programmen, 1995, Oldenburg Verlag]

9.2.2. Was ist eine Testsuite?

Eine Testsuite ist eine Sammlung von mehreren Tests. Diese Sammlung wird mittels eines Test-Werkzeugs durchlaufen. Ein Test ist eine Funktionsüberprüfungen. Die Funktionsüberprüfung besteht immer aus zwei Teilen, der Funktionsbeschreibungen und dem Aufruf der entsprechenden Funktion der Applikation. Ein Test ist also ein Beispiel dafür, wie sich der Quellcode (später) verhalten soll. Der Bericht nach einer Funktionsüberprüfung, das sogenannte Testprotokoll, gibt Auskunft darüber, ob Clansuite die vom Test gewünschte Funktionen ordnungsgemäß bereitstellt. Der zusammenfassende Bericht gibt nach Durchlaufen aller Funktionsüberprüfungen Auskunft über alle identifizierten Fehlfunktionen. Man nennt ihn Testabdeckungsbericht (engl. Coverage-Report). Die Suche nach den Defekten und die Analyse der Fehlfunktionen gehört nicht in den Bereich des Testens.

Test-getriebene Entwicklung bzw. Negative Todo-Liste

Man kann Tests als negative Aufgaben- bzw. Todoliste verstehen und auch so einsetzen. Dabei schreibt man zuerst den Test, definiert also was von Clansuite erwartet wird und welche Funktion von Clansuite erfüllt werden soll. Lässt man den Test nun laufen, bekommt man logischerweise einen negativen Bericht für diesen Test. Er wurde nicht erfolgreich durchlaufen. Nun schreibt man die eigentliche Funktion für Clansuite. Lässt man den Test erneut laufen, wird er erfolgreich durchlaufen und man kann sicher sein, dass dieses Feature funktioniert. Bei diesem Verfahren spricht man von "Test getriebener Entwicklung" (engl. Test-Driven-Development, abgekürzt auch TDD).

Das Verfahren lässt sich in die drei typische TDD-Schritte aufteilen: 1. Einen neuen Test schreiben [Neues Feature bzw. Neue Funktion beschreiben] 2. Den Test scheitern lassen [Failure] 3. Code schreiben, bis Test erfüllt ist [OK]

Um einen Bug, also einen Programmfehler, mittels TDD-Verfahren zu beseitigen, kann man folgendermaßen vorgehen: 1. Einen neuen Test schreiben, der den Bug entlarvt [Fehler wird beschrieben] 2. Der Test scheitert, weil der Bug existiert [Failure] 3. Bugfix-Code schreiben, bis der Test erfüllt und der Bug gefixt ist [OK] Man spricht von "Test getriebenen Bugfixing"
[http://xunitpatterns.com/test-driven%20bug%20fixing.html]
.

Regressionstests

An dieser Stelle ist es sinnvoll auch die sogenannten Regressionstests anzusprechen. Unter einem Regressionstest versteht man die Wiederholung von Testfällen, um Verschlechterungen, also Brüche, in der Software zu finden. Regressionstests haben mehrere Voraussetzungen. Zunächst ist ein testabgedecktes und erfolgreich getestetes Feature erforderlich. Dann ist eine Veränderung erforderlich, die zu einem Bruch in der Software und somit des bereits erfolgreich bestandenen Tests führt. Insoweit kann man sagen, dass eine Verschlechterung durch einen Verbesserungsversuch (mit-)verursacht wurde.

Regressionstests knüpfen an den Zusammenhang zwischen dem alten Testlauf, dem verschlechterten Testlauf und dem wieder ausgebesserten Testlauf an. In der Praxis werden Testfälle lediglich "kontinuierlich" wiederholt. An dieser Stelle setzen Werkzeuge zur kontinuierlichen Integration an (bspw. Hudson/Jenkins , CruiseControl, Atlassian Bamboo), die dem Entwickler die Arbeit des ständigen Wiederholens des Testens abnehmen und für eine automatisierte Wiederholung der Testfälle sorgen. In welchem Testlauf ein Testfehler auftrat und/oder wieder behoben wurde ist dabei irrelevant. Ich bezeichne diese Art des Testens als "vertikales" Testen.

Theoretisch müsste ein Regressionstest jedoch durch die Testformulierung einen Bezug zwischen dem letzten erfolgreichen Test (Testlauf-1), dem nachfolgenden erfolglosen Test aufgrund der Modifikation (Testlauf-2) und dem Beheben des Regressionsfehlers (Testlauf-3) hergestellt werden. Mir ist jedoch kein Testsystem bekannt, dass eine solche Erwartung bereitstellt, um eine Rückverknüpfung zwischen den Testergebnissen mehrerer Testläufe herzustellen. Ich bezeichne diese Art des Testens als "horizontal", da durch Regressionstests horizontale Verknüpfungen zwischen den "vertikalen" Testläufen hergestellt werden.

Vorteile Test-getriebener Entwicklung

Die Test schaffen Sicherheit darüber, dass der Code auch tatsächlich das tut, was in der Funktionsprüfung beschrieben wurde. Beim Implementieren des Code wird der Entwickler durch die Tests geführt. Dabei wird keine Zeile Code geschrieben, die nicht tatsächlich auch gebraucht wurde. Der geschriebene Code ist in der Zukunft leicht änderbar und man wird durch Tests darauf hingewiesen, wenn etwas kaputt gemacht wurde. Somit lassen sich beispielsweise die angesprochenen Regressionsfehler in den Griff bekommen.

a) Überblick wahren Es ist grundsätzlich sehr schwierig die Übersicht über die Tests zu behalten. Schon für eine kleine Applikation wächst die Anzahl der Testfälle sehr schnell an. Allerdings ist die Wahrung der Zuordung von Test zu Programmcode sehr wichtig. Daher ist eine systematische und kontextabhängige Ablage und Ordnung der Tests im Dateisystem zu empfehlen. Beispielsweise können Tests nach Klassen und Funktionen sortiert abgelegt werden. Jeder Test sollte zudem im Dokumentationsblock einen natürlich-sprachlicher Kommentar enthalten, der Aufschluss über die Absicht des Tests gibt. Damit kann auch nach längerer Zeit und mehreren beteiligten Entwicklern die Frage beantwortet werden, warum der Test existiert.

b) Tests erstellen, die die Datenbank verwenden Das Arbeiten mit einer Datenbank und Tests kann sich am Anfang recht schwierig gestalten. Die Lösung ist das Einrichten einer gleichbleibenden Testumgebung, welche die Datenbank vor den auszuführenden Tests initialisiert. Dazu wird vor jedem Test ein Script aufgerufen, dass die Datenbank klont, ohne aber Daten zu übernehmen. Für die Dauer des/der Tests wird so eine reine Testdatenbank eingesetzt. Grundsätzlich werden bei diesem Verfahren also mehrere Datenbanken eingesetzt.

c) Testszenario entwerfen Es ist wichtig mit Daten zu arbeiten, die nah an der Realität sind. Grundsätzlich neigen Programmierer dazu, lediglich Testdaten im Stil von "Blabla123" oder "Test123". Testdaten sind jedoch Daten, die real aussehen. Nach Möglichkeit kann für die Generierung von Testdaten auf Hilfswerkzeuge, wie z.B. die Beispieldaten-Bibliotheken "Faker" zurückgegriffen werden.

d) Stubs Stubs ersetzen Objekte oder Methoden für den Zeitraum des Tests durch Test-Dummys. So lassen sich beispielsweise Schnittstellenaufrufe bzw. API Aufrufe von Onlinediensten wie PayPal oder GoogleMaps "ersetzen". Der Code wird für den Moment des Tests von externen Abhängigkeiten, Nebenwirkungen und langwierigen Abläufen (Verbindung zum Onlineservice) befreit werden.

e) Mocks Mocks ersetzen Objekte oder Methoden für den Zeitraum des Tests durch Test-Dummys. Damit kann getestet werden, ob Methoden wie erwartet aufgerufen wurden, und, ob die Kommunikation mit externen Abhängigkeiten tatsächlich reibungslos funktioniert, ohne den Ablauf tatsächlich zu starten.

f) Benutzeroberfläche testen / Frontendtests Für das Testen der Benutzeroberfläche muss sich der Test wie ein User verhalten und sich durch die Webanwendung klicken. Die Web-Benutzeroberflächen sind aber nicht dafür erstellt worden, um von einer Maschine getestet zu werden. Daher gestaltet sich das Testen von Benutzeroberflächen als relativ kompliziert. Die Testumgebung muss sich auf HTTP-Aufrufe, HTML-Quelltext, Umgang mit Formularen und die Auswertung von Cookies verstehen. Um diesen Vorgang zu automatisieren stehen Werkzeuge wie "Selenium", "Webrat" oder "Cucumber" bereit. Dabei werden die Benutzerschritte aufgezeichnet und sind später automatisiert und als Test abspielbar. Hierbei ist ein systematisches Durcharbeiten durch die Möglichkeiten der Benutzeroberfläche erforderlich.

Testabdeckungsbericht (Code-Coverage Report)

Der Code-Coverage Bericht gibt Aufschlüss über den Grad an Testabdeckung. Von diesem Report werden bestimmte Bestandteile von Clansuite ausgeschlossen.

a) Tests - Denn Tests werden nicht getestet. b) Templates - Denn in Templates werden nur Variablen eingesetzt. c) Fremde Bibliotheken, Komponenten und Drittanbieter (3th party) Code - Denn wir sind nicht für die Tests zuständig.

Simpletest als Testwerkzeug

Wir verwenden Simpletest für automatisierte Tests gegen den Clansuite Core und Module. Die Tests befinden bei der Entwicklerversion im Verzeichnis "/tests". Dieser Ordner wird jedoch bei Neubildung von Clansuite entfernt. Um alle Tests im Browser auszuführen, ruft man "/tests/runAllTests.php" auf.

Wir "runAllTests.php" auf der CommandLine aufgerufen, so bewirkt dies die XML Ausgabe im JUnit Format. Die erste Version dieser Ausgabe wurde von Steven Jones
[http://www.computerminds.co.uk/hudson-and-simpletest]
erarbeitet und später als Extension in den SimpleTest Core aufgenommen.

Kontinuierliche Integration mit Jenkins (früher Hudson)

Jenkins und Hudson sind synonyme Begriffe für Butler oder Diener. Es ist ein java-basierter modularer Serverdaemon. Die Einrichtung und der Umgang mit einem Server zur kontinuierlichen Integration gestaltet sich wie nachfolgend beschrieben.

Voraussetzung ist eine kontinuierliche Integration von Quellcode. Das bedeutet, dass die Mitglieder des Entwicklungsteams ihre Arbeitsanteile in regelmäßigen Abständen in das zentrale Quellcode-Repository einstellen. Natürlich können hierbei mehrfache Integrationen an einem Tag vorkommen. Jede Integration wird getestet und man bekommt ein Feedback, ob die Integration das System nachteilig verändert hat.

Normalerweise wird Quellcode kompiliert. Diese Aufgabe würde Jenkins übernehmen und damit auch den Entwicklerrechner entlasten, den regelmäßig dauert das kompilieren größerer Applikation unter Einbeziehung verschiedener Bibliotheken lange. Es besteht die Möglichkeit den Komplierungsprozess auf mehrere Rechner zu verteilen. Hierbei fungiert Jenkins als Master-Server und die Clients als Slaves. Im PHP Umfeld entfällt dieser Kompilierungsvorgang gänzlich. Ein CI-Server nimmt hier lediglich qualitätssichernde Aufgaben wahr.

Der Server arbeitet folgende Schritte ab: 1) Er stellt eine Verbindung zum Quellcode-Repository her Dies kann zeitgesteuert oder ereignisgesteuert erfolgen, beispielsweise ausgelöst durch die letzte Integration bzw. den letzten Commit. 2) Der Arbeitsbereich wird geupdatet Dazu wird der Arbeitsbereich zunächst gesäubert. 3) Sodann werden die Buildscripte ausgeführt Dies sind häufig Shell-Scripte oder Ant bzw. im PHP-Umfeld Phing Anweisungen. Für komplexe Buildanweisungen können diverse Kommandozeilenargumente und Variablen als Platzhalter eingesetzt werden. 4) Bereitstellen der Ergebnisse bzw. Reports Wichtigste Aufgabe ist natürlich das Bereitstellen der Ergebnisse der zahlreichen Werkzeuge zur Quellcodeuntersuchung.

An dieser Stelle kann Jenkins seine Stärke als Reporting und Monitoring Werkzeug voll ausspielen. Sowohl die Geschichte eines Projekts über eine Anzahl von Builds, aber auch eine Übersicht über alle ausgeführten Shellscripte für jeden Build, sowie eine Übersicht über Unit-Tests und den Test-Trend werden bereitgestellt. Aufgrund der modularen Architektur des Systems können weitere Reportingwerkzeuge sehr einfach integriert werden. Gleiches gilt natürlich für den Bereich der Benachrichtigungswerkzeuge. Hier gibt es bereits viele verschiedene Benachrichtungs-Plugins. Neben den grundsätzlichen Funktionen wie Start, Changelog, Stop, Status, ist es auch möglich eine Blame-Funktion (Autor X broke the build) bzw. Praise-Funktion (Autor X fixes the build) einzusetzen.

5) Zu guter Letzt kommt Hudson als Deploymentwerkzeug ins Spiel. Nach erfolgreichem Test wird die Software zusammengepackt und zum Download bereitgestellt.

Selenium als Testwerkzeug

Wir verwenden die Firefox Erweiterung "Selenium IDE" für die Aufnahme und die Bearbeitung von Tests und das Debbuging des Frontends der Applikation. Die aufgenommenen Tests ermöglichen ein wiederholtes und automatisiertes Testen.

Nachfolgend finden Sie die Webseite des Selenium IDE Projekts. http://seleniumhq.org/projects/ide/

Webtest als Testwerkzeug

Nachfolgend finden Sie die Webseite von Webtest. http://webtest.canoo.com/

Lasttests mit ab & siege

Unter einem Lasttest versteht man einen Test, der ein Softwaresystem systematisch unter Belastung stellt, um zu beobachten, wie sich das System verhält. Insbesondere dienen Lasttests dazu, sicherzustellen, dass ein System unter künstlichem Stress stabil und performant läuft.

Das Lasttestwerkzeug Apache Benchmark "ab"

Das Lasttestwerkzeug Apache Benchmark (genannt "ab") ruft eine Webseite auf einem Webserver mehrfach ab und berechnet aus den Wartezeiten den Mittelwert.

Das Lasttestwerkzeug "siege"

Webseite: http://www.joedog.org/index/siege-home

10. Kapitel 10 - Die Erstellung und der Einsatz von Formularen

Das Kapitel beschreibt den Umgang mit der Klasse Clansuite_Form. Sie abstrahiert die Erstellung und den Zugriff auf Formulare. Behandelt werden die manuelle Erstellung von Formularen und die automatische Erzeugung von Formularen mittels Clansuite_Formgenerator. Insbesondere wird das Zusammenspiel zwischen Clansuite_Form, Clansuite_Formgenerator, Clansuite_Formvalidation und Clansuite_Formdecorator beschrieben. Im Anschluß folgt ein Überblick über die verfügbaren Formularelemente. Das Kapitel schließt mit der Erläuterung des Clansuite Moduls Formularbuilder, einem Werkzeug um Formulare grafisch zu erstellen.

Die Formularbeschreibung unterstreicht wiederrum die MVC-Schichtentrennung. Durch die Abstraktion der Formulare werden diese eigenständig wartbar, ergänzbar und pflegbar. Zudem wird die Einheitlichkeit der Formulare, sowohl in visueller, als auch in technischer Hinsicht (HTML) gewährleistet.

10.1. Manuelle Formularerstellung unter Verwendung von Clansuite_Form

10.1.1. Instanzierung

Bei der Instanzierung des Form-Objekts werden der Formularname, die Sendemethode und die Empfangsadresse (Action) übergeben.

# Instanzierung
$form = new Clansuite_Form('news_form', 'post', 'index.php?mod=news&sub=admin&action=update&type=create');
# Setzen einer Eigenschaft, hier der CSS Klasse
$form->setClass('News');
... weitere Methodenaufrufe, insbesondere von addElement()...
$form->render();

10.1.2. Verwendung

public function action_admin_create()
{
    ( #1 - Load Form Class, wenn sie ohne Autoloader arbeiten )
    ( require ROOT_CORE . 'viewhelper/form.core.php'; )

    #2 - Create a new form
    $form = new Clansuite_Form('news_form', 'post', 'index.php?mod=news&sub=admin&action=update&type=create');
    $form->setClass('News');

    #3 Assign some formlements
    $form->addElement('text')->setName('news_form[news_title]')->setLabel(_('Title'));
    $categories = Doctrine::getTable('CsNews')->fetchAllNewsCategoriesDropDown();
    $form->addElement('multiselect')->setName('news_form[cat_id]')->setLabel(_('Category'))->setOptions($categories);
    $form->addElement('multiselect')->setName('news_form[news_status]')->setLabel(_('Status'))->setOptions($this->_Statusmap)->setDefaultValue("0");
    $form->addElement('textarea')->setName('news_form[news_body]')->setID('news_form[news_body]')->setCols('110')->setRows('30')->setLabel(_('Your Article:'))->setEditor();

    #4 add the buttonbar
    $form->addElement('buttonbar')->getButton('cancelbutton')->setCancelURL('index.php?mod=news&amp;sub=admin');

    #5 Assign the html of the form to the view
    $this->getView()->assign('form', $form->render());

    #6
    $this->prepareOutput();
}

Um das Formular im Template anzuzeigen, reicht ein einfaches {$form}.

#/templates/action_admin_create.tpl

{$form}
Die Methode setLegend()

Die Methode setLegend() setzt den Legend-Text für das Fieldset eines Formulars. Das Fieldset ist ein Standardecorator.

# Kurzform
$form = new Clansuite_Form('languages_dropdown', 'post', WWW_ROOT . 'index.php?mod=languages&sub=admin&action=new');
$form->setLegend(_('Select the language to add'));

# entspricht der Langform, die den internen Ablauf besser beschreibt
$form = new Clansuite_Form('languages_dropdown', 'post', WWW_ROOT . 'index.php?mod=languages&sub=admin&action=new');
$form->setDecoratorAttributesArray(array('form' => array('fieldset' => array('legend' => _('Select the language to add')))));

$form->setDecoratorAttributesArray(array['form']['fieldset']['legend'] = _('Select the language to add'));

Zum Zeitpunkt der Definition des Forumlars sind die Decoratoren noch nicht instanziert. Erst wenn das Forumlar gerendert wird, werden automatisch die Standard-Decoratoren hinzugefügt und ebenfalls gerendert. Daher werden die Einstellungen für diese Decoratoren zunächst in einem Array zwischen gespeichert und nach deren Instanzierung, also zeitlich kurz vor dem Rendern zugewiesen.

Achtung: beim Deaktivieren der Standarddekoratoren und Verwendung von setLegend(). Falls sie die Standarddekoratoren deaktivieren, dann wird auch der Fieldsetdekorator entfernt. Wenn sie nicht manuell einen Fieldsetdekorator einfügen, dann wird beim Versuch, den mittels setLegend() gesetzten Legend-Text zuzuweisen, ein Fehler ausgelöst, da kein Fieldset-Objekt vorhanden ist, welchem der Legend-Text zugewiesen werden kann.

10.2. Automatische Erstellung von Formularen (Clansuite_Formgenerator)

Clansuite unterstützt die automatische Erstellung von Formularen. Dabei wird andhand einer Formularbeschreibung das konkrete Formular erzeugt. Die Formularbeschreibung kann dabei auf verschiedene Arten erfolgen. Der Formgenerator unterstützt eine Beschreibung mittels PHP-Arrays, JSON sowie XML.

10.2.1. Verwendung eines Arrays zur Formularerstellung (Clansuite_Formgenerator_Array)

Das Array zur Beschreibung eines Formulars hat den nachfolgenden Aufbau. Wir unterscheiden hierbei die Beschreibungsebene des Formulars von den Beschreibungsebenen der einzelnen Formelemente des Formulars.

Auf der Beschreibungsebene des Formulars ($form_array_section) werden die allgemeinen Formulareigenschaften definiert.

Die Beschreibungsebenen der einzelnen Formelement des Formulars ($form_array_element) unterteilt sich wiederrum in zwei Kategorien. Wir unterscheiden zwingend erforderliche (obligatorische) und mögliche (fakultative) Angaben zur Beschreibung eines Formulars.

Obligatorische (zwingende) Beschreibungselemenete
/**
 * Zu den obligatorischen Angaben gehören die folgenden Beschreibungselemente:
 *
 *   [id]            => resultsPerPage_show
 *   [name]          => resultsPerPage_show
 *   [label]         => Results per Page for Action Show
 *   [description]   => This defines the Number of Newsitems to show per Page in Newsmodule
 *   [formfieldtype] => text
 *
 */
Fakultative (mögliche) Beschreibungselemenete
/**
 * Optional sind die folgenden Beschreibungselemenete
 *
 *   [value] => 3
 *   [class] => cssClass
 *
 */

$form_array = array();

10.2.2. Verwendung von JSON zur Formularerstellung (Clansuite_Formgenerator_JSON)

10.2.3. Verwendung von XML zur Formularerstellung (Clansuite_Formgenerator_XML)

10.3. Überblick über Formularelemente

10.3.1. Buttonbar

Die Buttonbar ist eine Buttonleiste mit einem Submit, Reset und Cancel Button als Steuerelemente des Formulars.

# fügt die Buttonbar in das Forumlar ein
$form->addElement('buttonbar');

Um die einzelnen Buttons innerhalb der Buttonbar zu konfigurieren, kann die Methode getButton() eingesetzt werden.

Beispiel für getButton()
$form->addElement('buttonbar')->getButton('cancelbutton')->setCancelURL('index.php?mod=news&amp;sub=admin');

# entspricht (ohne chaining)
$cancelbutton = $form->addElement('buttonbar')->getButton('cancelbutton');
$cancelbutton->setCancelURL('index.php?mod=news&amp;sub=admin');

Der Cancel-Button verwendet standardmäßig den Javascript-Aufruf "history.back()", um den Browser auf die Ausgangsseite des Formulars zurückzuverweisen. Die Zielseite des CancelButtons kann auch mit der Methode setCancelURL() konfiguriert werden.

Weitere Buttons fügen sie mit der Methode addButton() hinzu.

$form->addElement('buttonbar')->addButton('confirmsubmitbutton');

Weitere Buttons sind: "confirmsubmitbutton", "jqconfirmsubmitbutton". Beide Buttons lösen einen Bestätigungsdialog aus.

10.3.2. Captcha

CAPTCHA ist ein Akronym für "Completely Automated Public Turing test to tell Computers and Humans Apart". In wörtlicher Übersetzung bedeutet das „Vollautomatischer öffentlicher Turing-Test zur Unterscheidung von Computern und Menschen“. Beim Turing-Test soll ein Mensch entscheiden, ob sein Gegenüber ein Rechner oder ein anderer Mensch ist. Captchas stellen dieses Grundproblem in anderer Art. Hier soll der Rechner diese Antwort liefern. Grundsätzlich sind es Frage-Antwort-Tests (engl. Challenge-Response-Tests). Dabei wird die Frage so gewählt, dass sie nicht von einem Computer, sondern nur von einem Menschen gelöst werden kann. Durch dieses Verfahren versucht man sicherzustellen, dass bestimmte Internetdienste nur von Menschen und nicht von Bots benutzt werden.

Die Frage wird dabei zufällig ausgewählt.

SimpleCaptcha
reCAPTCHA

reCATPCHA wurde durch Luis von Ahn entwickelt und im Jahr 2009 durch Google gekauft. Es basiert auf einem Crowdsourcing-Ansatz bei dem der Nutzer ein Captcha aus zwei Wörtern vorgelegt bekommt. Beide Wörter entstammen der Digitalisierungen von Büchern oder Zeitschriften. Jedoch konnte die Texterkennungssoftware (engl. Optical Character Recognition) die eingescannten Wörter nicht korrekt erkennen. Für einen Menschen sind die Wörter zumeist korrekt identifizierbar. Durch die Eingabe der Wörter ins Captchafeld wird daher die Texterkennung optimiert. Es werden zwei Wörter angezeigt. Das eine Wort ist dem System bereits bekannt und durch ein vorheriges Captcha-Verfahren bestätigt, das andere ist ein unerkanntes Wort.

10.3.3. Checkbox

10.3.4. Checkboxlist

10.3.5. Confirmsubmitbutton

10.3.6. Errors

10.3.7. File

Uploadajax (File)
Uploadapc (File)
Uploadify (File)

10.3.8. Hidden

10.3.9. Image

10.3.10. Imagebutton

10.3.11. Input

10.3.12. JQConfirmSubmitButton

10.3.13. JQSelectColor

10.3.14. JQSelectDate

10.3.15. JQSelectImage

10.3.16. Label

10.3.17. Multiselect

10.3.18. Password (Text)

10.3.19. Radio

10.3.20. Radiolist

10.3.21. ResetButton

10.3.22. Select

10.3.23. SelectColor

10.3.24. SelectCountry

10.3.25. SelectDate

10.3.26. SelectLanguage

10.3.27. SelectYesNo

10.3.28. SubmitButton (Input)

10.3.29. Text

10.3.30. Textarea

Wysiwyg Editoren
Verfügbare Editoren

Es stehen die folgenden What-You-See-Is-What-You-Get Editoren zur Verfügung: 1) MarkItUp 2) NicEdit 3) TinyMCE 4) CKEditor

  1. Ergänzen weiterer Editoren Weitere Editoren können durch Hinzufügen eines entsprechenden Formelement-Objekts leicht ergänzt werden. Dazu kann die Formelementdatei eines Editors als Vorlage dienen.

Verwendung des in der allgemeinen Konfiguration gesetzten Editors
$form->addElement('textarea')->setName('news_form[news_body]')->setEditor();

Der Aufruf von setEditor() bewirkt den Lookup der Einstellung $config[editor][type] aus der Konfigurationsdatei "clansuite.config.php".

Wysiwyg MarkItUp!
$form->addElement('textarea')->setName('news_form[news_body]')->setEditor('markitup');
Wysiwyg NicEdit
$form->addElement('textarea')->setName('news_form[news_body]')->setEditor('nicedit');
Wysiwyg TinyMCE
$form->addElement('textarea')->setName('news_form[news_body]')->setEditor('tinymce');
Wysiwyg CKEditor
$form->addElement('textarea')->setName('news_form[news_body]')->setEditor('ckeditor');

10.3.31. Sicherungselemente

Security-Token (CSRF)
Timetoken (CSRF)

10.4. Der Formularbuilder

10.4.1. Allgemeines

10.4.2. Verwendung

11. Kapitel 11 - Bibliotheken

12. Kapitel 12 - Die Clansuite Toolbar

In diesem Kapitel erfahren Sie, wie Sie die Clansuite Toolbar installieren, konfigurieren und verwenden. Entwickler erhalten zudem einen Einblick in die Programmierung und die Veröffentlichung der Toolbar.

12.1. Allgemeines

Die "Clansuite Toolbar" ist ein Toolbar-Addon für den Webbrowser Mozilla Firefox. Sie unterstützt die Entwickler und Nutzer mit Links zu den verschiedenen projektrelevanten Ressourcen und nützlichen Suchfunktionen. Unabhängig von der Website, die Sie gerade besuchen, können Sie so jederzeit die Ressourcen des Clansuite Projekts erreichen und zusätzlich in verschiedenen Handbüchern, Foren und Suchmaschinen nachschlagen, denn Sie haben das Sucheingabefeld immer im Blickfeld. Es befindet sich direkt unter der Adresszeile des Browsers. Ein hervorzuhebendes Features der Suche ist, die Mehrfachsuche eines Suchbegriffs auf den jeweiligen Zielseiten. Die Toolbar stellt sowohl Links zur Clansuite Dokumentation, als auch zu den Dokumentationen der Clansuite Libraries (z.B. Smarty und Doctrine) und der Projektwerkzeuge (z.B. Asciidoc und Subversion) bereit. Entwickler schätzen den komfortablen Schnellzugriff auf den lokalen Entwicklungswebserver (phpMyAdmin, Arbeitsverzeichnisse, Statusreport, Error- und Accesslog) und den Bugtracker. Abgerundet wird die Toolbar durch den praktischen "GO TO" Button. Er ermöglicht den Direktaufruf des Frontends, des Backends, des Installers, des Webinstallers und des Converters.

Kurzum: Die Clansuite Toolbar ist eine Hilfe für Jeden, der auf Informationen rund um Clansuite setzt! Sie ist als nützliche Hilfe ein Muß für jeden Entwickler!

Das Bild zeigt die Clansuite Toolbar im Firefox Browser.
Links

http://forum.clansuite.com/index.php/topic,127.0.html Forum Thread zur Clansuite Toolbar

12.2. Systemvoraussetzungen, Installation, Einblenden/Ausblenden, Updates und Deinstallation

Systemvoraussetzungen

Die Toolbar ist betriebssystemunabhängig und erfordert den Webbrowser: Mozilla Firefox Version 3 oder höher.

Tipp Falls Sie Mozilla Firefox nicht installiert haben sollten, können Sie die aktuelle Version auf der Webseite http://www.mozilla.com/de/ finden und herunterladen.
Installation

Die Toolbar ist eine selbstinstallierende Erweiterung für den Webbrowser Firefox. Ihre Installation ist denkbar einfach: sie kann bequem durch Aufruf der XPI Datei installiert werden. Ein Doppelklick genügt also.

Die Clansuite-Toolbar ist unter folgender URL zu beziehen: http://www.clansuite.com/toolbar/.

Einblenden/Ausblenden

Sie können die Toolbar sehr einfach ein- und ausblenden, indem Sie über den Menüpunkt „Ansicht ⇒ Symbolleisten” (Alt+a und y) den Haken neben „Clansuite Toolbar” setzen oder entfernen.

Updates

Nach der Installation aktualisiert sich die Toolbar beim Erscheinen einer neuen Version automatisch. Eine händische Deinstallation mit anschließender Installation der neuen Version ist ebenfalls möglich.

Deinstallation

Sollte Ihnen die Toolbar keine Hilfe sein, dann können Sie sie über die Addon-Verwaltung des Firefox deinstallieren. Dafür navigieren Sie zum Menüpunkt „Extras ⇒ Addons” (Alt+x und a). Auf der Übersichtsseite, welche Ihre installierten Addons zeigt, wählen Sie nun „Clansuite Community Toolbar” aus und klicken auf den Button „Deinstallieren” (Taste d). Die Toolbar wird daraufhin von ihrem System gelöscht und auch aus der Konfiguration des Firefox gelöscht. Damit die neue Konfiguration ohne die Toolbar aktiv wird, müssen sie den Firefox neustarten.

12.3. Übersicht über die Menüpunkte und Funktionen der Toolbar

Die meisten Menüpunkte der Toolbar sind Links. Ein einfacher Klick genügt daher, um die Zielseite anzusteuern.

Das Menu "Clansuite"

Das Bild zeigt das Clansuite-Menü.

Das Menu "Suche"

Das Bild zeigt das Menü der Suche.

Das Menu "Documentation"

Das Bild zeigt das Dokumentations-Menü.

Das Menu "Developer"

Das Bild zeigt das Developer-Menü.

Das Menu "Webserver (httpd)"

Das Bild zeigt das Webserver-Menü.

Das Menu "Bugtracker"

Das Bild zeigt die Links zum Bugtracker.

Das Menu "GoTo"

Das Bild zeigt die GoTo Links.

12.4. Konfiguration der Clansuite Toolbar

Die Toolbar hat einige wenige Konfigurationsmöglichkeiten.

Das Bild zeigt den Konfigurationsdialog für die Elemente der Toolbar und das Verhalten beim Öffnen der Links.
Abbildung 12. Der Konfigurationsdialog Toolbar Elemente

Im Konfigurationsdialog für die Toolbarelemente unterteilt sich in zwei Teildialoge. Erstens können Sie festlegen, welche Elemente in der Toolbar angezeigt werden sollen. Um ein Element anzuzeigen, setzen sie den entsprechenden Haken mittels Linksklick auf die Checkbox.

Zweitens können Sie bestimmen, auf welche Art und Weise die Links geöffnet werden sollen. Wenn Sie "Open in Tab" aktivieren, werden die Links der Toolbar jeweils in einem neuen Tab geöffnet, anstatt im aktuell aktiven Browsertab. Wenn Sie "Open Tab in background" aktivieren, werden die Links der Toolbar jeweils in einem neuen Tab geöffnet, wobei der aktuell aktive Browsertab im Vordergrund bleibt und die Tabs im Hintergrund geladen werden.

Das Bild zeigt den Konfigurationsdialog für die Konfiguration der Pfade für das Webservermenü und die Webserverlogs.
Abbildung 13. Der Konfigurationsdialog Pfade

Mittels des Konfigurationsdialogs für Pfade ist es möglich, die korrekten Pfade zu den Webserverlogs (error.log und access.log) anzugeben. Zugleich ist es möglich ein Webserver "Working Dir", sowie ein "Clansuite Dir" zu setzen, um schnell zwischen den beiden lokalen Arbeitsplätzen zu wechseln. Die entsprechenden Menüpunkte "Working Dir" und "Clansuite Dir" befinden sich im Webserver-Menü "httpd".

12.5. Programmierung der Toolbar

12.6. Verzeichnisstruktur

SVN-Repository

Die Toolbar ist ein eigenständiges Projekt innerhalb des Clansuite SVN-Repositories. Ihr Verzeichnis innerhalb des SVN-Repositories ist svn://svn.gna.org/svn/clansuite/toolbar. Das Verzeichnis ist klassisch unterteilt in "/trunk", "/tags" und "/branches".

Toolbar

Die Verzeichnisstruktur der Toolbar entspricht dem klassischen Layout einer Firefox Erweiterung. Firefox unterscheidet XULRunner Anwendungen, Erweiterungen und Themes. Dabei wird eine Grundstruktur für die Programmbündel vorgegeben
[https://developer.mozilla.org/de/Bundles]
. Das Hauptverzeichnis ist "/chrome". Es wird unterteilt in das Verzeichnis "/content", welches die wesentlichen Dateien der Toolbar enthält, in das Verzeichnis "/locale", welches die Übersetzungsdateien enthält und das Verzeichnis "/skin", welches Images und Icons für die Toolbar beinhaltet. Die Verzeichnisnamen sind zwingend kleinzuschreiben.

Das Bild zeigt die SVN Verzeichnisstruktur der Clansuite Toolbar.

Das Bild zeigt das Hauptverzeichnis der Clansuite Toolbar.

Das Bild zeigt das Verzeichnis /chrome/content der Clansuite Toolbar.

12.7. Das Buildscript der Toolbar

12.8. Die wesentlichen Dateien der Toolbar

Jede Erweiterung benötig eine install.rdf Datei mit beschreibenden Informationen über die Erweiterung wie eine einmalige ID, Version, Urheber oder Kompatibilität. Eine XPI-Datei beinhaltet mindestens die folgenden Dateien: XUL-Datei, Manifest, install.rdf und update.rdf. Diese Dateien werden ergänzt um Javascript (.js) und kasakdierende Stylesheets zur Ausgabeformatierung (.css), sowie Bilddatien, die z.B. als Icons und Buttons angezeigt werden.

12.9. XUL

12.10. Übersetzung der Toolbar

Die Toolbar ist lokalisiert und in zwei Sprachen (deutsch, englisch) verfügbar.

12.11. Checkliste für eine Veröffentlichung der Toolbar

Um eine neue Version der Clansuite Toolbar zu veröffentlichen sind folgende Schritte notwendig:

  1. Ausgangspunkt: Es sind Änderung am Sourcecode vorgenommen worden.

  2. Die Versionnummer in "install.rdf" und "/chrome/content/clansuite_about.xul" (Zeile 40 ff.) erhöhen (Frage: Muss man hier erneut Mccoy über install.rdf laufen lassen?)

  3. Die Toolbar mittels build[.bat|.sh] automatisch builden lassen.

  4. Die entstandene Datei "clansuite-toolbar-v.xpi" in "clansuite-toolbar-v(Versionummer).xpi" umbenennen, dabei die Versionsnummer eintragen.

  5. Den SHA1 Hash der "clansuite-toolbar-v(Versionummer).xpi" ermitteln. Hierfür Tool "Hashtab" verwenden.

  6. Den SHA1 Hash in die Datei "update.xml" eintragen und alle Elemente der alten Version klonen.

  7. Die Datei "update.xml" in "update.rdf" umbenennen.

  8. Das Tool McCoy zum Siginieren der "update.rdf" verwenden.

  9. Die Dateien in das Verzeichnis "/clansuite/toolbar" hochladen: 1) update.rdf, 2) clansuite-toolbar-v(Versionnummer).xpi, 3) updateInfo-v(Versionummer).xhtml

  10. Release-Informationen absetzen: 1) Forumthread updaten (http://forum.clansuite.com/index.php/topic,127.0.html) 2) Google News verfassen

13. Kapitel 13 - Das Deployment

Im folgenden, ersten Abschnitt, geht zunächst um die Notwendigkeit der Dokumentation des Deploymentverfahrens und es werden die Begriffe Deployment und Build erklärt. Sodann wird der Build-Prozesses thematisiert, wobei der Einsatz des Build-Werkzeugs Phing näher beschrieben wird. Danach folgt die Beschreibung des Verteilungsverfahrens, wobei insbesondere das PEAR Paket Management erklärt wird. Das Kapitel schließt mit einer genauen Darstellung von Aufbau und Inhalt der Paketbeschreibungsdatei. Um Entwickler in die Lage zu versetzen, ihre Entwicklungsteilleistungen entsprechenden den Build-Standards zu erstellen. Dazu gehört beispielsweise die ordnungsgemäße Ablieferung eines Moduls unter Beschreibung der Installationsvoraussetzungen und Abhängigkeiten.

13.1. Was ist Deployment und warum ist ihm ein eigenes Kapitel gewidmet?

Beim Deployment geht es darum eine Software (in diesem Fall Clansuite) zu builden, also ein fertiges Produktpaket zusammenstellen und es im Anschluss zu deployen, d.h. es für die Verteilung an Kunden bereitzustellen. Der Deploymentprozess hat also das Primärziel die Marktfreigabe eines Produktes oder einer Entwicklung in einem geordneten und geplanten Verfahren sicherzustellen. Denn die Erstinstallation beim Kunden soll schließlich reibungslos ablaufen. Aber auch nach einer Marktfreigabe sorgt der Deploymentprozess dafür, dass ein Softwareprodukt aktualisiert und beispielsweise mit Sicherheitspatches versorgt werden kann (Sekundärziel). Dieses Verfahren besteht zum Großteil aus wiederkehrenden Tätigkeiten. Daher kann man auf zahlreiche Automatismen zurückgreifen.

In Ein-Mann-Projekten, wie diesem, liegt das Wissen über das Verfahren des Deployments bei einer Person. Eine solche Wissenshortung führt dazu, dass die Verantwortlichkeit in den Händen nur einer Person liegt. Was passiert, wenn diese Person das Projekt verlässt oder nicht erreichbar ist, kann man sich denken. Das Wissen über das Deployment ist fast so wesentlich wie die Erstellung des Programms an sich. Fehlendes Wissen in diesem Bereich kann sich sehr schnell zum Flaschenhals entwickeln, besonders im Zeitraum nach einer Erstinstallation. Daher ist das Deployment transparent und nachvollziehbar darzustellen.

13.2. Das Build-Werkzeug Phing

Phing ist ein Build-Werzeug. Es dient dazu, klar definierte, wiederkehrende Aufgaben und Teilaufgaben beim Zusammenstellen von Softwarepaketen auszuführen. Phing ist in der PHP-Welt, was Apache Ant (Another neat tool)
[http://ant.apache.org/, Webseite von Apache Ant]
in der Java-Welt ist.

Phing verwendet eine XML Datei, die Build-File, um eine Liste mit Kommandos und Eigenschaften zu verwalten. Die Kommandos werden mit dem XML-Tag "target" definiert. Ein Kommando kann dabei ein von Phing mitgebrachter Task sein oder eine selbst-definierbare Schrittfolge.

Der Einsatz von Phing hat mehrere Vorteile. Neue Phing Tasks können in PHP geschrieben werden. Durch den Einsatz einer zentralen Beschreibungsdatei mit Taskdateien wird der Aufwand minimiert eine unüberschaubare Vielzahl an kleinen Shellscripten zu pflegen (Sorry, allen Shell-Ninjas). Ziel ist also, möglichst viel über Phing und möglichst wenig über Shellscripte abzuwickeln. Da Phing inzwischen ein Standardwerkzeug innerhalb der PHP-Community ist, lassen sich viele Anwendungsbeispiele finden.

13.2.1. Task "visualize-buildfile" - Visualiserung der Clansuite Buildfile

Das Kommando "visualize-buildfile" erzeugt eine grafische Darstellung der verfügbaren Kommandos der Clansuite Build File. Die Visualisierung erfordert "dot" und eine XSL-Datei zur Formatierung.

13.4. Die Verteilung mittels PEAR Paket Management

13.4.1. Was ist ein Paket?

Ein Paket ist ein Dateiarchiv mit einer Beschreibungsdatei im PEAR-Format. Es kann ein oder mehrere Clansuite-Kernmodule oder einzelne Module, Themes oder Erweiterungen enthalten. Die Pakete werden über einen Clansuite-PEAR-Kanal vertrieben und sind automatisch installierbar.

14. Kapitel 14 -

15. Dokumentation

Kapitelüberblick

Dieses Kapitel beschreibt die eingesetzten Werkzeuge und das Verfahren zur Erstellung der Clansuite Dokumentation.

15.1. Allgemeines zur Dokumentation

Die Dokumentation ist bekanntermaßen das ungeliebte Kind jedes Entwicklers. Zumeist werden Programme abgeliefert, ohne auch nur eine einzige Zeile Programmcode im Quelltext oder die Benutzung des Programms in Form eines Handbuchs dokumentiert zu haben. Neben der Dokumentation des Quelltextes im Quelltext selbst sollte auch eine beigefügte Dokumentation jede Komponente erklären.

Unabhängig von der Sprache, in der die Dokumentation erstellt wird, sollte immer eine Korrekturlesung stattfinden. Rechtschreibprüfungen helfen dabei, aber um die Grammatik muss man sich selbst kümmern. Schreibfehler und Falschbezeichnungen sind nicht nur unansehnlich. Sie auch können verheerende Folgen haben, insbesondere bei Variablennamen.

Überblick über unsere Dokumentationswerkzeuge
  1. AsciiDoc und po4a

  2. Trac Wiki

  3. phpDocumentor

  4. Doxygen

  5. Selbstdokumentation mittels Reflection

15.2. AsciiDoc und po4a

Allgemeines

Wir verwenden AsciiDoc für die automatisierte Erstellung der Dokumentation aus Textdateien. Das hat zwei Vorzüge: zum einen wird durch Dokumentation mittels einfacher Textdateien gewährleistet, dass die Dokumentation auf jedem System lesbar ist. Zum anderen, dass es problemlos möglich ist, die Dokumentationen in verschiedene Dokumentationsformate, wie z. B. Plain-Text, PDF oder XHTML zu konvertieren. Die Textdateien für AsciiDoc befinden sich im Verzeichnis "/doc/manuals" und haben die Dateiendung ".asc".

Wie funktioniert AsciiDoc?

Der Kern von AsciiDoc ist ein Pythonscript zur Konvertierung von Textdateien in andere Formate. Dabei werden die drei Formate "article", "book", "manpage" von Haus aus unterstützt. Über eine Konfigurationsdatei können weitere Formate wie DocBook XML, XHTML 1.1, HTML 4.01 ausgegeben werden.

Wählt man als Ausgabeformat beispielsweise DocBook XML, so wird AsciiDoc den hauseigenen DocBook Toolchain Wrapper "a2x" verwenden, um in einem ersten Schritt, den unstrukturierten Text in strukturiertes XML umzuwandeln. Hat man dies erreicht, kann in einem weiteren Schritt, die gesamte Vielfalt der Ausgabeformate von DocBook angesprochen werden. Dabei wird das XML zumeist mittels XSLT-Processing (xsltproc) mit einem entsprechenden DocBook XSL Stylesheet versehen und anschließend ausgegeben. Auf diese Weise lassen sich aus den Textdateien auch PostScript oder PDF Dokumente erzeugen. Dieses mehrschrittige Verfahren erschließt letztlich die volle Kraft von DocBook, wobei dessen eigentliche Komplexität vor dem Nutzer versteckt wird. Die Eintrittsbarriere in die Technik der automatischen Erstellung von Dokumentationen wird deutlich herabgesetzt und auf das Wesentliche, den Inhalt, konzentriert.

Übersetzung der Dokumentation

Die Ausgangssprache der Dokumentation ist Deutsch. Die Übersetzung in andere Sprachen erfolgt durch Verwendung von po4a. Das Ziel des po4a (po for anything) Werkzeugs ist, den Einsatzbereich des bekannten Gettext PO Formats und der Gettext Tools auf untypische Einsatzbereiche auszudehnen. Regelmäßig wird Gettext für die Lokalisierung von Software herangezogen, wobei hier eher kürzere Textabschnitt der Nutzerschnittstelle (Beschriftungen, Menüs, Meldungen, Statuszeilentexte) übersetzt werden. Besonders interessant wird der Einsatz des Übersetzungswerkzeugs Gettext im Bereich der Dokumentation von Software aber nicht durch die längeren Textabschnitte einer Dokumentation, denn Gettext ist durchaus in der Lage auch lange Übersetzungstexte zu handhaben, sondern durch die verbesserte Wartbarkeit und Pflege der Übersetzungsdateien. So gibt es zahlreiche Werkzeuge um den Übersetzungsfortschritt statistisch zu erfassen und grafisch darzustellen, sowie die Aktualisierungsnotwendigkeit bzw. Übersetzungsnotwendigkeit anzuzeigen.

Dazu extrahiert PO4A das zu übersetzende Material aus den Text- bzw. XML-Eingangsdaten und legt eine PO-Datei an. (http://www.gnu.org/software/hello/manual/gettext/PO-Files.html) Die Inhalte der PO Dateien können durch Zuhilfenahme von Gettext-Übersetzungseditoren, wie z. B. POEdit, sehr einfach übersetzt werden. Nach der Übersetzung der PO-Datei in die jeweilige Zielsprache wird der Übersetzungsgehalt in die Dokumentenstruktur der Eingangsdaten eingepflegt, wodurch das übersetzte Dokument entsteht. Sollte eine Zeichenkette nicht oder lediglich teilübersetzt sein, weil z. B. das Ausgangsdokument zwischenzeitlich verändert wurde, dann wird die Zeichenkette der Ausgangssprache im übersetzten Dokument verwendet. Dies ermöglicht neu hinzugekommene Passagen in der fremdsprachigen Version des Dokuments schnell und einfach zu erkennen, zu übersetzen und somit die Dokumentation up to date zu halten.

Die automatisch generierte Dokumentation ist immer online zu finden: http://docs.clansuite.com/

Formatierungsregeln

Die Formatierungsregeln für AsciiDoc sind sehr einfach gehalten. Man kann sich die Auszeichnungssprache als eine Art Wiki-Markup vorstellen, welches durch eine Vielzahl von Kommando-"Tags" erweitert wird. Der Fokus liegt eindeutig auf der Erstellung von Text und Inhalt und nicht auf dem Abplagen müssen mit endlosen HTML- und CSS-Tag-Kaskaden oder der Dokumentenbeschreibung im DocBook-Stil. Den offiziellen Leitfaden für die Formatierungsregeln findet man auf Webseite des AsciiDoc Projekts. Den durch die Community erstellten Cheat Sheet (engl. für Spickzettel) findet man hier unter der URL http://powerman.name/doc/asciidoc. Die Formatierungsregeln werden durch bestimmte Filter erweitert.

Die Erweiterung Source-highlight

Der Filter source-highlight verwendet gnu-highlight um in den Text eingebetteten Quellcode farbig hervorzuheben und somit die Lesbarkeit des Quellcodes zu Verbessern. Die den Highlighting-Style dokumentierende Seite von gnu-highlight findet sich unter: http://www.gnu.org/software/src-highlite/style_examples.html

Die Erweiterung graphviz

Der Filter graphviz ermöglicht die Erstellung von Diagrammen auf Basis der Grafikbeschreibungssprache Dot. Man zeichnet also keine Diagramme und schon gar nicht per Hand oder direkt mit einer Software, sondern beschreibt sie abstrakt. Das konkrete Layout übernimmt dann Graphviz bzw. Dot. Eine Assoziation die sich unmittelbar aufdrängt, ist HTML als Beschreibungssprache für Webseiten. Hier wird ebenfalls abstrakt beschrieben, wobei das konkrete Layout vom Layoutverständnis-Browser abhängt.

Webseite des Graphviz Projekts: http://www.graphviz.org

Nachfolgend finden Sie die Webseite des AsciiDoc Projekts: http://www.methods.co.nz/asciidoc/

15.3. Trac Wiki

Eine Dokumentation mittels des Trac Wiki wird derzeit nicht durchgeführt. Im Trac Wiki lassen sich daher hauptsächlich Hinweise zum Eintragen von Wünschen (Feature-Requests) und Fehlern (Bugs) finden.

Das Clansuite Trac Wiki finden sie unter: http://trac.clansuite.com/

15.4. phpDocumentor - PHP Documentation Generator

Die Clansuite API wird durch phpDocumentor automatisch dokumentiert. Dazu parsed phpDocumentor zunächst den Quellcode von Clansuite und analysiert anschließend Quellcode und zugehörige Kommentare. Um den Informationsgehalt der Kommentare zu erhöhen, wird der phpDoc-Kommentarstil eingesetzt. Welche phpDocumentor Blöcke und Tags im Clansuite Quellcode verwendet werden, erfahren Sie im Kapitel über die Programmierkonventionen.

Nachfolgend finden Sie die Webseite und das Handbuch des phpDocumentor Projekts: http://www.phpdoc.org/ http://manual.phpdoc.org/

Die mit phpDocumentor erstellte Clansuite API findet sich unter http://docs.clansuite.com/developer/phpdoc/

Installationshinweise für phpDocumentor über PEAR
1. PEAR Installation mittels        "apt-get install php-pear"
2. phpDocumentor installieren       pear install --alldeps phpDocumentor
3. Einige Anpassungen vornehmen
a) Memory Limit raufsetzen
Bei großen Projekten kann es zum fatalen Fehler "Allowed memory size of ***** bytes exhausted" kommen.
Dieses Problem kann durch Erhöhen des Memory Limits behoben werden.
Dazu passt man am besten die Datei "/usr/share/php/PhpDocumentor/phpDocumentor/Setup.inc.php" an.
Als Suchbegriff in der Datei einfach "memory" verwenden. Die entsprechende Stelle findet sich schnell.
b) Fehler unterdrücken
phpDocumentor verursacht in Abhängigkeit von der PHP Version und im Fehlerreportinglevel E_ALL mehrere PHP Errors.
Dies sind zumeist Notices, aber auch Deprecation Errors. Sollte dies auf Ihrem System der Fall sein, so können Sie
in der Datei "Setup.inc.php" auch gleich nach "error_reporting" suchen und es auf "0" setzen.

15.5. Doxygen

Die Clansuite API wird durch Doxygen automatisch dokumentiert. Genau wie bei alle anderen Dokumentationstools wird auch hier zunächst der Clansuite Quellcode geparsed und anschließend analysiert. Doxygen beherrscht die Kunst, das zugrunde liegende Klassenmodel aus dem Quellcode zu extrahieren und zu visualisieren. Die so entstehende grafische Klassen-Hierarchie erleichtert neuen Entwickern den Einstieg.

Link zur Clansuite API Dokumentation mittels Doxygen: http://docs.clansuite.com/developer/doxygen/

Nachfolgend findes Sie die Webseite des Doxygen Projekts: http://www.stack.nl/~dimitri/doxygen/

15.6. Selbstdokumentation mittels Reflection

Seit PHP5 bietet PHP die Reflection API an. Damit ist es möglich Objekte und Klassen per Introspektion zu untersuchen. Wir verwenden dieses Verfahren um eine API Dokumentation zu erstellen.

include::kapitel16-webserver.asc[

16. Kapitel 17 - Die Clansuite Programmierrichtlinien

Dieses Kapitel stellt den Clansuite Coding Standard, also die jeweils aktuell geltenden Programmierrichtlinien von Clansuite dar. Es ist untergliedert in drei Abschnitte. Im ersten und zweiten Abschnitt werden zwei Richtlinienarten erläutert. Die Richtlinien für die förmliche Gestaltung des Quelltextes und die Regeln für die Programmierung. Der dritte Abschnitt beschäftigt sich mit der automatischen Kontrolle dieser Richtlinien mit dem Werkzeug CodeSniffer.

Regeln und Konventionen sind feste, starre Richtlinien für den Entwurf einer Applikation. Diese Regeln mögen vielen Entwicklern als Gängellei erscheinen. Doch das ist bei Regeln der Normalfall. Sie wurden festgelegt, um Fehler zu vermeiden und hervortreten zu lassen und um eine bestimmte Form und Qualität bei der Entwicklung zu erzielen. Es sind absichtliche (künstliche) Einschränkungen der Software, die dem Entwickler einige Entscheidungen abnehmen und den Entwicklungsprozess effizienter und konsistenter gestalten. Es sind kleine, sich wiederholende Zeremonien.

Die Notwendigkeit von Programmierrichtlinien ergibt sich aus dem Gebot der Quellcodeschönheit ("Code is Poetry") und einer Kostenbetrachtung bei der Softwareentwicklung. Während des Lebenszyklus einer Software wird ein Großteil der Kosten durch die Wartung verursacht. Oft sind in den unterschiedlichen Lebensphasen einer Software nicht die gleichen Programmierer am Werke. Die Wartungskosten entstehen daher oft durch die zusätzliche Einarbeitungszeit in den zu wartenden Quellcode durch neue Programmierer. Um die Wartungskosten, und damit die Gesamtkosten, gering zu halten, ist es erforderlich Quellcode so zu schreiben, dass er einfach nachzuvollziehen und die Einarbeitungszeit gering ist.

Mache den Codingstyle nach, den Du im Clansuite Repository vorfindest. Erfinde den Style nicht neu und halte Dich an die gegebenen Spielregeln. Um auf Fehler automatisch beim Committen ins SVN hingewiesen zu werden, kannst Du einen SVN pre-commit-hook einsetzen. Beim Versuch eine Datei ins SVN zu committen, wird der PHP CodeSniffer zunächst den Stil und die Richtigkeit der PHP-Syntax der Datei kontrollieren. Im Fehlerfall bekommst Du eine ausführliche Meldung, was in einer Datei zu verändern ist, damit sie regelkonform wird.

Für alle offenen Fragen und unbehandelten Themen gilt die analoge Anwendung der PEAR Standards. - http://pear.php.net/manual/en/standards.php - http://www.dagbladet.no/development/phpcodingstandard/

16.1. Richtlinien für die förmliche Gestaltung des Quelltextes

Wenn in diesem Kapitel von richtig und falsch gesprochen wird, dann ist damit nicht die Funktionalität des Quellcodeabschnitts gemeint, sondern seine Form und Darstellung.

16.1.1. PHP Dateianfang und Dateiende

Jede PHP Datei beginnt mit <?php und endet mit ?>. Das bedeutet, dass weder vor dem öffnenden noch nach dem schließenden Tag Leerzeichen stehen. Abgekürzte Tags (engl. short tags) sind verboten ( <? ?> ).

<?php
    /**
     * Quelltext
     */
?>

Viele PHP-Projekte definieren in Ihren Programmierrichtlinien den Verzicht auf das schließende ?> Tag. Zum einen wird angeführt, dass man den schließenden ?> Tag nicht wirklich braucht. Das mag wohl richtig sein, aber schlampig arbeiten ist eben sehr einfach. Zum anderen wird angeführt, dass es zu Problemen kommen kann, wenn nach dem ?> Tag weitere Zeichen, regelmäßig sind es vergessene Leerzeichen, folgen. Diese Meinung kann man gut vertreten, wenn man die Übersicht über die Leerzeichen nach dem eigenen Programm bereits verloren hat und der Verzicht auf den schließenden Tag die einfachste Lösungsmöglichkeit ist.

16.2. Maximale Zeilenlänge

Die maximale Zeilenlänge beträgt 130 Zeichen.

16.2.1. Kommentare

Um den Umfang eines oder mehrerer Kommentare zu bestimmen, kann man beherzt auf die einfache Grundregel 40% Kommentare und 60 % Code zurückgreifen. Beim Kommentieren ist es wichtig, darauf zu achten, dass die Kommentare so einfach wie möglich geschrieben sind. Kommenate sind keine wissenschaftlichen Abhandlungen. Im Prinzip sollte Deine Oma verstehen können, was der Code an dieser Stelle macht. Mit anderen Worten, ist es für einen Nichtprogrammierer möglich, anhand der Kommentare den Ablauf des Programms nachzuvollziehen. Es hat sich aber herausgestellt, dass für ein späteres Wiederverstehen von Codeabschnitten durch Programmierer, Kommentare besonders hilfreich sind, die nicht lediglich das "Wie" oder "Was" kommentieren, denn das beschreibt der Quellcode selbst, sondern die das "Warum eine bestimmte Codezeile existiert" erläutern.

Einzeilige Kommentare werden durch # eingeleitet (Perl-Style), nicht durch "//" oder "/* */".

Einzeilige Kommentare
Richtig:
# Kommentar

Falsch:
// Kommentar

Falsch:
/* Kommentar */

Es ist erlaubt einzeilige Kommentare hinter dem zu kommentieren Quellcode einzusetzen.

Kommentareinsatz nach PHP Anweisung
# Richtig (Kann-Vorschrift):
$counter = '123'; # Der Kommentar erklärt, was, warum gezählt wird.
Mehrzeilige Kommentare

Mehrzeilige Kommentare werden im DocBlock-Style dargestellt. Sie werden in der ersten Kommentarzeilen mit "/**" eröffnet. Die zweite Kommentarzeilen beginnt mit " *" (Leerzeichen dann Sternchen). Dies erfolgt, damit die Sterne "*" untereinander stehen, gefolgt vom ersten Kommentar. Es folgen beliebig viele weitere Kommentarzeilen dieser Art. Die letzte Kommentarzeilen enthält den Kommentarabschluss " */".

Richtig:
/**
 * Ein Kommentar
 * über mehrere Zeilen.
 */

Falsch:
/**
* Ein Kommentar
* über mehrere Zeilen.
*/

Falsch:
/*
Ein Kommentar
über mehrere Zeilen.
*/

Falsch:
// Ein Kommentar
// über mehrere Zeilen.
PHPDocumentor Kommentierungsstil

Immer den PHPDocumentor Kommentierungsstil einsetzen. Die automatische Erstellung von PHPDoc-Tags wird durch IDEs wie Netbeans, Zend Studio, Eclipse PDT unterstützt. Die IDEs werten die PHPDoc Tags aus und bieten CodeHints, CodeCompletion und Popup-Documentation on the fly.
[http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.howto.pkg.html#basics.starting]
Link zum PHPdoc-Tutorial.

PHPDoc Schlüsselwörter (Tags)
  1. Pflichtangaben

    Immer *@license*, *@author* und *@param*, *@returns*, *@vars* definieren. Zusätzlich bei Bedarf *@see* und *@link*.
    Bei der Definition von *@param* ist stets der Typ des Parameters anzugeben. Im Zweifel ist "mixed" als Typ zu verwenden.
    Der Tag *@license* ist immer: [ * @license    GNU/GPL v2 or (at your option) any later version, see "/doc/LICENSE". ]
  2. Verbote

    Keinesfalls *@globals* definieren. Da die Verwendung von globalen Variablen verboten ist, sind sie auch nicht zu dokumentieren.
    Keinesfalls *@access* definieren. Dieser Tag ist veraltet (PHP4) und kann durch einen PHPDOC-Parser automatisch bestimmt werden.
    Keinesfalls *@since* definieren. Um die Versionsgeschichte nachzuvollziehen, können die Logs des Quellcode-Repositories bemüht werden.
    Keinesfalls *@return void" definieren. Es ist überflüssig anzugeben, dass eine Funktion beendet wird, ohne ein Ergebnis zurückzuliefern.
  3. Optionale Schlüsselwörter verwenden:

    • @todo [taskid] Topicname evtl. URL zum Bugtracker

    • @bug [bugid] Topicname

    • @example Angabe von Quellcode der die Verwendung erläutert.

  4. Ein PHPDoc-Block beginnt immer mit einem Satz und endet mit einem Punkt. Alle PHPDoc Tags hingegen verzichten auf den abschließenden Punkt.

Dateien

Der Dateikopf einer PHP-Datei beginnt immer mit dem DocBlock des Projekts.

<?php
   /**
    * Clansuite - just an eSports CMS
    * Jens-André Koch © 2005 - onwards
    * http://www.clansuite.com/
    *
    * This file is part of "Clansuite - just an eSports CMS".
    *
    * LICENSE:
    *
    *    This program is free software; you can redistribute it and/or modify
    *    it under the terms of the GNU General Public License as published by
    *    the Free Software Foundation; either version 2 of the License, or
    *    (at your option) any later version.
    *
    *    This program is distributed in the hope that it will be useful,
    *    but WITHOUT ANY WARRANTY; without even the implied warranty of
    *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    *    GNU General Public License for more details.
    *
    *    You should have received a copy of the GNU General Public License
    *    along with this program; if not, write to the Free Software
    *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    *
    * @license    GNU/GPL v2 or (at your option) any later version, see "/doc/LICENSE".
    * @author     Jens-André Koch <vain@clansuite.com>
    * @copyright  Jens-André Koch (2005 - onwards)
    * @link       http://www.clansuite.com
    *
    * @version    SVN: $Id: kapitel17-codingstyle.asc 5953 2012-01-24 17:54:32Z vain $
    */

# Security Handler
if(defined('IN_CS') === false)
{
    die('Clansuite not loaded. Direct Access forbidden.');
}
Klassen

Klassen und Interfaces beginnen immer mit einem DocBlock nachfolgender Art:

/**
 * Name der Klasse evtl. Kurzbeschreibung. Ein Satz.
 *
 * Ein längerer
 * auch mehrzeiliger
 * Beschreibungstext.
 *
 * @author      Vorname Nachname <email>
 *
 * @category    Clansuite
 * @package     Core
 * @subpackage  ModuleController
 */

Der @license Tag über der Klassendefinition ist regelmäßig entbehrlich, da die Lizenzdefinition bereits im Projektheader erfolgt ist. Möchte ein Klassenautor denoch davon abweichen, so hat er zuerst eine GNU/GPL v2+ kompatible Lizenz zu wählen und kann diese anschließend mit dem @license Tag im DocBlock der Klasse angeben.

Der @category Tag muss immer den Inhalt "Clansuite" haben. Das @package Tag gibt an in welchen Bereich des Systems die Klasse gehört. Wir unterscheiden die Angaben "Core" und "Modules". Das @subpackage Tag wiederholt den Namen der Klasse.

Methoden

Methoden beginnen immer mit einem DocBlock nachfolgender Art. Dieser Dokumentationsblock enthält einen kurzen einführenden Satz der die Methode bezeichnet, gefolgt von einem optionalen Beschreibungstext und einer Beispielsangabe, welche die Verwendung der Methode verdeutlicht. Anzugeben sind immer die Parameter und eventuelle Rückgabewerte. Überflüssig und somit nicht anzugeben ist, dass nichts zurückgegeben wird (@return void). Gleiches gilt auch für Funktionen (dann natürlich ohne die Sichtbarkeitsdefinition). Nicht anzugeben ist der Autor der Methode (@author), dies erfolgt im Klassen Docblock.

/**
 * eineMethode - ist eine PHPDoc-Block Demonstration.
 *
 * Eine längere Beschreibung ist optional.
 *
 * Wünschenswert ist die Angabe eines Beispiels.
 * @example
 *      $this->eineMethode('meinParameterXY');
 *
 * @param <type> $parameter Erläuterung zum Parameter
 * @return <type> Beschreibung
 */
public function eineMethode($parameter)
{
    /**
     * Methode für das PHPDoc Beispiel
     */

    return $parameter;
}
Klassenvariablen

Variablen sind alphabetisch geordnet und vor den Methoden anzugeben. Die Verwendung von "var" zur Definition der Variablen ist untersagt. Die Sichtbarkeit (public, private, protected) der Variablen ist anzugeben. Soweit mehrere Variablen vom gleichen Typ sind, können sie auf einer Zeile gruppiert werden.

class Clansuite_Klassenname())
{
    /**
     * Counters
     *
     * @var int
     */
    private $cnt1, $cnt2;

    /**
     * The name
     *
     * @var string
     */
    public $name;

    # falsch
    var $variable;
}

16.2.2. Einrückungen

Quellcode ist einzurücken. Im Quellcode sind keine Tabulatoren (Tabulatoren-Sprünge) zu verwenden. Sie können bei den meisten Editoren und IDE’s einstellen, dass der Tabulator (Tab-Taste) einer bestimmten Anzahl von Leerzeichen entspricht. Diese Einstellung findet sich unter "Tabulatorgröße in Leerzeichen einstellen" oder "Tabulator zu Leerzeichen" oder "Tab Policy". Verwende in PHP Dateien 4 Leerzeichen, in CSS und JS und YML jeweils 2 Leerzeichen.

16.2.3. Weißraum und Leerzeichen

Weißraum am Zeilenende entfernen.

Der Weißraum an Zeilenenden ist zu entfernen.

Leerzeichen in und nach Anweisungen

Um die Lesbarkeit zu erhöhen, sind innerhalb und nach Anweisungen Leerzeichen zu verwenden.

# richtig
if ( $bedingung === true )
{
    echo 'bedingung ist wahr!';
}

for($i = 0; $i < count($result); $i++)

# falsch
if($bedingung===true){echo'bedingung ist wahr!';}
for($i=0;$i<count($result);$i++)
Commit ins SCM

Entferne Weißraum nur von Zeilen, die du tatsächlich verändert hast. Oder anders formuliert: Deine Änderungen bringen keinen überflüssigen Weißraum mit. Wenn bei einem Commit die Mehrzahl der Änderungen auf "Weißraum" / "Leerzeichen" Entfernung entfällt, dann ist dieser Commit als alleinstehender QA bzw. Coding Style Enforcement Commit durchzuführen. Somit werden eventuell vorhandene, überflüssige Leerzeichen durch Quality Assurance Commits entfernt.

16.2.4. Boolean-Ausdrücke

Boolean-Ausdrücke immer klein schreiben (true, false, null) und nicht groß (nicht TRUE, FALSE) oder mit großem Anfangsbuchstaben (nicht True, False). Keine Zahlenwerte für Booleans verwenden (nicht 0 / 1). Eine Ausnahme gilt im Bereich der Konfigurationsdateien. Hier sind Zahlenwerte für Booleans zulässig. Boolean-Kontrolle mit "===" durchführen, anstelle von "==".

Vergleiche sind immer explizit durchzuführen - implizite Vergleiche sind verboten. .Verbot impliziter Vergleiche

# Falsch:
if ( is_null($var) ) # impliziter true-vergleich
{
    ...
}

# Richtig:
if ( is_null($var) === true ) # expliziter true-vergleich
{
    ...
}

Verwenden Sie is_null() um zu prüfen, ob eine Variable vom Typ "null" ist.

Verwendung von is_null
# Richtig:
if ( is_null($var) === true )
{
    ...
}

# Falsch:
if ( $var == null)
{
    ...
}

16.3. Logische Operatoren

Die Verwendung der logischen Operatoren "&&" und "||", sowie "!" ist verboten.

Die beiden Operatoren "&&" und "||" haben eine höhere Priorität als die logischen Operatoren "and" und "or", obwohl sie logisch-funktional äquivalent sind[footnote: http://www.php.net/manual/de/language.operators.precedence.php]. Viele PHP-Programmierer sehen zumeist nur die funktionale Gleichwertigkeit. Der Grund für die Existenz zweier unterschiedlicher Operatoren für die "Und"- und die "Oder"-Verknüpfung ist jedoch, dass die beiden Operatoren jeweils eine Rangfolge haben. Die zu beachtende Operatoren-Rangfolge wird oft vernachlässigt oder ist oftmals gar nicht bewusst. Bei uneinheitlicher und unachtsamer Verwendung der Operatoren und insbesondere bei gemischter Verwendung, kann dieser Umstand aber zu erheblichen Problemen bei der Auswertung von If-Ausdrücken führen.

Zudem ist die Verwendung von "and" (Und) , "or" (Oder), "xor" (Entweder Oder) schneller!

Der logische Operator "!" (Nicht) prüft auf "nicht true". Er kann oft durch einen Vergleich mit false ersetzt werden. Nach Möglichkeit sind Negativprüfungen (Vergleiche mit false) zu vermeiden und Positivprüfungen (Vergleiche mit true) durchzuführen.

16.3.1. Klammern

Klammern auf einer Zeile

Klammern sind auf einer Zeile darzustellen. Diese Regel gilt solange die maximale Zeilenlänge erreicht ist.

Zu einer Überschreitung der maximalen Zeilenläge kommt es oftmals bei komplexen Bedingungen und mehrdimensionalen Arrays. Hier gelten die folgenden Klammer-Regeln.

If-Anweisung mit mehreren Bedingungen
if ( ($bedingung1 != 1 and $bedingung2 == 2) or
     ($bedingung3 != 3 or $bedingung4 == 4)
    )
{
    Anweisung
}
Mehrdimensionale Arrays
$array = array(
    'element1' => 'wert1',
    'element2' => 'wert2',
    'element3' => 'wert3'
);

16.3.2. Geschweifte Klammern

Die geschweiften Klammern { und } befinden sich jeweils auf einer neuen Zeile. Die öffnende geschweifte Klammer ist unterhalb des ersten Zeichens des PHP-Commands zu platzieren. Die schließende auf gleicher Einrückungshöhe. Das ist der sogenannte Eric Allman-Stil (Autor von sendmail) und das Gegenteil vom Unix- Style!

Die Zeilen mit geschweiften Klammern sind als Quasi-Leerzeilen zu verstehen und sehr wichtig, denn sie erhöhen die Lesbarkeit der Programmstrukturen. Man kann sie auch als Absatz eines Textes verstehen. Daher gilt, jeder Weißraum der durch eine geschweifte Klammer geschaffen wird, ist positiv zu bewerten. Der Unix-Style ist in seiner Form eher auf komprimierte Kurzschreibweise ausgerichtet. Als Entwickler muß man Quellcode nicht ausdrucken und inzwischen (2010!) sind 20+ Zoll Monitore verbreitet.

Das Weglassen von geschweiften Klammern ist verboten. Ein häufig anzutreffendes Beispiel ist das Weglassen von Klammern bei einzeiligen if-Anweisungen.

Weglassen von geschweiften Klammern bei einzeiligen if-Anweisungen
# falsch (syntaktisch natürlich korrekt und lauffähig)
if($bedingung) echo 'Bedingung ist wahr!';

# richtig
if ($bedingung === true)
{
    echo 'Bedingung ist wahr!';
}

16.4. Arrays

Bei numerisch indexierten Arrays ist ein Leerzeichen nach dem Komma einer jeden Wertangabe zu verwenden. Soweit durch die Angabe von zahlreichen Werten die maximale Zeilenlänge erreicht wird, ist ein Zeilenumbruch einzufügen. Eine Angabe in mehreren Zeilen kann nach eigenem Ermessen durchgeführt werden.

Numerisch indexiertes Array
# mit leerzeichen nach komma
$array = array ('wert1', 'wert2', 'wert3');

# auch mehrzeilig, wenn korrekt eingerückt
$array = array (
    'wert1',
    'wert2',
    'wert3'
);

Die gleichen Regeln gelten auch für assoziative Arrays, sowie für mehrdimensionale assoziatives und numerisch indexierte Arrays.

Assoziatives Array
# auch mehrzeilig, wenn korrekt eingerückt
$array = array (
    'element1' => 'wert1',
    'element2' => 'wert2',
    'element3' => 'wert3'
);
Mehrdimensionales assoziatives Array
$array = array (
    'element1' => 'wert1',
    'element2' => 'wert2',
    'subarray' => array (
        'element1' => 'wert1',
        'element2' => 'wert2'
    )
);
Mehrdimensionales numerisch indexiertes Array
$array = array (
    1 => array (
        'element1' => 'wert1',
        'element2' => 'wert2'
    ),
    2 => array (
        'element1' => 'wert1',
        'element2' => 'wert2'
    )
);

16.5. Richtlinien für die Programmierung

Bevor etwas programmiert wird, sollte erstmal ein logischer Vorentwurf erfolgen. Dazu kann man eine Skizze auf einem Blatt anfertigen oder ein Grafik- oder Schreibprogramm verwenden. Insbesondere gibt es CASE-Tools und UML-, sowie ER-Werkzeuge, um Strukturen und Beziehungen besser zu modellieren. Dieses Vorgehen entspricht der Vorentwicklungsphase innerhalb des Drei-Phasen-Prinzips der Softwareentwicklung. Man unterteilt dabei die zu verrichtenden Tätigkeiten in die Phasen Vorentwicklung, Entwicklung, und Nachentwicklung. Siehe dazu auch den Abschnitt zum Entwicklungsprozess im Kapitel 2 Projektorganisation.

16.5.1. Struktur

Es ist stets die Gesamtstruktur und ein bestehender Ablaufplan beachten. Ein neues Teil fügt sich immer in das Ganze. Zerlegen der größeren Aufgabe in kleinere Teile (Teile-Herrsche & Salami-Taktik).

Am Anfang erfolgt immer die Initialisierung von Variablen. So werden Notices vermieden und der schwachen Typisierung von PHP entgegengewirkt.

Der Anfang einer Applikation ist der richtige Ort um Konstanten zu definieren.

Danach kann mit der Deklaration von Funktionen oder Klassen mit Methoden begonnen werden.

Innerhalb von Klassen sind normale Methoden vor magischen Methoden zu deklarieren. Eine Ausnahme bildet der Konstruktor einer Klasse. Er ist die einzige magische Methode, die an den Anfang der Klasse gehört. Eine __toString() Methode kommt regelmäßig an das Ende einer Klasse.

16.5.2. Konvention geht über Konfiguration

Im Ergebnis soll ein konfigurierbarer Teil der Software lauffähig sein, ohne eine Konfiguration vornehmen zu müssen. Nach Möglichkeit sind für alle Konfigurationseinstellungen sinnvolle Standardwerte zu setzen. Nach Möglichkeit ist also mit Fallbacks auf Konfigurationsstandardwerte zu arbeiten.

16.5.3. Klassen

Lose Kopplung

Abhängigkeiten zwischen den Klassen vermeiden. Lose Kopplung der Klassen bevorzugen. Jede Klasse als ein funktional eigenständiges Gebilde betrachten.

Klassennamen und Namespaces

Weil PHP erst ab Version 5.3.0 die Verwendung von Namespaces unterstützt, ist allen Clansuite Klassen der Prefix "Clansuite_" vorangestellt. Namensräume ermöglichen eine neue Art der Kategorienbildung und damit der Ordnung von Klassen. Auf diese Art lassen sich benutzerdefinierte Klassen besser von systemeigenen Klassen unterscheiden und es treten keine Kollisionen auf.

Wir werden zu gegebenen Zeitpunkt Namespaces einsetzen, um die langen Klassennamen zu kürzen.

Interfaces (Schnittstellen)

Die Namen für Interfaces entsprechen denen Klassennamen. Sie enden jedoch immer mit "_Interface". Schnittstellen (interface) und Elternklassen (extends) sind auf der gleichen Zeile anzugeben.

class Clansuite_Kind_Klassenname extends Clansuite_Klassenname implements Clansuite_Klassenname_Interface
{
   # ...
}
Instanzierung einer Klasse

Wenn eine Instanz einer Klasse erzeugt wird und dem Constructor dabei keine Parameter übergeben werden, dann sind die dem Klassennamen nachfolgenden Klammern wegzulassen.

class Clansuite_Klasse
{
   # ...
}

# alt
$klasse = new Clansuite_Klasse();

# neu
$klasse = new Clansuite_Klasse;

16.5.4. Umgang mit SQL bzw. DQL (Doctrine Query Language)

SQL gehört aufgrund der MVC-Schichtentrennng immer in den Bereich des Models. Die SQL Abfragen sind in Methoden zu fassen. Diese SQL-Methoden liefern ein oder ein zusammengefasstes Array (compact) zurück.

16.5.5. Funktionen, Methoden

Klassenmethoden statisch deklarieren

Nach Möglichkeit sind Klassenmethoden als statisch zu deklarieren ("static functions"). Klassenmethoden als statisch zu deklarieren macht diese zugänglich, ohne dass man die Klasse instanzieren muss. Dabei ist zuerst immer die Sichtbarkeit anzugeben. Demnach ist die Benennung "public static function" formrichtig, nicht hingegen "static public function".

public    static method1()  { ... }
private   static method2()  { ... }
protected static method3()  { ... }

Es ist verboten Magische Methoden als statisch zu deklarieren!

Keine statischen magischen Methoden
# falsch
public static __toString())  { ... }
public static __get())  { ... }
Auspacken von Schachteln

Das Ineinanderverschachteln von Funktionen ist unübersichtlich und daher nicht wünschenswert. Ab einer Verschachtelungstiefe von 3 Funktionen mit Parametern, sind die Verschachtelungen aufzulösen.

Verkettungen

Im Bereich der Konkatenation ist sprintf() einzusetzen. Als eine Orientierung, ab wann auf sprintf() zurückzugreifen ist, um einen String zu erzeugen, gilt ein Wert von 3 Verkettungen.

16.5.6. Der goto Operator

Der goto-Operator ist verboten. Er führt häufig zu Spaghetticode, verschlechtert also die Programmqualität.

Der goto-Operator wurde in PHP 5.3 als neue Kontrollstruktur eingeführt. Mit Goto lassen sich bedingte Sprünge oder Schleifen ausdrücken. Der Ursprung des Goto-Operators liegt in der unbedingten Sprunganweisung JMP (jump / Assembler68), die die Kontrolle an einen anderen Punkt im Programm überträgt. Dieser Punkt wird durch eine Sprungmarke (label) definiert.

Goto verstärkt PHPs Ausdrucksmöglichkeiten im Bereich von kleinen Scripten. Für mehr taugt dieses Sprachmittel meiner Meinung nach nicht, da die Nachvollziehbarkeit eines längeren Programmflusses durch die Sprünge erheblich leidet. Es sind immer zusätzliche Sprungmarken (labels) einzuführen.

Zudem gibt es einige Einschränkungen bei der Verwendung. Man kann aus Code-Blöcken zwar herausspringen, aber nicht in sie hinein. Zudem sind Sprünge nur im gleichen OpCode-Array Bereich durchführbar, d.h. nur innerhalb der gleichen Funktion bzw. innerhalb des globalen Bereichs der gleichen Datei.

Beispiele
label-A: echo 'Hello World!';
goto label-A;

Ich möchte an dieser Stelle, an den kurzen und oft zitierten Artikel "Go To Statement Considered Harmful" von Edsger W. Dijkstra erinnern, der bereits im März 1968 erschienen ist. Schon der Einleitungssatz bringt es auf den Punkt: "the quality of programmers is a decreasing function of the density of go to statements in the programs they produce".
[Communications of the ACM, Vol. 11, No. 3, March 1968, pp. 147-148. Copyright © 1968, Association for Computing Machinery, Inc.]

16.5.7. Grundsätzliches zu Variablen und Konstanten in PHP

Namenskonventionen für die Bezeichnung von Konstanten und Variablen

Konstanten und Variablen sind eindeutig zu bezeichnen. Ein Bezeichner ist immer so zu wählen, das in ihm kurz und prägnant zum Ausdruck kommt, welchen Inhalt oder welche Funktion sich dahinter verbirgt. Es sollen logische und unabgekürzte Namen bei gleichbleibender Verwendung sein. Zur Bezeichnung bzw. Identifikation sind Literale (Buchstaben und Buchstabenketten) und Numerale (Zahlen und Zahlenketten) zu verwenden. Zulässig ist dabei eine Kombination von Literalen und Numeralen, sowie der Einsatz des Unterstrichs als Trennzeichen und zur Gruppierung durch einen Prefix. Eine Bezeichnung unter ausschließlicher Verwendung von Numeralen ist ebenso untersagt, wie die Verwendung von "l33tspeak". Konstanten werden in Großbuchstaben geschrieben.

Variablennamen sollen möglichst prägnant sein, denn man soll sofort sehen können was eine Variable macht. Aber vor allem soll man einer Variable ansehen können, wenn sie falsch verwendet wird. Die falsche Variablenverwendung soll im Quelltext deutlich als falsch erkennbar sein. Außerdem soll eine Variable so nah wie möglich an ihrem Verwendungsort definiert werden. Das erleichtert die Suche im Kontext durch Beschränkung auf einen kleinen Umkreis.

Beispiele
/**
 * Der Bezeichner für die Variable besteht aus Literalen und Unterstrichen.
 * Man kann nachvollziehen, was sich hinter dem Namen verbirgt.
 * Er ist grundsätzlich zulässig, allerdings nicht kurz und prägnant gewählt.
 */
$das_haus_in_dem_ich_wohne_hat_die_hausnummer = '20';

# Ok.
$haunummer = '20';

# Auch das  Voranstellen des Variablentyps ist zulässig.
$intHausnummer = '20';
$boolUserIsAuthed = true;

# Unzulässig, da nur Numerale eingesetzt werden.
$558 = array('');

# Zulässige Kombination von Literalen und Numeralen und Unterstrich.
$haus_1 = array( 'hausnummer' => '20', 'straße' => 'sonnenallee', 'stadt' => 'köln');
Datentypen

PHP ist eine schwach typisierte Sprache. Einer Variablen kann man daher verschiedene Datentypen zuweisen. Einige Beispiele: $var = 0; # int $var = false; # bool $var = string; # string Der Datentyp muss daher vom Programmierer unbedingt im Auge behalten werden. Aber auch der Aufgabengehalt einer Variable ist wichtig. Dafür ist eine Kontextbeobachtung notwendig. Es gibt also zwei wichtige Dinge bei einer Variablen: ihr Datentyp und ihre Aufgabe.

Ein typisches Beispiel wäre eine Flag-Variable. Jeder Variable kann man nur Datentyp und Inhalt entnehmen. Die Eigenschaft eine Flag-Variable zu sein, kann man der Variable selbst nicht entnehmen, sie ergibt sich nur im Programmkontext. Der Kontext lässt sich durch einen Kommentar hinter der Initialisierung der Variable angeben. Aber damit ist diese Information nicht an jeder Stelle verfügbar, bei der diese Variable verwendet wird. (Ausnahme: Gute Entwicklungsumgebungen (IDE’s) und Editoren können einmal definierte Variablen und deren Kommentare bei Wiederverwendung anzeigen. Beispielsweise implementiert NetBeans diese Kontextfunktion für Klassen, Methoden und Variablen. Sie ist mittels der Tastenkombination "Steuerung und Leertaste" zu erreichen.)

Zu einer Zeit als helfende IDE’s noch nicht entwickelt waren führte man eine spezielle Methode ein, um den Kontext anzugeben. Um diese Variablen-Kontextbeobachtung zu erleichtern, wurde eine Namenskonvention für Variablen entwickelt, bei der die Art der Variablen in ihrem spezifischen Kontext zu einem Bestandteil des Variablennames wurde. Man nennt diese Namenskonvention "ungarische Notation". Die Konvention geht auf Charles Simonyi, einen ungarischen Programmierer und späteren Chefentwickler bei Mircosoft zurück. Die originale "ungarische Notation", auch "Apps Hungarian" genannt, gibt den Kontext einer Variablen an, nicht den Datentyp.

Speicherfreigabe

Nach Verwendung einer Variablen sollte sie aus Gründen der Ressourcenschonung aus dem Speicher entfernt werden. Ein unset() zu verwenden ist die saubere und manuelle Art der Speicherbereinigung. Bei PHP-Applikationen ist dieser Punkt nicht ganz so wichtig.

Unterstrich am Anfang des Variablennamens

Außer Kraft: Klasseninterne Variablen haben mit einem Unterstrich "_" zu beginnen. Der Unterstich ist meiner Meinung nach sinnlos, da der Sichtbarkeitsbereich der Variablen durch Doc-Werkzeuge automatisch erkannt werden kann. Nachfolgende Regelungen sind ohne den beginnenden Unterstich zu lesen.

CamelCase

Bei Variablennamen ist grundsätzlich CamelCase zu verwenden. Jedoch mit der Ausnahme, dass das erste Variablenwort dabei klein zu schreiben ist. Richtig: $this→_klassenVariable;

Bei der Zuweisung eines Strings an eine Variable sind stets einfache Anführungszeichen zu verwenden.

Doppelte Anführungszeichen sind verboten
#Richtig:
$string = 'text';

#Falsch:
$string = "text";

Das Verbot doppelter Anführungszeichen zieht das Verbot der Variablenausgabe innerhalb von Strings nach sich.

Variablenausgabe innerhalb von Strings
$var = 'Hello';
Falsch:
$string = "$var World!";

Verwenden Sie stattdessen Konkatenation. Setzen Sie also Zeichenketten aus Teilen zusammen.

Konkatenation
Richtig:
$string = $var . ' World!';

Sind mehrere Ersetzungen in einem String erforderlich, so greifen Sie auf sprintf() zurück.

Bei mehreren String-Ersetzungen sprintf() verwenden
$var2 = 'This is';
$string = sprintf('%s %s World!', $var2, $var); # This is Hello World!
Leerzeile vor return Anweisung

Jeder return Anweisung ist eine Leerzeile voranzustellen. Dies hebt einen Rückgabewert nochmals hervor.

# falsch:
$variable = 'Text to return';
return $variable;

# richtig:
$variable = 'Text to return';

return $variable;

16.5.8. Fehlerbehandlung

Fehlerberichterstattungslevel E_STRICT

Damit jedes noch so kleine Warning sofort ins Auge springt.

Fehlerunterdrückung mittels Silencing-Operator (@) ist verboten

Keine Fehlerunterdrückung mittels @-Operator bei Funktionsaufrufen verwenden! Erstens ist es eine teure Operation, denn die Fehlerbehandlung wird zunächst abgestellt und nach Ausführung des Kommandos wieder eingeschaltet. Zweitens entstehen dadurch nur unnötige Schwierigkeiten beim Debugging, die man vermeiden kann. Wenn es nicht anders geht und Fehlerunterdrückung zum Einsatz kommt, ist immer detailliert zu Kommentieren.

16.5.9. Einsatz von PHP Kommandos

Für die Prüfung, ob eine Datei existiert, ist anstatt file_exists() immer is_file() zu bevorzugen.

Um eine Datei einzubinden bzw. zu laden ist immer die PHP Funktion require anstatt require_once zu verwenden. Dabei ist immer der absolute Pfad zu verwenden und auf Klammern zu verzichten.

Zur Klammerverwendung bei require, require_once, include und include_once wird oft Eingewand, Die Befehle können auch ohne Klammern geschrieben werden, dies aber bitte vermeiden. Das unterstreicht den aktiven Charakter dieser Anweisungen (den Seiteneffekt der _once()-Variante).

16.5.10. Keine Globals

Keine Globals verwenden! Verboten: "global", "$GLOBALS".

16.5.11. PHP und HTML (Templates) auseinander halten

Trennungsprinzip beachten: Kein HTML im PHP. Kein ECHO in Modulfunktionen verwenden (MVC-Durchbrechung), denn die Ausgabe erfolgt regelmäßig automatisch. Das Trennungsprinzip darf nur im Bereich Fehler- und Ausnahmebehandlung durchbrochen werden.

16.5.12. Ternärer Operator

Das Grundanliegen des ternären Operators ist, eine einfache if-else-Anweisung platzsparend auszudrücken. Das Konstrukt ist zweifellos sehr platzsparend. Manche Entwickler sehen aufgrund der Verkürzung der if-else-Schleife auch eine verbesserte Lesbarkeit. Andere sehen darin eher eine Verschlechterung, wobei neben das Lesbarkeitsproblem ein Verständlichkeitsproblem tritt. So beispielsweise bei Verwendung von mehreren Bedingungen mit unterschiedlichen Boolean-Operatoren, sowie bei einer Einbettung des ternären Operators in eine andere Anweisung.

Unter dem Namen "issetOr"-Operator wurde die Einführung der Kurzsyntax (?:) des ternären Operators diskutiert. Es stellte sich heraus, dass einer der Hauptanwendungsbereiche des ternären Operators im Bereich der Variablen-Initialisierung von Request-Parametern liegt.

# Normalsyntax des ternären Operators
$id = isset($_GET['id']) ? $_GET['id'] : 0;

# Kurzsyntax des ternären Operators, der sogenannte "issetOr"-Operator (?:)
$id = $_GET['id'] ?: 0;

# Eingebettete Nutzung
echo 'Es ($i == 1 ? 'ist' : 'sind') '.$i.' Nutzer angemeldet.';

# Verschachtelter ternärer Opearator.
$value = ( $a == $b )
            ? 'true value # 1'
            : ( $a == $c )
                ? 'true value # 2'
                : 'false value';

# Etwas klarer, aber immernoch ungenügend, ist die Darstellung bei Anordnung
# der Bedingung und des Ergebnisses auf der gleichen Zeile.
$result = (condition == A) ? resultA :
          (condition == B) ? resultB :
          (condition == C) ? resultC :
          (condition == D) ? resultD :
                             fail_result;

Der ternäre Operator ist verboten.

Statt des ternären Operators ist immer eine if-else-Anweisung zu verwenden.

16.5.13. Anführungszeichen

Einfache Anführungszeichen anstatt doppelte Anführungszeichen verwenden!

16.5.14. Datei- und Verzeichnisnamen

Für Dateien und Verzeichnisse sind nur alphanumerische Zeichen, sowie der Unterstrich (engl. underscore) "_" und der Trennstrich "-" (engl. dash) erlaubt. Leerzeichen sind verboten. Zusätzlich gilt für Datei- und Verzeichnisnamen die Kleinschreibung.

16.6. Clansuite CodeSniffer Standard

CodeSniffer ist ein PEAR Paket. Es überprüft den Quelltext auf die Verletzung vorher definierter Programmierrichtlinien. Jeder Programmierer ist zwar gehalten, den Richtlinien zu folgen, aber im Eifer des Gefechts werden starre Regeln manchmal über Bord geworfen, um zu schnellen Ergebnissen zu gelangen. Unter dieser Verletzung der Richtlinien leidet jedoch die Qualität des Quellcodes.

Die in den vorherigen Abschnitten befindlichen Programmierrichtlinien wurden daher in einem CodeSniffer Regelsatz zusammengefasst. Mit Hilfe dieses Regelsatzes ist es CodeSniffer möglich, den Quellcode automatisch auf Fehler zu prüfen und diese anzuzeigen. Durch Verwendung von CodeSniffer lässt sich also die hohe Qualität des Clansuite Quellcodes sichern.

Der "Clansuite CodeSniffer Standard" befindet sich im SVN unter "/build-tools/CodeSniffer". CodeSniffer liefert bereits einige Regelsätze bekannter Projekte wie Zend, Squiz und PEAR mit. Jeder Regelsatz besteht aus einzelnen Regeln, den sogenannten Sniffs. So gibt es zum Beispiel einen Regelsatz "LineLengthSniff.php", der die maximale Zeilenlänge einer PHP-Datei auf 130 Zeichen festlegt. Soweit die Konventionen anderer Projekte mit denen des Clansuite Projekts übereinstimmen, wurde auf einige dieser "Standard Sniffs" zurückgegriffen, um den Clansuite Standard zu realisieren. Wir definieren jedoch zahlreiche eigene "Sniffs", da die Clansuite Programmierrichtlinien teilweise erheblich von denen anderer Projekte abweichen.

16.6.1. Installation des Clansuite CodeSniffer Standards

Die Installation des "Clansuite CodeSniffer Standards" kann auf zwei Wegen erfolgen.

Einmal ist der "Clansuite CodeSniffer Standard" als PEAR Paket erhältlich. Er ergänzt also lediglich die bestehende PEAR CodeSniffer Installation um den Clansuite Regelsatz.

Falls man keinen Zugriff auf "pear" hat, kann man alternativ auch das Archiv herunterladen, auspacken und in das PEAR Verzeichnis kopieren. Der richtige Ort innerhalb des PEAR Verzeichnisses ist: [PEAR]/PHP/CodeSniffer/Standards.

16.6.2. Verwendung von CodeSniffer

Wir setzen CodeSniffer auf zwei Arten ein:

Ständiges Quellcode-Monitoring

Der Quelltext im "/trunk" wird ständig durch CodeSniffer auf Verletzungen der Richtlinien untersucht. Die Überprüfung erfolgt mittels einer Phing Aufgabe ("codesniffer-report" und "codesniffer-report-w32"). Diese CodeSniffer-Aufgabe wird regelmäßig aufgerufen. Der Aufruf erfolgt einerseits ausgelöst durch einen Cronjob auf dem Clansuite-Entwicklungsserver, andererseits auch im Rahmen des kontinuierlichen Integrationsprozesses durch Bitten (Trac). Alle Fehler werden in einem Fehlerbericht zusammengefasst und automatisch im Entwicklerbereich der Webseite veröffentlicht. Jeder Entwickler kann so Verstöße erkennen und Fehler beheben.

Sie finden den CodeSniffer Fehlerbericht unter http://docs.clansuite.com/developer/reports/codesniffer.html

Quellcode-Kontrolle vor dem Commit

Damit fehlerhafter Quellcode aber gar nicht erst unter Versionskontrolle gestellt wird, kann und sollte man ihn vor einem Commit überprüfen. Die Überprüfung kann auf zwei Arten geschehen.

Einmal durch manuelles Aufrufen des CodeSniffers: "phpcs --standard=Clansuite zu-prüfende-datei.php". Dadurch wird die einzelne Datei gegen den Clansuite Standard geprüft.

HINT: Man kann die Angabe des "--standards" auch weglassen, wenn man in den CodeSniffer Einstellungen die Verwendung des "Clansuite Standards" als Grundeinstellung setzt. Der Befehl dafür ist "phpcs --config-set default_standard Clansuite".

Alternativ kann der Aufruf des CodeSniffers auch automatisch erfolgen, wenn man ihn in die Versionsverwaltung einbindet. Diese Einbindung lässt sich sehr einfach mit einem Subversion "Pre-Commit-Hook" zum Aufruf von "phpcs" umsetzen. Der "Pre-Commit-Hook", so ja auch schon sein Name, wird vor einem Commit ins Repository automatisch ausgeführt. Sollten zu diesem Zeitpunkt Fehler im Quelltext enthalten sein, wird der Commit abgebrochen. Man kann zum Code zurückkehren, die gemeldeten Fehler beheben und dann ein weiteres Mal versuchen zu committen. Werden keine Fehler gefunden erfolgt der Commit ins Quellcodearchiv.

16.7. Standards für CMS und Frameworks

16.7.1. PHP-Standard für Frameworks

Derzeit wird in der Google Group "PHP-Standards" über eine Vereinheitlichung der Programmierrichtlinien für PHP-Frameworks diskutiert. Es sind Vertreter der folgenden Systeme sind an der Diskussion beteiligt: Cake, Seagull, Symfony, Prado, Zend Framework und Joomla, Mambo sowie Magento. Die Diskussion soll dazu führen, dass Module und Komponenten zwischen den verschiedenen Systemen austauschbar und wiederverwendbar werden. Ein aktueller Entwurf des zukünftigen Standards ist in der Google-Group abrufbar.

17. Subversion (SVN) - Sourcecode-Versionsverwaltung

17.1. Wie kann man mit mehreren Entwicklern effizient SourceCode gleichzeitig bearbeiten?

Dazu stellt man eine zentrale Verwaltung aller Quelltext-Dateien zur Verfügung. Dabei ist der Zugriff steuerbar, beispielsweise Lesen für jedermann und Schreiben nur für Entwickler.

Man hält zu jeder Datei, nicht nur die zuletzt gespeicherte Version vor, sondern auch alle früheren. Demnach lassen sich Änderungen an der Datei sehr einfach verfolgen, denn jede Übermittlung einer Dateiänderung erzeugt eine neue Version.

Bei paralleler Bearbeitung und anschließender Speicherung kommt es zu einem Versionskonflikt. Dieser kann durch Zusammenführung der beiden Dateiinhalte ausgeglichen werden.

17.2. Wie ist das Subversion Archiv aufgebaut?

Das Versionsverwaltungsarchiv auf dem Server wird auch "repository" genannt. Die Arbeitskopie auf dem eigenen Rechner nennt man "working copy".

Es hat sich als zweckmäßig erwiesen folgende Struktur zu verwenden:

/branches    Ein Ast der Entwicklung : ermöglicht Weiterentwicklung in einem extra Bereich, bei Erfolg wird "branch" in "trunk" eingefügt
/tags        Ablagebereich für benannte Versionen, z. B. Produkt X Version alpha
/trunk       Der Stamm der Entwicklung : Hauptentwicklungsbereich

Benennung der Versionen:

"revision"   gibt das Archiv mit der jeweiligen Version wieder, zB rev 1 = erste Version
"head"       gibt das Archiv in der aktuellsten Version (meint regelmäßig die letzte Änderung am /trunk)

17.3. Der Arbeitsablauf mit Subversion

Wie läuft das nun genau ab? Es lassen sich 3 Arbeitsschritte benennen. Das Holen, das Aktualisieren und das Hochladen.

Das Holen - Checkout

Zunächst werden alle Daten vom Server geholt. Diesen Vorgang bezeichnet man als "checkout". Es ist der Erstbezug des Quellcodes. Dadurch wird eine lokale Arbeitskopie erzeugt.

Das Aktualisieren - Update

Neuerungen auf dem Server kann man mittels "update" in die lokale Arbeitskopie einpflegen. So hält man die "working copy" auf dem neuesten Stand. Sollte eine lokale Datei jedoch verändert worden sein, wird ein Zusammenführen der alten (lokalen) und neuen (server-repos) ermöglicht. Diesen Vorgang nennt man "mergen", im Sinne einer Versionsverbindung.

Das Hochladen - Commit

Mittels "commit" werden die lokal durchgeführten Veränderungen an das zentrale Repository übertragen und erzeugen dort eine neue Revisionsnummer (den Head, die aktuellste verfügbare Version), wenn die Serverdateien nicht zwischenzeitlich selbst geändert worden sind. Falls zwischenzeitlich eine Veränderung des Archivs durch einen anderen Entwickler erfolgt ist, wird ein Zusammenführen (das sogennte "mergen") der eigenen lokalen Datei und der Serverdatei ermöglicht. Hiernach stehen alle Änderungen allen anderen Entwicklern zur Verfügung.

17.4. Der Zugriff auf das Clansuite Subversion Archiv

Das Clansuite Subersion Repository liegt auf dem Server von "http://gna.org".

17.4.1. Welche Zugriffsmöglichkeiten gibt es?

Es gibt 2 Zugriffsarten auf das SVN: (A) öffentlich (anonym) und (B) privat (registriert).

Der "öffentliche" Zugriff steht jedem zur Verfügung.

Der "private" Zugriff erfordert die Erstellung eines Nutzerkontos bei GNA. Dazu ist die Hinterlegung des SSH-Keys auf dem Gna-Server und die Aktivierung der verschlüsselten Verbindung auf dem lokalen Rechner erforderlich.

Dabei kann die Generierung des Keys für die Verschlüsselung über "puttygen" erfolgen. Die lokale Aktivierung des Verbindungstunnel kann mittels "Pageant" durchgeführt werden. Beide Anwendungen sind Bestandteil des Programmpakets "putty".

17.4.2. Mit welchem Werkzeug kann ich das am besten machen?

Für beide bietet sich als SVN Verwaltungsprogramm "TortoiseSVN" an. Du kannst es über diesen Link downloaden: http://tortoisesvn.net/downloads (Tortoise SVN Downloads).

17.5. (A) Der öffentliche Zugriff ( für Nicht-Mitglieder des Projekts )

Der öffentliche SVN Zugriff steht jedermann zur Verfügung. Die Verbindungs-Urls für das Clansuite SVN lautet:

http://svn.gna.org/svn/clansuite/trunk

Du kannst sie direkt in Tortoise Checkout einfügen, ein Zielverzeichnis angeben und es erfolgt ein Checkout (das Holen der Dateien, siebe oben) des Trunk (aktuellste Version, siehe oben). Oder als Konsolenbefehl für SVN:

svn co http://svn.gna.org/svn/clansuite/trunk clansuite

17.6. (B) Privater Zugriff (für Clansuite Projekt Mitglieder)

Der "private" Zugriff erfordert (1) die Erstellung eines Nutzerkontos bei GNA, (2) die Hinterlegung des SSH-Keys auf dem Gna-Server und die Aktivierung der verschlüsselten Verbindung auf dem lokalen Rechner. Dabei erfolgt die Generierung des Keys über "puttygen". Die lokale Aktivierung mittels "Pageant". Beide Anwendungen kommen mit "putty".

Schritt 1: Bei Gna.org registrieren

Wenn Sie mitmachen und Quellcode beisteuern möchten, dann legen Sie sich zunächst ein Benutzerkonto bei GNA an. Die Seite mit der Benutzerkontoanzeige können Sie im Browser geöffnet lassen, wir brauchen sie gleich nochmal.

Schritt 2: Für sichere Verbindung zum GNA Server sorgen

Jetzt ist es an der Zeit sich um eine sichere Verbindung von Ihrem Rechner zum GNA Server zu kümmern. Das erfolgt in drei kleineren Schritten: (1) Als ersten erstellen Sie einen öffentlichen SSH-Schlüssel, zu dem nur Sie das Passwort kennen. (2) Diesen hinterlegen Sie dann auf dem GNA Server. (3) Danach aktivieren Sie diesen Schlüssel lokal und geben das Passwort ein.

17.6.1. Den Öffentlichen Schlüssel erstellen

Einen öffentlichen Schlüssel kann man mit dem Programm "puttygen" erstellen. "Puttygen" wird mit "Putty" installiert und liegt dann im Installationspfad von "Putty".

Wenn Du "puttygen" gestartet hast, gehst Du auf "Generate Key".(Parameterhinweis: SSH2-RSA 1024) Zu diesem Schlüssel gibst Du nun Dein Passwort (Keyphrase) ein. Um Tippfehler auszuschließen gibst Du es nochmals ein.

Jetzt hast Du einen SSH-Schlüssel mit Passwort. Du speicherst sowohl "Private" als auch "Public" Schlüssel ab.

17.6.2. Den öffentlichen Schlüssel bei GNA hinterlegen

Um den Schlüssel bei GNA zu hinterlegen kopierst Du den kompletten Inhalt (vom ersten bis zum letzten Zeichen) der Schlüsselanzeige (das oberste Formularfeld) aus "Puttygen" in die Zwischenablage.

Das Browserfenster mit der Benutzerkontoanzeige bei GNA ist noch geöffnet und Du gehst auf SSH-Keys hinzufügen. Alternativ kannst Du diesen Link verwenden: https://gna.org/my/admin/editsshkeys.php , wenn Du noch angmeldet bist.

Rest erklärt sich von selbst: den Inhalt der Zwischenablage in ein Schlüssel-Inputfeld einfügen. Saven und fertig: Schlüssel ist bei GNA hinterlegt. (Beispiel: ssh-rsa AAAAblalba123blabla==)

(Zusatzinformation: Damit dieser Schlüssel für das SVN auf dem GNA Server aktiv wird, muss erst die Rechtetabelle aktualisiert werden. Der Eintrag mittels CronJob dauert zwischen 30 und 60 Minuten. Also später nicht wundern, dass man nicht sofort gesichert zugreifen kann.)

17.6.3. Den öffentlichen Schlüssel lokal aktivieren

Um den Schlüssel nun für jeden Kommunikationsvorgang mit dem GNA Server zur Hand zu haben, startest Du das Programm "Pageant" (im "Putty" Verzeichnis) und lädst den abgespeicherten Public Private Key (öffentlicher privater Schlüssel). Die Dateiendung ist PPK. Alternativ kannst Du den Key doppelklicken, wenn Pageant mit der PPK Endung verknüpft ist, sollte es starten.

Es öffnet sich ein Fenster zur Eingabe Deines Passworts.

Nach erfolgreicher Eingabe taucht in der Taskleiste neben der Uhr ein Symbol "PC mit Hut" auf. Du kannst hier per "rechts-klick" und "View Keys" prüfen, ob der Key auch geladen wurde.

Wenn dieses Symbol angezeigt wird und der Key hinterlegt ist, kann Dein Rechner über eine SSH-Verbindung gesichert mit dem GNA Server kommunizieren.

17.7. Wie ist die Checkout-URL für Projektmitglieder?

Checkouts der Projektmitglieder müssen mitteks einer bestimmten Checkout-URL erfolgen. Dieses URL-Format ist notwendig, damit später Commits den jeweiligen Usern zugeordnet und die SSH Keys abgeglichen werden können.

In den nachfolgenden URLs ist <membername> durch den GNA Nickname zu ersetzen! Die URLs können direkt per Copy/Paste in Tortoise SVN eingefügt werden.

Checkout-URL des Trunk
svn+ssh://<membername>@svn.gna.org/svn/clansuite/trunk
Checkout des Trunk in das Verzeichnis /clansuite per Konsole:
svn co svn+ssh://<membername>@svn.gna.org/svn/clansuite/trunk clansuite

17.8. Wie bekomme ich das gesamte Repository?

Um das gesamte Archiv zu beziehen, kann die folgenden Checkout URL eingesetzt werden.

svn+ssh://<membername>@svn.gna.org/svn/clansuite/
Achtung Die Verwendung dieser URL bewirkt das Holen aller Branches, Tags und des zusätzlichen Entwicklermaterials und kann recht platzgreifend sein! Bei Revision #2350 waren rund 280 MB Festplattenplatz erforderlich. Diese Größe kommt insbesondere durch das SVN Dateisysten zustande, welches sehr viele kleine Dateien beinhaltet.

17.9. Wie bekomme ich nur einen Teil des Repositories?

Wenn Du die nachfolgende Checkout URL verwendest, bekommst Du alle Dateien unterhalb des angegebenen Unterverzeichnisses.

svn+ssh://<membername>@svn.gna.org/svn/clansuite/ + unterverzeichnis

Ein konkretes Beispiel. Wenn Sie nur an Themes arbeiten, können Sie die folgende URL verwenden:

svn+ssh://<membername>@svn.gna.org/svn/clansuite/trunk/themes

17.10. Privater Zugriff auf das SVN unter Linux

Anmerkung
Privater Zugriff auf das SVN unter Linux
  1. Schlüssel erstellen ssh-keygen -t dsa -b 1024 -C <comment>

  2. Wo finde ich den Schlüssel? Der Schlüssel wird im Verzeichnis des Benutzers abgelegt: ~/.ssh/id_dsa.pub.

  3. Den Schlüssel aus "id_dsa.pub" bei gna.org eintragen Danach kann man eine gute Stunde abwarten, bis der GNA-Cronjob den neuen Schlüssel aufgenommen hat. https://gna.org/my/admin/editsshkeys.php

  4. SSH Verbindung prüfen (Connection Check) ssh -v <membername>@svn.gna.org Hier müsste eine Fehlermeldung kommen, denn die Anmeldung an der Console ist nicht gestattet.

  5. SVN-Checkout svn co svn+ssh://<membername>@svn.gna.org/svn/clansuite/trunk

17.11. Installation von Subversion

17.11.1. Subversion Binary Packages

Für die Installation von Subversion stehen verschiedene Binary Packages zur Auswahl
[http://subversion.apache.org/packages.html]
.

Linux (Debian)

 apt-get install subversion

Windows

18. Anhang A - Lizenztexte der Dokumentation

Zumeist werden die Lizenztexte der GNU/GPL v2+ oder GNU FDL nur in englischer Sprache einer Software beigefügt. Dies ist vornehmlich auf den Umstand zurückzuführen, dass es bedauerlicherweise keine offizielle deutsche Sprachversion der GPL gibt. Ich bin allerdings der Auffassung, dass bei einer Software, die in Deutschland vertrieben wird, jedoch auch eine deutsche Übersetzung dabei sein sollte, da die Vertragssprache in Deutschland im allgemeinen "Deutsch" ist. Dem Anhang wurde daher eine inoffizelle deutsche Übersetzung der GNU FDL 1.3 und die offizielle Übersetzung der CC-BY-SA 3 beigefügt.

18.0.1. Clansuite Documentation License(s)

Copyright (c)  2005-onwards  Jens-André Koch.
The "Clansuite Documentation" consists of the
  1. Clansuite Quick-Guide

  2. Clansuite User-Manual

  3. Clansuite Developer’s Manual

    and is dual-licensed under
    1. GNU Free Documentation License - Version 1.3

        Permission is granted to copy, distribute and/or modify the Clansuite Documentation
      under the terms of the GNU Free Documentation License, Version 1.3
      or any later version published by the Free Software Foundation;
      with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
         A copy of the license is included in the Clansuite Documentation in the section entitled "GNU
      Free Documentation License". A copy of the license can be obtained from the file
      "/doc/documentation-license-gnufdl.txt". The most recent copy can be obtained from
      "http://www.gnu.org/copyleft/fdl.html".
    2. Creative Commons License: Attribution-Share Alike 3.0 Unported (CC-BY-SA-3.0)

         You are free (a) to copy, distribute, display, and perform the work and
      (b) to make derivative works. Under the following conditions (a) you must give
      the original author credit (Attribution) and (b) if you alter, transform, or build
      upon this work, you may distribute the resulting work only under the same,
      similar or a compatible license (Share Alike).
         A copy of the license is included in the Clansuite Documentation in the section
      entitled "Creative Commons License (cc-BY-SA-3.0)". A copy of the license can be
      obtained from the file "/doc/documentation-license-ccbysa.txt". The most recent copy can be
      obtained from "http://creativecommons.org/licenses/by-sa/3.0/legalcode".
GNU-Lizenz für freie Dokumentation

Version 1.3, 3 November 2008

Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.

Jedem ist es gestattet dieses Lizenzdokument zu kopieren und unveränderte Kopien zu verteilen, aber seine Änderung wird nicht erlaubt.

Der Zweck dieser Lizenz ist es, ein Handbuch, Fachbuch, oder ein anderes sachliches sowie nützliches Dokument „frei“ im Sinne von Freiheit anzufertigen: um jedermann die wirkliche Freiheit zuzusichern, es zu kopieren und neu zu verteilen, mit oder ohne Modifikation daran, entweder kommerziell oder nicht kommerziell. Zweitrangig erhält diese Lizenz für den Autor und Herausgeber die Möglichkeit aufrecht, Anerkennung für ihr Werk zu bekommen, während Sie nicht als verantwortlich betrachtet werden für vorgenommene Modifikationen anderer.

Diese Lizenz ist eine Art „Copyleft“, was bedeutet, dass abgeleitete Werke des Dokuments ihrerseits im selben Sinne frei sein müssen. Sie ergänzt die GNU General Public License, welche eine Copyleft-Lizenz darstellt, die für freie Software vorgesehen ist.

Wir haben diese Lizenz zur Verwendung für Handbücher von freier Software konzipiert, da freie Software freie Dokumentation benötigt: Ein freies Programm sollte mit Handbüchern erhältlich sein, welche dieselben Freiheiten zur Verfügung stellen wie es die Software tut. Doch diese Lizenz ist nicht auf Software-Handbücher beschränkt; sie kann für jedes textliche Werk verwendet werden, unabhängig vom Thema oder ob es als ein gedrucktes Buch veröffentlicht wird. Wir empfehlen diese Lizenz vorwiegend für Werke, deren Einsatzzweck Anleitung oder Referenz ist.

Diese Lizenz trifft auf jedes Handbuch oder sonstiges Werk zu, in beliebiger Form, das einen vom Urheberrechtsinhaber untergebrachten Hinweis mit den Worten enthält, dass es unter den Bestimmungen dieser Lizenz verteilt werden kann. Solch ein Hinweis gewährt eine weltweite, vergütungsfreie Lizenz von unbefristeter Dauer, um dieses Werk unter den hier festgelegten Bedingungen zu verwenden. Das „Dokument“, nachstehend, bezieht sich auf jedes derartige Handbuch oder Werk. Jedes Mitglied der Öffentlichkeit ist ein Lizenznehmer und wird als „Sie“ angesprochen. Sie akzeptieren die Lizenz, wenn Sie die Werke kopieren, modifizieren oder verteilen, was gewissermaßen unter dem Urheberrechtsgesetz die Erlaubnis erfordert.

Eine „modifizierte Version“ des Dokumentes bedeutet, dass jedes Werk das Dokument selbst oder einen Teil davon beinhaltet, entweder unverändert kopiert, oder mit Modifikationen und/oder übersetzt in eine andere Sprache.

Ein „untergeordneter Abschnitt“ ist ein benannter Anhang oder ein Titelei-Abschnitt des Dokuments, der sich ausschließlich mit dem Verhältnis der Herausgeber oder Autoren des Dokuments zum Gesamtthema des Dokuments befasst (oder damit in Verbindung stehende Bewandtnisse), und nichts beinhaltet was direkt innerhalb des Gesamtthemas fallen könnte. (Wenn das Dokument zu einem Fachbuch über Mathematik gehört, kann ein untergeordneter Abschnitt folglich nichts Mathematisches erläutern.) Die Beziehung könnte ein Anliegen mit historischer Verbindung zum Thema oder ähnlicher Angelegenheiten, oder bezüglich ihrer rechtlichen, kommerziellen, philosophischen, ethischen oder politischen Position sein.

Die „unveränderlichen Abschnitte“ sind bestimmte untergeordnete Abschnitte, deren Titel zum Beispiel in dem Hinweis, der besagt, dass das Dokument unter dieser Lizenz freigegeben ist, als jene unveränderlichen Abschnitte gekennzeichnet sind. Wenn ein Abschnitt nicht zur obigen Definition von untergeordnet passt, dann ist es nicht erlaubt ihn als unveränderlich zu kennzeichnen. Das Dokument kann null unveränderliche Abschnitte enthalten. Wenn das Dokument keine unveränderlichen Abschnitte kennzeichnet, dann gibt es keine.

Die „Umschlagtexte“ sind bestimmte kurze Textpassagen die als vordere Umschlagtexte oder hintere Umschlagtexte in dem Hinweis, der besagt, dass das Dokument unter dieser Lizenz freigegeben ist, verzeichnet sind. Ein vorderer Umschlagtext darf höchstens 5 Wörter lang sein, und ein hinterer Umschlagtext darf höchstens 25 Wörter lang sein.

Eine „transparente“ Kopie des Dokumentes bedeutet eine maschinenlesbare Kopie, in einem ansehnlichen Format, dessen Spezifikation für die Allgemeinheit verfügbar ist, welches geeignet ist das Dokument unkompliziert mit allgemeinen Texteditoren oder (für aus Pixeln bestehende Bilder) allgemeinen Malprogrammen oder (für Zeichnungen) irgendeinem weit verbreiteten Zeicheneditor zu überarbeiten, und das geeignet ist zur Eingabe in Textformatierer oder zur automatischen Übersetzung in eine Variante von geeigneten Formaten zur Eingabe in Textformatierer. Eine Kopie, erstellt in einem ansonsten transparenten Dateiformat, dessen Auszeichnung oder fehlende Auszeichnung derart ausgestaltet wurde, um nachträgliche Modifikation durch Leser zu behindern oder zu verhindern, ist nicht transparent. Ein Bildformat ist nicht transparent, wenn es für irgendeine beträchtliche Menge von Text verwendet wird. Eine Kopie, die nicht „transparent“ ist, wird „undurchlässig“ genannt.

Beispiele von geeigneten Formaten für transparente Kopien beinhalten einfachen ASCII ohne Auszeichnung, Texinfo Eingabeformat, LaTeX Eingabeformat, SGML oder XML unter Verwendung einer öffentlich zugänglichen DTD, und standardkonformes einfaches HTML, PostScript oder PDF, vorgesehen für humane Modifikation. Beispiele für transparente Bildformate beinhalten PNG, XCF und JPG. Undurchlässige Formate beinhalten proprietäre Formate die nur mit proprietären Textverarbeitungssystemen gelesen und bearbeitet werden können, SGML oder XML für welche die DTD und/oder Bearbeitungswerkzeuge nicht allgemein verfügbar sind, und das maschinengenerierte HTML, PostScript oder PDF, erzeugt mit irgendwelchen Textverarbeitungssystemen, nur für Ausgabezwecke.

Das „Titelblatt“ bedeutet, für ein gedrucktes Buch, das Titelblatt an sich zzgl. solcher nachfolgenden Seiten die notwendig sind, die Lesbarkeit des Materials beizubehalten, wie von dieser Lizenz erfordert, um im Titelblatt zu erscheinen. Für Werke in Formaten, welche kein Titelblatt als solches haben, bedeutet „Titelblatt“ der Text nahe dem bedeutendsten Auftreten des Titels dieses Werkes, ausgehend vom Anfang des Textkörpers.

Der „Herausgeber“ ist jede Person oder Instanz, welche Kopien des Dokuments an die Öffentlichkeit verteilt.

Ein Abschnitt „Mit dem Titel XYZ“ bedeutet eine benannte Untereinheit des Dokuments, dessen Titel entweder genau XYZ ist, oder XYZ in runden Klammern, gefolgt von Text, welcher XYZ in eine andere Sprache übersetzt. (Hier steht XYZ für einen spezifischen Abschnittsnamen, weiter unten erwähnt, wie zum Beispiel „Danksagungen“, „Widmungen“, „Befürwortungen“ oder „Verlauf“.) Den „Titel“ eines solchen Abschnitts „zu erhalten“, wenn Sie das Dokument modifizieren, bedeutet, dass dieser ein Abschnitt „Mit dem Titel XYZ“ gemäß seiner Definition bleibt.

Das Dokument kann neben dem Hinweis, der festlegt, dass diese Lizenz auf das Dokument zutrifft, Garantie-Ausschlussklauseln beinhalten. Diese Garantie-Ausschlussklauseln werden als aufgenommen betrachtet, durch Verweis in dieser Lizenz, aber nur was die Ausschließung von Garantien betrifft: Jede andere Auswirkung, die diese Garantie-Ausschlussklauseln haben können, ist ungültig und hat keine Wirkung auf die Bedeutung dieser Lizenz.

Sie dürfen das Dokument in beliebiger Form kopieren und verteilen, entweder kommerziell oder nicht kommerziell, vorausgesetzt, dass diese Lizenz, die Urheberrechtshinweise und der Lizenzhinweis mit den Worten, dass diese Lizenz auf das Dokument zutrifft, in allen Kopien wiedergegeben werden, und dass Sie keine anderen Bedingungen, welcher Art auch immer, zu jenen dieser Lizenz hinzufügen. Sie dürfen keine technischen Maßnahmen anwenden die das Lesen oder weitere Vervielfältigung von den Kopien, die Sie erstellen oder verteilen, behindern oder kontrollieren. Allerdings können Sie Bezahlung im Austausch für Kopien entgegennehmen. Wenn Sie eine ausreichend große Anzahl von Kopien verteilen, müssen Sie außerdem die Bedingungen in Abschnitt 3 beachten.

Sie dürfen außerdem Kopien verleihen, unter den selben, oben angegebenen Bedingungen, und Sie dürfen Kopien öffentlich auslegen.

Wenn Sie, mehr als 100 umfassend, gedruckte Kopien eines Dokuments veröffentlichen (oder Kopien in Medien, die üblicherweise gedruckte Umschläge haben) und der Lizenzhinweis des Dokuments Umschlagtexte erfordert, müssen Sie die Kopien in Umschläge beifügen, welche eindeutig und leserlich alle diese Umschlagtexte tragen: vordere Umschlagtexte auf vordere Umschläge, und hintere Umschlagtexte auf hintere Umschläge. Beide Umschläge müssen, ebenso eindeutig und leserlich, Sie, als den Herausgeber dieser Kopien, identifizieren. Der vordere Umschlag muss den vollständigen Titel, mit allen Wörtern des Titels, in gleicher Weise auffallend und leicht erkennbar darstellen. Sie dürfen darüber hinaus sonstiges Material auf die Umschläge anbringen. Vervielfältigung mit Änderungen, begrenzt auf die Umschläge, sofern sie den Titel des Dokuments erhalten und diese Bedingungen erfüllen, können ansonsten als unveränderte Vervielfältigung behandelt werden.

Wenn die erforderlichen Texte für beide Umschläge zu umfangreich sind, um lesbar zu passen, sollten Sie die ersten verzeichneten (so viele, um angemessen zu passen) auf den aktuellen Umschlag setzen, und den Rest auf den nachfolgenden Seiten fortsetzen.

Wenn Sie, mehr als 100 umfassend, undurchlässige Kopien des Dokuments veröffentlichen oder verteilen, müssen Sie entweder eine maschinenlesbare transparente Kopie zusammen mit jeder undurchlässigen Kopie einbeziehen, oder in bzw. mit jeder undurchlässigen Kopie eine Computer-Netzwerkadresse angeben, von welcher die allgemeine netzwerknutzende Öffentlichkeit, unter Verwendung von Netzwerkprotokollen öffentlicher Standards, Zugang hat, um eine vollständig transparente Kopie, frei von hinzugefügtem Material, herunterzuladen. Falls Sie die letzte Option verwenden, müssen Sie angemessen überlegte Schritte unternehmen, wenn Sie mit der Verteilung von undurchlässigen Kopien in großen Mengen beginnen, um sicherzustellen, dass diese transparente Kopie unter der angegebenen Adresse auf diese Weise zugänglich bleibt, bis mindestens ein Jahr nachdem Sie zum letzten Mal eine undurchlässige Kopie (unmittelbar oder durch Ihre Vertreter oder Einzelhändler) in dieser Ausgabe an die Öffentlichkeit verteilen.

Es ist erwünscht, aber nicht erforderlich, dass Sie in Kontakt mit den Autoren des Dokuments treten, kurz bevor Sie irgendeine große Anzahl von Kopien neu verteilen, um ihnen die Möglichkeit zu geben, Sie mit einer aktualisierten Version des Dokuments zu versorgen.

Sie dürfen eine modifizierte Version des Dokuments unter den oben erwähnten Bedingungen der Abschnitte 2 und 3 kopieren und verteilen, vorausgesetzt, dass Sie die modifizierte Version unter genau dieser Lizenz freigeben, mit der modifizierten Version wird die Rolle des Dokuments besetzt, und somit der Lizenzierung von Verteilung und Modifikation der modifizierten Version, für jeden der eine Kopie davon besitzt. Zusätzlich müssen Sie diese Sachen in der modifizierten Version erledigen:

  • A. Verwenden Sie auf dem Titelblatt (und gegebenenfalls auf den Umschlägen) einen Titel der sich von dem des Dokuments unterscheidet, und von jenen der vorhergehenden Versionen (die, wenn es irgendwelche gab, in dem Verlaufs-Abschnitt des Dokuments verzeichnet sein sollten). Sie dürfen denselben Titel wie den einer vorhergehenden Version verwenden, wenn der ursprüngliche Herausgeber dieser Version die Erlaubnis gibt.

  • B. Verzeichnen Sie auf dem Titelblatt, als Autoren, eine oder mehrere Personen oder Organe, verantwortlich für die Autorschaft der Modifikationen in der modifizierten Version, zusammen mit mindestens fünf der Hauptautoren des Dokuments (alle seine Hauptautoren, wenn es weniger als fünf hat), es sei denn, dass sie Sie von dieser Anforderung befreien.

  • C. Geben Sie auf dem Titelblatt den Namen des Herausgebers der modifizierten Version als den des Herausgebers an.

  • D. Erhalten Sie alle Urheberrechtshinweise des Dokumentes.

  • E. Fügen Sie einen entsprechenden Urheberrechtshinweis für Ihre Modifikationen, angrenzend zu den anderen Urheberrechtshinweisen, hinzu.

  • F. Nehmen Sie, direkt nach den Urheberrechtshinweisen, einen Lizenzhinweis auf, der die öffentliche Erlaubnis gibt, die modifizierte Version unter den Bestimmungen dieser Lizenz zu verwenden, in der Form, wie weiter unten im Anhang gezeigt.

  • G. Erhalten Sie in diesem Lizenzhinweis die vollständigen Listen der unveränderlichen Abschnitte und erforderlichen Umschlagtexte, aufgeführt in dem Lizenzhinweis des Dokuments.

  • H. Nehmen Sie eine ungeänderte Kopie dieser Lizenz auf.

  • I. Erhalten Sie den Abschnitt mit dem Titel „Verlauf“, erhalten Sie seinen Titel und fügen Sie ihm einen Punkt hinzu, der mindestens den Titel, das Jahr, neue Autoren und Herausgeber der modifizierte Version angibt, wie auf dem Titelblatt aufgeführt. Wenn es keinen Abschnitt „Verlauf“ in dem Dokument gibt, erzeugen Sie einen, der den Titel, das Jahr, die Autoren und Herausgeber des Dokuments angibt, wie auf seinem Titelblatt aufgeführt, dann fügen Sie einen Punkt hinzu, der die modifizierte Version beschreibt, wie in dem vorhergehenden Satz angegeben.

  • J. Erhalten Sie gegebenenfalls die Netzwerkadresse, aufgeführt in dem Dokument, für den öffentlichen Zugang zu einer transparenten Kopie des Dokuments, und ebenso die in dem Dokument aufgeführten Netzwerkadressen, für vorhergehende Versionen, auf dem es beruht. Diese können in den Abschnitt „Verlauf“ untergebracht werden. Sie dürfen eine Netzwerkadresse für ein Werk auslassen, das mindestens vier Jahre vor dem Dokument selbst veröffentlicht wurde, oder der ursprüngliche Herausgeber der Version, auf die es sich bezieht, die Erlaubnis gibt.

  • K. Für jeden Abschnitt mit dem Titel „Danksagungen“ oder „Widmungen“, erhalten Sie den Titel des Abschnitts, und erhalten Sie in dem Abschnitt vollständig den wesentlichen Gehalt und Umgangston der, von jeglichen Mitwirkenden darin aufgeführten, Danksagungen und/oder Widmungen.

  • L. Erhalten Sie alle unveränderlichen Abschnitte des Dokuments, ungeändert in ihrem Text und ihren Titeln. Abschnittsnummern oder Entsprechendes werden nicht als Teil der Abschnittstitel betrachtet.

  • M. Löschen Sie jeden Abschnitt mit dem Titel „Befürwortungen“. Solch ein Abschnitt darf nicht in die modifizierte Version aufgenommen werden.

  • N. Betiteln Sie keinen Titel eines vorhandenen Abschnitts neu, der mit „Befürwortung“ betitelt ist oder in Konflikt zum Titel irgendeines unveränderlichen Abschnitts steht.

  • O. Erhalten Sie jegliche Garantie-Ausschlussklauseln.

Wenn die modifizierte Version neue Titelei-Abschnitte oder Anhänge beinhaltet, die als untergeordnete Abschnitte qualifiziert sind und kein kopiertes Material aus dem Dokument enthalten, können Sie Ihrer Wahl nach einige oder alle diese Abschnitte als unveränderlich bestimmen. Um dies zu tun, fügen Sie ihre Titel zur Liste der unveränderlichen Abschnitte in den Lizenzhinweis der modifizierten Version hinzu. Diese Titel müssen sich von allen anderen Abschnittstitel unterscheiden.

Sie können einen Abschnitt mit dem Titel „Befürwortungen“ hinzufügen, vorausgesetzt, dass dieser nichts enthält als nur Befürwortungen Ihrer modifizierten Version durch verschiedene Parteien – zum Beispiel Aussagen der Begutachtung oder dass der Text von einer Organisation als maßgebliche Definition eines Standards anerkannt worden ist.

Sie können eine Textpassage von bis zu fünf Wörtern als einen vorderen Umschlagtext, und eine Textpassage von bis zu 25 Wörtern als hinteren Umschlagtext in der modifizierten Version hinzufügen. Nur eine Textpassage des vorderen Umschlagtextes und eine des hinteren Umschlagtextes kann von (oder durch, von ihr, angefertigte Zusammenstellung) irgendeiner Person hinzugefügt werden. Wenn das Dokument bereits einen Umschlagtext für denselben Umschlag beinhaltet, zuvor von Ihnen hinzugefügt oder durch Zusammenstellung, angefertigt von derselben Person, in dessen Namen Sie handeln, können Sie keinen weiteren hinzufügen; aber Sie dürfen den alten ersetzen, mit ausdrücklicher Erlaubnis des vorherigen Herausgebers, welcher den alten hinzufügte.

Der/die Autor(en) und Herausgeber des Dokuments geben durch diese Lizenz für keine modifizierte Version die Erlaubnis ihre Namen für Werbung zu verwenden oder Befürwortung zu behaupten oder anzudeuten.

Sie dürfen das Dokument mit anderen, unter dieser Lizenz freigegeben, Dokumenten kombinieren, unter den Bestimmungen, definiert in Abschnitt 4 für modifizierte Versionen, vorausgesetzt, dass Sie in die Kombination alle unveränderlichen Abschnitte aller Originaldokumente, nicht modifiziert, einbeziehen und sie alle als unveränderliche Abschnitte Ihres kombinierten Werkes in dessen Lizenzhinweis verzeichnen, und dass Sie alle ihre Garantie-Ausschlussklauseln erhalten.

Das kombinierte Werk muss nur eine Kopie dieser Lizenz enthalten, und mehrfach identische unveränderliche Abschnitte können gegen eine einzelne Kopie ausgetauscht werden. Wenn es mehrfach identische unveränderliche Abschnitte mit demselben Namen, aber unterschiedlichem Inhalt gibt, erzeugen Sie den Titel eines jeden solchen Abschnitts an seinem Ende eindeutig durch Hinzufügen, in runden Klammern, des Namens, falls bekannt, des ursprünglichen Autors oder Herausgebers dieses Abschnittes, oder andernfalls einer eindeutigen Nummer. Nehmen Sie dieselbe Anpassung bei den Abschnittstiteln in der Liste von unveränderlichen Abschnitten in dem Lizenzhinweis des kombinierten Werkes vor.

In der Kombination müssen Sie jegliche Abschnitte mit dem Titel „Verlauf“ in den verschiedenen Originaldokumenten kombinieren und einen Abschnitt mit dem Titel „Verlauf“ bilden; ebenso kombinieren Sie jegliche Abschnitte mit dem Titel „Danksagungen“, und jegliche Abschnitte mit dem Titel „Widmungen“. Sie müssen alle Abschnitte mit dem Titel „Befürwortungen“ löschen.

Sie dürfen eine Sammlung erzeugen, bestehend aus dem Dokument und anderen Dokumenten, freigegeben unter dieser Lizenz, und die Einzel-Kopien dieser Lizenz in den verschiedenen Dokumenten gegen eine einzelne Kopie, die in die Sammlung aufgenommen wird, austauschen, vorausgesetzt, dass Sie die Regeln dieser Lizenz für unveränderte Vervielfältigung jedes Dokuments in jeder anderen Hinsicht befolgen.

Sie dürfen ein einzelnes Dokument aus solch einer Sammlung entnehmen, und es individuell unter dieser Lizenz verteilen, vorausgesetzt, dass Sie eine Kopie dieser Lizenz in das extrahierte Dokument einfügen, und diese Lizenz in jeder anderen Hinsicht, bezüglich der unveränderten Vervielfältigung dieses Dokuments, befolgen.

Eine Zusammentragung des Dokuments oder seiner Ableitungen mit anderen gesonderten und unabhängigen Dokumenten oder Werken, in oder zu einem Band auf einem Speicher- oder Verteilungsmedium, wird eine „Gruppierung“ genannt, wenn das Urheberrecht, das sich aus der Zusammentragung ergibt, nicht verwendet wird, um die gültigen Rechte der Benutzer dieser Zusammentragungen darüber hinaus, was die Einzel-Werke gestatten, zu beschränken. Wenn das Dokument in eine Gruppierung aufgenommen ist, trifft diese Lizenz nicht auf die anderen Werke in der Gruppierung zu, welche nicht selbst abgeleitete Werke des Dokuments sind.

Wenn die Anforderung für Umschlagtext von Abschnitt 3 auf diese Kopien des Dokuments anwendbar ist, wenn außerdem das Dokument weniger als eine Hälfte der gesamten Gruppierung darstellt, kann der Umschlagtext des Dokuments auf Umschläge, die das Dokument innerhalb der Gruppierung einklammern, untergebracht werden, oder der elektronischen Entsprechung von Umschlägen, wenn das Dokument in elektronischer Form vorliegt. Andernfalls müssen sie auf gedruckten Umschlägen vorkommen, welche die vollständige Gruppierung einklammern.

Übersetzung wird als eine Art von Modifikation betrachtet, also dürfen Sie Übersetzungen unter den Bestimmungen von Abschnitt 4 verteilen. Das Austauschen unveränderlicher Abschnitte mit Übersetzungen erfordert besondere Erlaubnis von ihren Urheberrechtsinhabern, aber Sie können Übersetzungen von einigen oder allen unveränderlichen Abschnitten aufnehmen, zusätzlich zu den Originalversionen dieser unveränderlichen Abschnitte. Sie können eine Übersetzung dieser Lizenz aufnehmen, und alle Lizenzhinweise in dem Dokument, und jegliche Garantie-Ausschlussklauseln, vorausgesetzt, dass Sie außerdem die englische Originalversion dieser Lizenz und die Originalversionen jener Hinweise und Ausschlussklauseln aufnehmen. Im Falle eines Widerspruchs zwischen der Übersetzung und der Originalversion dieser Lizenz oder eines Hinweises oder einer Ausschlussklausel, wird sich die Originalversion durchsetzen.

Wenn ein Abschnitt in dem Dokument mit „Danksagungen“, „Widmungen“ oder „Verlauf“ betitelt ist, wird die Anforderung (Abschnitt 4), seinen Titel (Abschnitt 1) zu erhalten, normalerweise die Änderung des tatsächlichen Titels erfordern.

Sie dürfen das Dokument nicht kopieren, modifizieren, unterlizenzieren oder verteilen, außer, als ausdrücklich unter dieser Lizenz zur Verfügung gestellt. Jeder andere Versuch es zu kopieren, zu modifizieren, zu unterlizenzieren oder zu verteilen ist ungültig, und wird automatisch Ihre Rechte unter dieser Lizenz aufkündigen.

Jedoch, wenn Sie jeglichen Verstoß gegen diese Lizenz beenden, dann ist ihre Lizenz eines bestimmten Urheberrechtsinhabers wieder (a) vorläufig, sofern und solange der Urheberrechtsinhaber nicht ihre Lizenz beendet, und (b) dauerhaft, wenn der Urheberrechtsinhaber es versäumt, Sie über den Verstoß zu benachrichtigen, mit angemessenen Mitteln, vorzeitig 60 Tage nach der Beendigung.

Darüber hinaus ist Ihre Lizenz eines bestimmten Urheberrechtsinhabers wieder dauerhaft, wenn der Urheberrechtsinhaber Sie über den Verstoß mit angemessenen Mitteln benachrichtigt, es das erste Mal ist, dass Sie eine Benachrichtigung über den Verstoß dieser Lizenz (für jedes Werk) vom Urheberrechtsinhaber erhalten, und Sie den Verstoß vorzeitig 30 Tage nach Erhalt der Benachrichtigung beseitigen.

Die Beendigung Ihrer Rechte unter diesem Abschnitt beendet nicht die Lizenzen der Parteien, welche Kopien oder Rechte von Ihnen unter dieser Lizenz erhalten haben. Wenn Ihre Rechte aufgekündigt und nicht wieder dauerhaft geworden sind, gibt Ihnen der Erhalt einer Kopie von Teilen oder Sämtlichem des gleichen Materials keine Rechte, diese zu verwenden.

Die Free Software Foundation kann von Zeit zu Zeit neue, überarbeitete Versionen der GNU-Lizenz für freie Dokumentation veröffentlichen. Solche neuen Versionen werden im Geist zur gegenwärtigen Version gleich sein, aber können sich im Detail unterscheiden, um neue Probleme oder Anliegen anzusprechen. Sehen Sie »http://www.gnu.org/copyleft/«.

Jeder Version der Lizenz wird eine charakteristische Versionsnummer gegeben. Wenn das Dokument spezifiziert, dass eine besonders nummerierte Version dieser Lizenz „oder jede spätere Version“ auf sich zutrifft, haben Sie die Wahl den Bestimmungen und Bedingungen entweder dieser spezifizierten Version oder jeder späteren Version, die (nicht als Entwurf) durch die Free Software Foundation veröffentlicht worden ist, zu folgen. Wenn das Dokument spezifiziert, dass ein Bevollmächtigter entscheiden darf welche zukünftigen Versionen dieser Lizenz verwendet werden können, berechtigt Sie das dauerhaft, durch die öffentliche Aussage desjenigen Bevollmächtigten über die Akzeptanz einer Version, diese Version für das Dokument zu wählen.

„Massive Multiauthor Collaboration Standort“ (oder „MMC-Standort“) meint jeglichen World Wide Web Server, welcher urheberrechtsfähige Werke veröffentlicht und ferner bedeutende Möglichkeiten für jeden bietet, solche Werke zu editieren. Ein öffentliches Wiki, welches jeder bearbeiten kann, ist ein Beispiel eines solchen Servers. Eine „Massives Multiautor Collaboration“ (oder „MMC“), enthalten im Standort, bedeutet jegliche Zusammenstellung urheberrechtsfähiger Werke, die folglich auf dem MMC-Standort veröffentlicht werden.

„CC-BY-SA“ meint die Creative Commons Namensnennung-Weitergabe unter gleichen Bedingungen 3.0 Lizenz, veröffentlicht von der Creative Commons Corporation, einem gemeinnützigen Unternehmen mit Hauptgeschäftssitz in San Francisco, Californien, sowie zukünftige Copyleft-Versionen dieser Lizenz, welche durch dieselbe Organisation veröffentlicht wird.

„Einbeziehen“ bedeutet, ein Dokument zu veröffentlichen oder neu zu veröffentlichen, ganz oder teilweise, als Bestandteil eines anderen Dokuments.

Eine MMC ist „geeignet zur Relizenzierung“ wenn sie unter dieser Lizenz lizenziert wird, und wenn alle Werke, die zuerst unter dieser Lizenz irgendwo anders als auf der MMC veröffentlicht, und nachträglich ganz oder teilweise in der MMC einbezogen wurden, (1) keine Umschlagtexte oder unveränderliche Abschnitte hatten, und (2) folglich vor dem 1. November 2008 einbezogen wurden.

Der Betreiber eines MMC-Standortes kann eine MMC, enthalten im Standort unter CC-BY-SA des gleichen Standortes, jederzeit vor dem 1. August 2009 neu veröffentlichen, vorausgesetzt, die MMC ist für die Relizenzierung geeignet.

Um diese Lizenz in einem Dokument, das Sie geschrieben haben, zu verwenden, nehmen Sie eine Kopie der Lizenz in das Dokument auf und setzen Sie die folgenden Urheberrechts- und Lizenzhinweise unmittelbar hinter das Titelblatt:

Copyright © JAHR IHR NAME.

Es wird die Erlaubnis gewährt, dieses Dokument zu kopieren, zu verteilen und/oder zu modifizieren, unter den Bestimmungen der GNU Free Documentation License, Version 1.3 oder jeder späteren Version, veröffentlicht von der Free Software Foundation; mit keinen unveränderlichen Abschnitten, keinen vorderen Umschlagtexten und keinen hinteren Umschlagtexten. Eine Kopie der Lizenz ist aufgenommen in den Abschnitt mit dem Titel "GNU Free Documentation License".

Wenn Sie unveränderliche Abschnitte, vordere Umschlagtexte und hintere Umschlagtexte haben, ersetzen Sie die Zeile „mit … Umschlagtexten.“ durch diese:

mit den unveränderlichen Abschnitten AUFGELISTET NACH TITELN, mit den vorderen Umschlagtexten AUFGELISTET und mit den hinteren Umschlagtexten AUFGELISTET.

Wenn Sie unveränderliche Abschnitte ohne Umschlagtexte haben oder eine andere Kombination der drei, vermischen Sie jene zwei Alternativen zu einer übereinstimmenden Situation.

Wenn Ihr Dokument nicht-triviale Beispiele eines Programmcodes enthält, empfehlen wir, diese Beispiele entsprechend unter einer freien Software-Lizenz ihrer Wahl, wie der GNU General Public License freizugeben, um deren Verwendung in freier Software zu gestatten.

This is an unofficial translation of the GNU Free Documentation License into German.
It was not published by the Free Software Foundation, and does not legally state the distribution terms for     documentation that uses the GNU FDL—only the original English text of the GNU FDL does that.
However, we hope that this translation will help German speakers understand the GNU FDL better.

Dies ist eine inoffizielle Übersetzung der GNU Free Documentation License (FDLv1.3) ins Deutsche. Sie wurde nicht von der Free Software Foundation veröffentlicht, und legt keine rechtsgültigen Bestimmungen zur Verteilung für Dokumentation fest, welche die GNU FDL verwendet – nur der englische Originaltext der GNU FDL gewährleistet dies. Dennoch hoffen wir, dass diese Übersetzung Deutsch sprechenden dazu verhilft, die GNU FDL besser zu verstehen. Urheberrechtshinweis

Deutsche Übersetzung © 2008 – 2009 Ingo Rybaczyk <rybaczyk@freeunix.net>

Die unveränderte Vervielfältigung und Verteilung des gesamten Artikels in beliebiger Form ist gestattet, vorausgesetzt, dass dieser Hinweis erhalten bleibt.

Diese inoffizielle Übersetzung ins Deutsche entstammt der Webseite von Ingo Rybaczyk. Diese Textfassung hat das letzte Abfrufdatum des 31.07.2009. Die aktuellste Version der Übersetzung findet man unter der Internetadresse (URL) http://rybaczyk.freeunix.net/licenses/fdl-1.3.de.html.

GNU Free Documentation License
Version 1.3, 3 November 2008
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
    <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque".

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text.

The "publisher" means any person or entity that distributes copies of the Document to the public.

A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition.

The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

  1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.

  2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.

  3. State on the Title page the name of the publisher of the Modified Version, as the publisher.

  4. Preserve all the copyright notices of the Document.

  5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.

  6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.

  7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice.

  8. Include an unaltered copy of this License.

  9. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.

  10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.

  11. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.

  12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.

  13. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.

  14. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.

  15. Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles.

You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements".

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License.

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document.

"Massive Multiauthor Collaboration Site" (or "MMC Site") means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A "Massive Multiauthor Collaboration" (or "MMC") contained in the site means any set of copyrightable works thus published on the MMC site.

"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.

"Incorporate" means to publish or republish a Document, in whole or in part, as part of another Document.

An MMC is "eligible for relicensing" if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.

The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

Copyright (c)  YEAR  YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with…Texts." line with this:

with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

Creative Commons Lizenz - Namensnennung-Weitergabe unter gleichen Bedingungen 3.0 Deutschland

DER GEGENSTAND DIESER LIZENZ (WIE UNTER "SCHUTZGEGENSTAND" DEFINIERT) WIRD UNTER DEN BEDINGUNGEN DIESER CREATIVE COMMONS PUBLIC LICENSE ("CCPL", "LIZENZ" ODER "LIZENZVERTRAG") ZUR VERFÜGUNG GESTELLT. DER SCHUTZGEGENSTAND IST DURCH DAS URHEBERRECHT UND/ODER ANDERE GESETZE GESCHÜTZT. JEDE FORM DER NUTZUNG DES SCHUTZGEGENSTANDES, DIE NICHT AUFGRUND DIESER LIZENZ ODER DURCH GESETZE GESTATTET IST, IST UNZULÄSSIG.

DURCH DIE AUSÜBUNG EINES DURCH DIESE LIZENZ GEWÄHRTEN RECHTS AN DEM SCHUTZGEGENSTAND ERKLÄREN SIE SICH MIT DEN LIZENZBEDINGUNGEN RECHTSVERBINDLICH EINVERSTANDEN. SOWEIT DIESE LIZENZ ALS LIZENZVERTRAG ANZUSEHEN IST, GEWÄHRT IHNEN DER LIZENZGEBER DIE IN DER LIZENZ GENANNTEN RECHTE UNENTGELTLICH UND IM AUSTAUSCH DAFÜR, DASS SIE DAS GEBUNDENSEIN AN DIE LIZENZBEDINGUNGEN AKZEPTIEREN.

  1. Der Begriff "Abwandlung" im Sinne dieser Lizenz bezeichnet das Ergebnis jeglicher Art von Veränderung des Schutzgegenstandes, solange die eigenpersönlichen Züge des Schutzgegenstandes darin nicht verblassen und daran eigene Schutzrechte entstehen. Das kann insbesondere eine Bearbeitung, Umgestaltung, Änderung, Anpassung, Übersetzung oder Heranziehung des Schutzgegenstandes zur Vertonung von Laufbildern sein. Nicht als Abwandlung des Schutzgegenstandes gelten seine Aufnahme in eine Sammlung oder ein Sammelwerk und die freie Benutzung des Schutzgegenstandes.

  2. Der Begriff "Sammelwerk" im Sinne dieser Lizenz meint eine Zusammenstellung von literarischen, künstlerischen oder wissenschaftlichen Inhalten, sofern diese Zusammenstellung aufgrund von Auswahl und Anordnung der darin enthaltenen selbständigen Elemente eine geistige Schöpfung darstellt, unabhängig davon, ob die Elemente systematisch oder methodisch angelegt und dadurch einzeln zugänglich sind oder nicht.

  3. "Verbreiten" im Sinne dieser Lizenz bedeutet, den Schutzgegenstand oder Abwandlungen im Original oder in Form von Vervielfältigungsstücken, mithin in körperlich fixierter Form der Öffentlichkeit anzubieten oder in Verkehr zu bringen.

  4. Unter "Lizenzelementen" werden im Sinne dieser Lizenz die folgenden übergeordneten Lizenzcharakteristika verstanden, die vom Lizenzgeber ausgewählt wurden und in der Bezeichnung der Lizenz zum Ausdruck kommen: "Namensnennung", "Weitergabe unter gleichen Bedingungen".

  5. Der "Lizenzgeber" im Sinne dieser Lizenz ist diejenige natürliche oder juristische Person oder Gruppe, die den Schutzgegenstand unter den Bedingungen dieser Lizenz anbietet und insoweit als Rechteinhaberin auftritt.

  6. "Rechteinhaber" im Sinne dieser Lizenz ist der Urheber des Schutzgegenstandes oder jede andere natürliche oder juristische Person oder Gruppe von Personen, die am Schutzgegenstand ein Immaterialgüterrecht erlangt hat, welches die in Abschnitt 3 genannten Handlungen erfasst und bei dem eine Einräumung von Nutzungsrechten oder eine Weiterübertragung an Dritte möglich ist.

  7. Der Begriff "Schutzgegenstand" bezeichnet in dieser Lizenz den literarischen, künstlerischen oder wissenschaftlichen Inhalt, der unter den Bedingungen dieser Lizenz angeboten wird. Das kann insbesondere eine persönliche geistige Schöpfung jeglicher Art, ein Werk der kleinen Münze, ein nachgelassenes Werk oder auch ein Lichtbild oder anderes Objekt eines verwandten Schutzrechts sein, unabhängig von der Art seiner Fixierung und unabhängig davon, auf welche Weise jeweils eine Wahrnehmung erfolgen kann, gleichviel ob in analoger oder digitaler Form. Soweit Datenbanken oder Zusammenstellungen von Daten einen immaterialgüterrechtlichen Schutz eigener Art genießen, unterfallen auch sie dem Begriff "Schutzgegenstand" im Sinne dieser Lizenz.

  8. Mit "Sie" bzw. "Ihnen" ist die natürliche oder juristische Person gemeint, die in dieser Lizenz im Abschnitt 3 genannte Nutzungen des Schutzgegenstandes vornimmt und zuvor in Hinblick auf den Schutzgegenstand nicht gegen Bedingungen dieser Lizenz verstoßen oder aber die ausdrückliche Erlaubnis des Lizenzgebers erhalten hat, die durch diese Lizenz gewährten Nutzungsrechte trotz eines vorherigen Verstoßes auszuüben.

  9. Unter "Öffentlich Zeigen" im Sinne dieser Lizenz sind Veröffentlichungen und Präsentationen des Schutzgegenstandes zu verstehen, die für eine Mehrzahl von Mitgliedern der Öffentlichkeit bestimmt sind und in unkörperlicher Form mittels öffentlicher Wiedergabe in Form von Vortrag, Aufführung, Vorführung, Darbietung, Sendung, Weitersendung, zeit- und ortsunabhängiger Zugänglichmachung oder in körperlicher Form mittels Ausstellung erfolgen, unabhängig von bestimmten Veranstaltungen und unabhängig von den zum Einsatz kommenden Techniken und Verfahren, einschließlich drahtgebundener oder drahtloser Mittel und Einstellen in das Internet.

  10. "Vervielfältigen" im Sinne dieser Lizenz bedeutet, mittels beliebiger Verfahren Vervielfältigungsstücke des Schutzgegenstandes herzustellen, insbesondere durch Ton- oder Bildaufzeichnungen, und umfasst auch den Vorgang, erstmals körperliche Fixierungen des Schutzgegenstandes sowie Vervielfältigungsstücke dieser Fixierungen anzufertigen, sowie die Übertragung des Schutzgegenstandes auf einen Bild- oder Tonträger oder auf ein anderes elektronisches Medium, gleichviel ob in digitaler oder analoger Form. 11.

    "Mit Creative Commons kompatible Lizenz" bezeichnet eine Lizenz, die unter http://creativecommons.org/compatiblelicenses aufgelistet ist und die durch Creative Commons als grundsätzlich zur vorliegenden Lizenz äquivalent akzeptiert wurde, da zumindest folgende Voraussetzungen erfüllt sind:
    Diese mit Creative Commons kompatible Lizenz
       1. enthält Bestimmungen, welche die gleichen Ziele verfolgen, die gleiche Bedeutung haben und die gleichen Wirkungen erzeugen wie die Lizenzelemente der vorliegenden Lizenz; und
       2. erlaubt ausdrücklich das Lizenzieren von ihr unterstellten Abwandlungen unter vorliegender Lizenz, unter einer anderen rechtsordnungsspezifisch angepassten Creative-Commons-Lizenz mit denselben Lizenzelementen, wie sie die vorliegende Lizenz aufweist, oder unter der entsprechenden Creative-Commons-Unported-Lizenz.

Diese Lizenz ist in keiner Weise darauf gerichtet, Befugnisse zur Nutzung des Schutzgegenstandes zu vermindern, zu beschränken oder zu vereiteln, die Ihnen aufgrund der Schranken des Urheberrechts oder anderer Rechtsnormen bereits ohne Weiteres zustehen oder sich aus dem Fehlen eines immaterialgüterrechtlichen Schutzes ergeben.

Unter den Bedingungen dieser Lizenz räumt Ihnen der Lizenzgeber - unbeschadet unverzichtbarer Rechte und vorbehaltlich des Abschnitts 3.e) - das vergütungsfreie, räumlich und zeitlich (für die Dauer des Schutzrechts am Schutzgegenstand) unbeschränkte einfache Recht ein, den Schutzgegenstand auf die folgenden Arten und Weisen zu nutzen ("unentgeltlich eingeräumtes einfaches Nutzungsrecht für jedermann"):

  1. Den Schutzgegenstand in beliebiger Form und Menge zu vervielfältigen, ihn in Sammelwerke zu integrieren und ihn als Teil solcher Sammelwerke zu vervielfältigen;

  2. Abwandlungen des Schutzgegenstandes anzufertigen, einschließlich Übersetzungen unter Nutzung jedweder Medien, sofern deutlich erkennbar gemacht wird, dass es sich um Abwandlungen handelt;

  3. den Schutzgegenstand, allein oder in Sammelwerke aufgenommen, öffentlich zu zeigen und zu verbreiten;

  4. Abwandlungen des Schutzgegenstandes zu veröffentlichen, öffentlich zu zeigen und zu verbreiten. 5.

    Bezüglich Vergütung für die Nutzung des Schutzgegenstandes gilt Folgendes:
       1. Unverzichtbare gesetzliche Vergütungsansprüche: Soweit unverzichtbare Vergütungsansprüche im Gegenzug für gesetzliche Lizenzen vorgesehen oder Pauschalabgabensysteme (zum Beispiel für Leermedien) vorhanden sind, behält sich der Lizenzgeber das ausschließliche Recht vor, die entsprechende Vergütung einzuziehen für jede Ausübung eines Rechts aus dieser Lizenz durch Sie.
       2. Vergütung bei Zwangslizenzen: Sofern Zwangslizenzen außerhalb dieser Lizenz vorgesehen sind und zustande kommen, verzichtet der Lizenzgeber für alle Fälle einer lizenzgerechten Nutzung des Schutzgegenstandes durch Sie auf jegliche Vergütung.
       3. Vergütung in sonstigen Fällen: Bezüglich lizenzgerechter Nutzung des Schutzgegenstandes durch Sie, die nicht unter die beiden vorherigen Abschnitte (i) und (ii) fällt, verzichtet der Lizenzgeber auf jegliche Vergütung, unabhängig davon, ob eine Einziehung der Vergütung durch ihn selbst oder nur durch eine Verwertungsgesellschaft möglich wäre.

Das vorgenannte Nutzungsrecht wird für alle bekannten sowie für alle noch nicht bekannten Nutzungsarten eingeräumt. Es beinhaltet auch das Recht, solche Änderungen am Schutzgegenstand vorzunehmen, die für bestimmte nach dieser Lizenz zulässige Nutzungen technisch erforderlich sind. Alle sonstigen Rechte, die über diesen Abschnitt hinaus nicht ausdrücklich durch den Lizenzgeber eingeräumt werden, bleiben diesem allein vorbehalten. Soweit Datenbanken oder Zusammenstellungen von Daten Schutzgegenstand dieser Lizenz oder Teil dessen sind und einen immaterialgüterrechtlichen Schutz eigener Art genießen, verzichtet der Lizenzgeber auf sämtliche aus diesem Schutz resultierenden Rechte.

Die Einräumung des Nutzungsrechts gemäß Abschnitt 3 dieser Lizenz erfolgt ausdrücklich nur unter den folgenden Bedingungen:

  1. Sie dürfen den Schutzgegenstand ausschließlich unter den Bedingungen dieser Lizenz verbreiten oder öffentlich zeigen. Sie müssen dabei stets eine Kopie dieser Lizenz oder deren vollständige Internetadresse in Form des Uniform-Resource-Identifier (URI) beifügen. Sie dürfen keine Vertrags- oder Nutzungsbedingungen anbieten oder fordern, die die Bedingungen dieser Lizenz oder die durch diese Lizenz gewährten Rechte beschränken. Sie dürfen den Schutzgegenstand nicht unterlizenzieren. Bei jeder Kopie des Schutzgegenstandes, die Sie verbreiten oder öffentlich zeigen, müssen Sie alle Hinweise unverändert lassen, die auf diese Lizenz und den Haftungsausschluss hinweisen. Wenn Sie den Schutzgegenstand verbreiten oder öffentlich zeigen, dürfen Sie (in Bezug auf den Schutzgegenstand) keine technischen Maßnahmen ergreifen, die den Nutzer des Schutzgegenstandes in der Ausübung der ihm durch diese Lizenz gewährten Rechte behindern können. Dieser Abschnitt 4.a) gilt auch für den Fall, dass der Schutzgegenstand einen Bestandteil eines Sammelwerkes bildet, was jedoch nicht bedeutet, dass das Sammelwerk insgesamt dieser Lizenz unterstellt werden muss. Sofern Sie ein Sammelwerk erstellen, müssen Sie auf die Mitteilung eines Lizenzgebers hin aus dem Sammelwerk die in Abschnitt 4.c) aufgezählten Hinweise entfernen. Wenn Sie eine Abwandlung vornehmen, müssen Sie auf die Mitteilung eines Lizenzgebers hin von der Abwandlung die in Abschnitt 4.c) aufgezählten Hinweise entfernen. 2.

    Sie dürfen eine Abwandlung ausschließlich unter den Bedingungen
       1. dieser Lizenz,
       2. einer späteren Version dieser Lizenz mit denselben Lizenzelementen,
       3. einer rechtsordnungsspezifischen Creative-Commons-Lizenz mit denselben Lizenzelementen ab Version 3.0 aufwärts (z.B. Namensnennung - Weitergabe unter gleichen Bedingungen 3.0 US),
       4. der Creative-Commons-Unported-Lizenz mit denselben Lizenzelementen ab Version 3.0 aufwärts, oder
       5. einer mit Creative Commons kompatiblen Lizenz
    verbreiten oder öffentlich zeigen.
    Falls Sie die Abwandlung gemäß Abschnitt (v) unter einer mit Creative Commons kompatiblen Lizenz lizenzieren, müssen Sie deren Lizenzbestimmungen Folge leisten.
       Falls Sie die Abwandlungen unter einer der unter (i)-(iv) genannten Lizenzen ("Verwendbare Lizenzen") lizenzieren, müssen Sie deren Lizenzbestimmungen sowie folgenden Bestimmungen Folge leisten: Sie müssen stets eine Kopie der verwendbaren Lizenz oder deren vollständige Internetadresse in Form des Uniform-Resource-Identifier (URI) beifügen, wenn Sie die Abwandlung verbreiten oder öffentlich zeigen. Sie dürfen keine Vertrags- oder Nutzungsbedingungen anbieten oder fordern, die die Bedingungen der verwendbaren Lizenz oder die durch sie gewährten Rechte beschränken. Bei jeder Abwandlung, die Sie verbreiten oder öffentlich zeigen, müssen Sie alle Hinweise auf die verwendbare Lizenz und den Haftungsausschluss unverändert lassen. Wenn Sie die Abwandlung verbreiten oder öffentlich zeigen, dürfen Sie (in Bezug auf die Abwandlung) keine technischen Maßnahmen ergreifen, die den Nutzer der Abwandlung in der Ausübung der ihm durch die verwendbare Lizenz gewährten Rechte behindern können. Dieser Abschnitt 4.b) gilt auch für den Fall, dass die Abwandlung einen Bestandteil eines Sammelwerkes bildet, was jedoch nicht bedeutet, dass das Sammelwerk insgesamt der verwendbaren Lizenz unterstellt werden muss.
    3.
    Die Verbreitung und das öffentliche Zeigen des Schutzgegenstandes oder auf ihm aufbauender Abwandlungen oder ihn enthaltender Sammelwerke ist Ihnen nur unter der Bedingung gestattet, dass Sie, vorbehaltlich etwaiger Mitteilungen im Sinne von Abschnitt 4.a), alle dazu gehörenden Rechtevermerke unberührt lassen. Sie sind verpflichtet, die Rechteinhaberschaft in einer der Nutzung entsprechenden, angemessenen Form anzuerkennen, indem Sie - soweit bekannt - Folgendes angeben:
       1. Den Namen (oder das Pseudonym, falls ein solches verwendet wird) des Rechteinhabers und / oder, falls der Lizenzgeber im Rechtevermerk, in den Nutzungsbedingungen oder auf andere angemessene Weise eine Zuschreibung an Dritte vorgenommen hat (z.B. an eine Stiftung, ein Verlagshaus oder eine Zeitung) ("Zuschreibungsempfänger"), Namen bzw. Bezeichnung dieses oder dieser Dritten;
       2. den Titel des Inhaltes;
       3. in einer praktikablen Form den Uniform-Resource-Identifier (URI, z.B. Internetadresse), den der Lizenzgeber zum Schutzgegenstand angegeben hat, es sei denn, dieser URI verweist nicht auf den Rechtevermerk oder die Lizenzinformationen zum Schutzgegenstand;
       4. und im Falle einer Abwandlung des Schutzgegenstandes in Übereinstimmung mit Abschnitt 3.b) einen Hinweis darauf, dass es sich um eine Abwandlung handelt.
       Die nach diesem Abschnitt 4.c) erforderlichen Angaben können in jeder angemessenen Form gemacht werden; im Falle einer Abwandlung des Schutzgegenstandes oder eines Sammelwerkes müssen diese Angaben das Minimum darstellen und bei gemeinsamer Nennung mehrerer Rechteinhaber dergestalt erfolgen, dass sie zumindest ebenso hervorgehoben sind wie die Hinweise auf die übrigen Rechteinhaber. Die Angaben nach diesem Abschnitt dürfen Sie ausschließlich zur Angabe der Rechteinhaberschaft in der oben bezeichneten Weise verwenden. Durch die Ausübung Ihrer Rechte aus dieser Lizenz dürfen Sie ohne eine vorherige, separat und schriftlich vorliegende Zustimmung des Lizenzgebers und / oder des Zuschreibungsempfängers weder explizit noch implizit irgendeine Verbindung zum Lizenzgeber oder Zuschreibungsempfänger und ebenso wenig eine Unterstützung oder Billigung durch ihn andeuten.
    4. Die oben unter 4.a) bis c) genannten Einschränkungen gelten nicht für solche Teile des Schutzgegenstandes, die allein deshalb unter den Schutzgegenstandsbegriff fallen, weil sie als Datenbanken oder Zusammenstellungen von Daten einen immaterialgüterrechtlichen Schutz eigener Art genießen.
    5. Persönlichkeitsrechte bleiben - soweit sie bestehen - von dieser Lizenz unberührt.

SOFERN KEINE ANDERS LAUTENDE, SCHRIFTLICHE VEREINBARUNG ZWISCHEN DEM LIZENZGEBER UND IHNEN GESCHLOSSEN WURDE UND SOWEIT MÄNGEL NICHT ARGLISTIG VERSCHWIEGEN WURDEN, BIETET DER LIZENZGEBER DEN SCHUTZGEGENSTAND UND DIE EINRÄUMUNG VON RECHTEN UNTER AUSSCHLUSS JEGLICHER GEWÄHRLEISTUNG AN UND ÜBERNIMMT WEDER AUSDRÜCKLICH NOCH KONKLUDENT GARANTIEN IRGENDEINER ART. DIES UMFASST INSBESONDERE DAS FREISEIN VON SACH- UND RECHTSMÄNGELN, UNABHÄNGIG VON DEREN ERKENNBARKEIT FÜR DEN LIZENZGEBER, DIE VERKEHRSFÄHIGKEIT DES SCHUTZGEGENSTANDES, SEINE VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK SOWIE DIE KORREKTHEIT VON BESCHREIBUNGEN. DIESE GEWÄHRLEISTUNGSBESCHRÄNKUNG GILT NICHT, SOWEIT MÄNGEL ZU SCHÄDEN DER IN ABSCHNITT 6 BEZEICHNETEN ART FÜHREN UND AUF SEITEN DES LIZENZGEBERS DAS JEWEILS GENANNTE VERSCHULDEN BZW. VERTRETENMÜSSEN EBENFALLS VORLIEGT.

DER LIZENZGEBER HAFTET IHNEN GEGENÜBER IN BEZUG AUF SCHÄDEN AUS DER VERLETZUNG DES LEBENS, DES KÖRPERS ODER DER GESUNDHEIT NUR, SOFERN IHM WENIGSTENS FAHRLÄSSIGKEIT VORZUWERFEN IST, FÜR SONSTIGE SCHÄDEN NUR BEI GROBER FAHRLÄSSIGKEIT ODER VORSATZ, UND ÜBERNIMMT DARÜBER HINAUS KEINERLEI FREIWILLIGE HAFTUNG.

  1. Diese Lizenz und die durch sie eingeräumten Nutzungsrechte erlöschen mit Wirkung für die Zukunft im Falle eines Verstoßes gegen die Lizenzbedingungen durch Sie, ohne dass es dazu der Kenntnis des Lizenzgebers vom Verstoß oder einer weiteren Handlung einer der Vertragsparteien bedarf. Mit natürlichen oder juristischen Personen, die Abwandlungen des Schutzgegenstandes oder diesen enthaltende Sammelwerke unter den Bedingungen dieser Lizenz von Ihnen erhalten haben, bestehen nachträglich entstandene Lizenzbeziehungen jedoch solange weiter, wie die genannten Personen sich ihrerseits an sämtliche Lizenzbedingungen halten. Darüber hinaus gelten die Ziffern 1, 2, 5, 6, 7, und 8 auch nach einem Erlöschen dieser Lizenz fort.

  2. Vorbehaltlich der oben genannten Bedingungen gilt diese Lizenz unbefristet bis der rechtliche Schutz für den Schutzgegenstand ausläuft. Davon abgesehen behält der Lizenzgeber das Recht, den Schutzgegenstand unter anderen Lizenzbedingungen anzubieten oder die eigene Weitergabe des Schutzgegenstandes jederzeit einzustellen, solange die Ausübung dieses Rechts nicht einer Kündigung oder einem Widerruf dieser Lizenz (oder irgendeiner Weiterlizenzierung, die auf Grundlage dieser Lizenz bereits erfolgt ist bzw. zukünftig noch erfolgen muss) dient und diese Lizenz unter Berücksichtigung der oben zum Erlöschen genannten Bedingungen vollumfänglich wirksam bleibt.

  1. Jedes Mal wenn Sie den Schutzgegenstand für sich genommen oder als Teil eines Sammelwerkes verbreiten oder öffentlich zeigen, bietet der Lizenzgeber dem Empfänger eine Lizenz zu den gleichen Bedingungen und im gleichen Umfang an, wie Ihnen in Form dieser Lizenz.

  2. Jedes Mal wenn Sie eine Abwandlung des Schutzgegenstandes verbreiten oder öffentlich zeigen, bietet der Lizenzgeber dem Empfänger eine Lizenz am ursprünglichen Schutzgegenstand zu den gleichen Bedingungen und im gleichen Umfang an, wie Ihnen in Form dieser Lizenz.

  3. Sollte eine Bestimmung dieser Lizenz unwirksam sein, so bleibt davon die Wirksamkeit der Lizenz im Übrigen unberührt.

  4. Keine Bestimmung dieser Lizenz soll als abbedungen und kein Verstoß gegen sie als zulässig gelten, solange die von dem Verzicht oder von dem Verstoß betroffene Seite nicht schriftlich zugestimmt hat.

  5. Diese Lizenz (zusammen mit in ihr ausdrücklich vorgesehenen Erlaubnissen, Mitteilungen und Zustimmungen, soweit diese tatsächlich vorliegen) stellt die vollständige Vereinbarung zwischen dem Lizenzgeber und Ihnen in Bezug auf den Schutzgegenstand dar. Es bestehen keine Abreden, Vereinbarungen oder Erklärungen in Bezug auf den Schutzgegenstand, die in dieser Lizenz nicht genannt sind. Rechtsgeschäftliche Änderungen des Verhältnisses zwischen dem Lizenzgeber und Ihnen sind nur über Modifikationen dieser Lizenz möglich. Der Lizenzgeber ist an etwaige zusätzliche, einseitig durch Sie übermittelte Bestimmungen nicht gebunden. Diese Lizenz kann nur durch schriftliche Vereinbarung zwischen Ihnen und dem Lizenzgeber modifiziert werden. Derlei Modifikationen wirken ausschließlich zwischen dem Lizenzgeber und Ihnen und wirken sich nicht auf die Dritten gemäß Ziffern 8.a) und b) angeboteten Lizenzen aus.

  6. Sofern zwischen Ihnen und dem Lizenzgeber keine anderweitige Vereinbarung getroffen wurde und soweit Wahlfreiheit besteht, findet auf diesen Lizenzvertrag das Recht der Bundesrepublik Deutschland Anwendung.

Creative Commons License - Attribution-ShareAlike 3.0 Unported

THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.

BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.

  1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.

  2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License.

  3. "Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License.

  4. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.

  5. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.

  6. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.

  7. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.

  8. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.

  9. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.

  10. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.

  11. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.

Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.

Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:

  1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;

  2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";

  3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and,

  4. to Distribute and Publicly Perform Adaptations. 5.

    For the avoidance of doubt:
       1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
       2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
       3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.

The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.

The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:

  1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested.

  2. You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License.

  3. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor’s copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.

  4. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author’s honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author’s honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.

UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.

EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

  1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.

  2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.

  1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.

  2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.

  3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.

  4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.

  5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.

  6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.

19. Index