====== Programmierrichtlinien ======
===== Vorwort =====
**Hallo liebe Freunde der Vereinsverwaltung!**
Das vorliegende Dokument soll dabei helfen, sauberen, für andere nachvollziehbaren, Code zu generieren. Die hier aufgeführten Punkte sind lediglich als Umsetzungsvorschläge zu verstehen. Im Zweifelsfall sollte man einfach den Verstand einschalten und nachdenken, ob das alles wirklich so übersichtlich ist, wie man sich das vorgestellt hat.
Man sollte beim Programmieren schon gewisse Disziplin walten lassen. Dazu gehört das Vermeiden von Umlauten, einheitliche Codeeinrückungen und noch viel mehr. Es bezieht sich auf alle Programmiersprachen, die in Admidio benutzt werden (PHP, JavaScript).
Dieses Dokument ist hauptsächlich an Entwickler gerichtet, die ihren Code gerne in das offizielle Admidio-Release einbauen wollen, aber auch für die private Entwicklung können diese Richtlinien nicht schaden. Das Dokument ist übrigens noch nicht fertig. Wer möchte kann gerne eigene Kapitel oder Anmerkungen hinzufuegen.
===== Einrückung =====
Einrückungen gehören zu den wichtigsten Mitteln um den Code strukturiert zu halten.
Wir haben uns für Einrückungen in Höhe von **vier** Leerzeichen entschieden. Das heißt, in der Entwicklungsumgebung muss eingestellt sein, dass ein Tab vier Leerzeichen entspricht. Außerdem sollte jeder einstellen, dass die Tabs beim Einfügen/Speichern durch Leerzeichen ersetzt werden.
Die Einrückung gilt dann sowohl für PHP, JavaScript und HTML-Code.
echo '
';
===== Kontrollstrukturen =====
Mit Kontrollstrukturen sind folgende Elemente gemeint:
* if
* for
* while
* switch
Hierbei sollte darauf geachtet werden, dass die geschweiften Klammern immer auf der Höhe der zugehörigen Kontrollstruktur in einer separaten Zeile stehen!
Hier ein Beispiel für eine verschachtelte if-Anweisung:
if((bedingung1) and (bedingung2))
{
action1;
if(bedingung3)
{
action2;
}
}
elseif((bedingung4) or (bedingung5))
{
action3;
action4;
}
else
{
defaultaction;
}
Hier die Erläuterung:
* Wer möchte kann 1 Leerzeichen zwischen ControlKeyword (if) und der Bedingung machen, um sie von Methodenaufrufen abzugrenzen. Dies ist aber jedem selbst überlassen.
* auch wenn nur eine Action definiert ist immer geschweifte Klammern nutzen
Hier noch ein Beispiel für eine switch/case-Anweisung:
switch(bedingung)
{
case 1:
action1;
break;
case 2:
action2;
break;
default:
defaultaction;
break;
}
Verkürzte Schreibweisen, wie zum Beispiel die folgende If-Anweisung sollten aus Gründen der Übersichtlichkeit vermieden werden!
(bedingung) ? action1 : action2
===== Funktionsaufrufe =====
Ein Funktionsaufruf geschieht immer ohne Leerzeichen zwischen dem Funktionsnamen, der öffnenden Klammer und dem ersten Übergabeparameter. Die einzelnen Parameter werden mit Komma und Leerzeichen von einander getrennt. Hinter dem letztem Parameter wird ebenfalls kein Leerzeichen mehr eingesetzt. Anbei wieder ein Beispiel:
$var = funktion($para1, $para2, $para3);
Wie oben gezeigt steht auf der linken und rechten Seite des Gleichheitszeichen jeweils ein Leerzeichen. Wenn mehrere Funktionsaufrufe und damit Variablenzuweisungen im Block untereinander stehen, kann, um die Lesbarkeit des Codes zu gewährleisten, davon abgewichen werden:
$kurz = foo($para1);
$langer_name = foo($para2);
===== Definieren von Funktionen =====
Beim Definieren von Funktionen wandern die Argumente mit Default-Werten ans Ende der Deklaration. Funktionsnamen, Argumente und Rückgabewerte sollten selbsterklärend sein. Hier ein Beispiel:
function addition($wert1, $wert2, $wert3 = 0)
{
$ergebnis = $wert1 + $wert2 + $wert3;
return $ergebnis;
}
===== Kommentare =====
Damit auch andere die eventuell vorhanden Bugs in eurem Code fixen können, muss dieser nicht nur übersichtlich, sondern auch verständlich sein. Daher ist der ein oder andere Kommentar unumgänglich. Hier ist der richtige Mittelweg zu wählen. Zu viel Kommentar verschränkt den Blick auf das wesentliche (den Code), zu wenig Kommentar lässt ihn undurchdringbar erscheinen...
Kommentare sollten in der Regel in englisch erfasst werden, so dass der Sourcecode auch von nicht deutschsprachigen Entwicklern gelesen werden kann. Bei der Dokumentation von Klassen, Methoden und Funktionen verwenden wir zur Unterstützung Doxygen. Damit kann eine übersichtliche HTML-Hilfe erstellt werden. Allerdings müssen dazu ein paar Tags innerhalb des Kommentars gesetzt werden. Eine [[de:entwickler:sourcecode-dokumentation|Beschreibung zur Dokumentation mit Doxygen]] ist aber vorhanden.
Kommentare direkt im Sourcecode (keine Funktions- und Methodenbeschreibung) müssen eingerückt werden. So dass sie auf der selben Ebene wie das zu kommentierende Konstrukt stehen. Ein- bis zweizeilige Kommentare werden wie folgt dargestellt:
// This is the first line of a short comment
// This is the second line of a short comment
Wie oben zu sehen ist, sollte auch in Kommentaren von Umlauten abgesehen werden. Erstreckt sich ein Kommentar über mehr als 2 Zeilen sollten Block-Kommentare eingesetzt werden:
/* This comment could be very long ...
* This comment could be very long ...
* This comment could be very long ...
* This comment could be very very very long ... */
Wichtig bei Blockkommentaren sind die * am Anfang der Zeilen. Diese sind nicht notwendig, erleichtern aber den Überblick erheblich und sollten deshalb gesetzt werden.
===== PHP-Code-Tags =====
Man sollte um den PHP-Code herum immer die Tags **** setzen und nicht die Kurzform ** ?>**. Dies ist die einzige Möglichkeit zu gewährleisten, dass der Code auf allen Plattformen auch als PHP-Code interpretiert wird.
===== Header von Dateien =====
Jede Datei des Admidio-Projekts sollte am Anfang der Datei einen DocBlock enthalten. Dieser muss eine kurze Erklärung des PHP-Scripts enthalten. Außerdem sind hier fein säuberlich alle möglichen Übergabewerte des Scripts aufgelistet...
Hier ein Beispiel aus der Datei dates_function.php:
/******************************************************************************
* Verschiedene Funktionen fuer Termine
*
* Copyright : (c) 2004 - 2008 The Admidio Team
* Homepage : http://www.admidio.org
* Module-Owner : Vor- und Nachname des Entwicklers
* License : GNU Public License 2 http://www.gnu.org/licenses/gpl-2.0.html
*
* Uebergaben:
*
* dat_id: ID des Termins, der angezeigt werden soll
* mode: 1 - Neuen Termin anlegen/aendern
* 2 - Termin loeschen
* 4 - Termin im iCal-Format exportieren
* 5 - Frage, ob Termin geloescht werden soll
*
*****************************************************************************/
===== SVN-Vorgaben =====
Wenn Dateien in SVN eingecheckt werden, muss auch eine Commit-Message verfasst werden. Bei einem Bugfix gehört in die Messages auf jeden Fall die zugehörige Bugnummer und eine kurze Beschreibung der verrichteten Tätigkeiten...
===== Namenskonventionen =====
**Klassen**\\
Klassen sollen selbstsprechende Namen erhalten. Kryptische Abkürzungen sollte man wenn möglich vermeiden. Klassen sollten immer mit einem Großbuchstaben beginnen.
**Funktionen**\\
Funktionsnamen sollten im camelStyle (vielen auch als [[http://de.wikipedia.org/wiki/CamelCaps|camelCaps]] oder laOlaStyle bekannt) geschrieben werden. Dies soll heißen, dass der erste Buchstabe klein geschrieben ist und der erste Buchstabe des nächsten Wortes groß.\\
Beispiel:
getSystemData();
**Variablen**\\
Variablen sollten ähnlich den Funktionsnamen im camelStyle (vielen auch als [[http://de.wikipedia.org/wiki/CamelCaps|camelCaps]] oder laOlaStyle bekannt) geschrieben werden. Globale Variablen, die systemweit gelten erhalten ein **g** als Präfix, Übergabevariablen an ein Script erhalten ein **get** bzw. **post** als Präfix, damit immer direkt klar ist, dass der Inhalt der Varialben manipuliert sein kann.\\
Beispiel:
numberRows // Varialbenbezeichnung
gCurrentUser // globale Varialbe
getUserId // Übergabevariable an ein Script
**Konstanten**\\
Bei Konstanten werden alle Buchstaben groß geschrieben und die einlenen Worte innerhalb de Namens durch Unterstriche getrennt.\\
Beispiel:
TBL_ORGANIZATIONS
===== Dateiformate =====
Um die Entwicklung auf verschiedenen Systemen zu gewährleisten muss ein einheitliches Format genutzt werden:
* Zeichensatz **UTF-8**
* Zeilenumbruch **Windows (CRLF)**
Bei UTF-8 ist noch zu beachten, dass der Editor das Byte-Order-Flag (BOM) nicht setzen darf. Dieses Flag dient eigentlich zur genauen Identifizierung des verwendeten UTF Kodierung (UTF-8, UTF-16 oder UTF-32). Verwendet man dieses aber in PHP, so wird es einfach am Scriptanfang im Browser ausgegeben und führt dann auch meistens zu einer Fehlermeldung im Script.
===== Dateinamen =====
* Dateinamen der Scripte müssen immer klein geschrieben werden, da einige Server immer noch so konfiguriert sind, dass sie mit der Großschreibung nicht klar kommen.
* Besteht ein Scriptname aus mehreren Wörtern, so sollten diese durch einen Unterstrich _ getrennt werden\\ Beispiel: **new_user_function.php**
* Das Hauptscript eines Moduls sollte genauso heißen, wie der Modulordner\\ Beispiel: **adm_program/modules/announcements/announcements.php**
===== Gebrauch von Anführungszeichen =====
Alle Strings werden in einfache Anführungszeichen gesetzt. Beispiel:
$array['element'] = $object->getValue('id');
$string = 'example';
Argumente innerhalb von Strings werden in doppelte Anführungszeichen gesetzt. Beispiel:
echo '';
$sql = 'SELECT * FROM '. TBL_TEXT. ' WHERE txt_value = "beispiel" ';
Innerhalb von Javascript sollten dagegen die doppelten Anführungszeichen genutzt werden, damit so wenig wie möglich Zeichen escaped werden müssen. Damit Javascriptcode einfacher zwischen den Scripten kopiert werden kann, sollten wir auch bei reinen Javascript-Dateien die doppelten Anführungszeichen nehmen.
echo '';
Ausnahmen zu diesen Regeln ist Javasciptcode direkt in HTML-Attributen. Dort müssen die einfachen Anführungszeichen (escaped) genommen werden, da ansonsten das Attribut beendet wird.
echo 'Html-Code';
===== Vergleichsoperatoren =====
Beim Vergleich des Inhalts von Variablen sollten diese so gewählt werden, dass auch der Typ (integer/string) mit geprüft wird. Dies erreicht man, indem man gleich mit **===** oder ungleich mit **!==** angibt.
if($a == $b) // prüft nur ob der Inhalt gleich ist. "Test" == Test > true
if($a === $b) // prüft ob auch der Typ gleich ist. "Test" === Test > false
// "Test" === "Test" > true
if($a != $b) // prüft nur ob der Inhalt ungleich ist. "Test" != Test2 > true
if($a !== $b) // prüft ob auch der Typ gleich ist. "Test" !== Test > false
// "Test2" !== "Test" > true