Inhaltsverzeichnis
Anleitung für Entwickler
Referenzhandbuch
Das Yana-Framework bietet eine API zum Arbeiten mit Datenbanken, welche auf PEAR-DB basiert. Diese API erweitert die Fähigkeiten von PEAR um folgende Features:
Es gibt einige Features welche die FlatFile-Datenbank zur Zeit nicht unterstützt, die aber für eine zukünftige Version geplant sind.
Es gibt einige Features welche in Datenbankschemata zur Zeit nicht unterstützt werden, aber für zukünftige Versionen geplant sind.
Voraussetzung ist eine Schemadatei. Die Schemadateien müssen sich im Verzeichnis "config/db/" befinden und die Dateiendung ".config" besitzen.
Die Verbindungsdaten für die Datenbank (wie Hostadresse, Nutzername und Passwort) werden vom Nutzer im Administrationsmenü eingegeben. Sie müssen diese im Quellcode NICHT angeben.
Wenn Sie keine Strukturdatei verwenden möchten, können Sie diese Angabe frei lassen. Dies wird jedoch in einer Produktionsumgebung nicht empfohlen. In diesem Fall wird das Framework versuchen, die Angaben selbst zu ermitteln. Falls dies fehlschlägt ist die Datenbankverbindung nicht nutzbar.
Wenn Sie eine Verbindung mit einer Datenbank herstellen, aber die Verbindungsdaten selbst angeben wollen, dann gehen Sie wie folgt vor:
Dazu bietet die API die Funktion $db->get(string $key). Diese führt eine Select-Anfrage auf der Datenbank aus und liefert den Wert an der Stelle zurück, welche mit dem Argument $key angegeben wurde.
global $YANA;
$db = $YANA->connect("guestbook"); /* Es gilt folgende Syntax: $db->get( string "$tabelle.$zeile.$spalte", string $where, string $order_by, int $offset, int $limit ); Beispiel: $value = $db->get("table.1.field","row1=wert1,row2=wert2","order by row1",0,1); erzeugt folgende SQL-Anfrage: SELECT field from table where primary_key = "1" and row1 like '%wert1%' and row2 like '%wert2%' order by row1 limit 1; */ /* Feld ausgeben */ $value = $db->get("table.1.field"); /* erzeugt folgende SQL-Anfrage: SELECT field from table where primary_key = "1"; */ /* Spalte ausgeben: */ $column = $db->get("table.*.field"); foreach ($column as $row => $value) { print "<p>Value of 'field' in row '$row' = $value</p>"; } /* erzeugt folgende SQL-Anfrage: SELECT field from table; */ /* Zeile ausgeben: */ $row = $db->get("table.2"); foreach ($row as $column => $value) { echo "<p>Value of column '$column' in row '2' = $value</p>"; } /* erzeugt folgende SQL-Anfrage: SELECT * from table where primary_key = "2"; */ /* Tabelle ausgeben: */ $table = $db->get("table"); foreach ($table as $index => $row) { foreach ($row as $column => $value) { echo "<p>Value at 'table.$index.$column' = $value</p>"; } } /* erzeugt folgende SQL-Anfrage: SELECT * from table; */
Dazu verwenden Sie die Funktion $db->insert($key,$value). Diese fügt den Wert „value“ an der Stelle „key“ ein. Dabei kann es sich entweder um eine Zeile oder eine Tabellenzelle handeln. Das Einfügen von ganzen Tabellen oder Spalten ist nicht möglich.
Beim ersten Aufruf der Funktion wird automatisch eine Transaktion gestartet. Benutzen Sie die Funktion $db->write() um ein COMMIT der Daten auszulösen. Wenn eine der Anweisungen in der Transaktion fehlschlägt, wird automatisch ein CALLBACK ausgeführt.
Falls die Zeile nicht existiert, wird ein die SQL-Anweisung „insert“ benutzt, sonst „update“.
Die Funktion gibt bei Erfolg „true“ zurück und „false“ sonst.
Bitte beachten Sie: die SQL-Anweisung wird erst ausgeführt, wenn die Funktion $db->write() aufgerufen wird.
Im Folgenden einige Beispiele:
global $YANA;
$db = $YANA->connect("guestbook"); /* Neue Zeile einfügen: */ $db->insert("table.*",array("row1"=>"wert1","row2"=>"wert2")); $db->write(); /* Zeile aktualisieren: */ $db->insert("table.2",array("row1"=>"wert1","row2"=>"wert2")); $db->write(); /* Zelle aktualisieren: */ $db->insert("table.2.row1","wert1"); $db->write(); /* Transaktion durchführen: */ $db->insert("table.*",array("row1"=>"wert1","row2"=>"wert2")); $db->insert("table.*",array("row1"=>"wert3","row2"=>"wert4")); $db->insert("table.1.row3","wert1"); $db->write();
Dazu verwenden Sie die Funktion $db->remove($key). Diese löscht den Datensatz an der Adresse „key“ aus der Tabelle. Die Funktion gibt bei Erfolg „true“ zurück und „false“ sonst. Es können nur Datensätze gelöscht werden. Keine Tabellen, Zellen oder Spalten.
Beachten Sie folgende Beschränkung: aus Sicherheitsgründen wird pro Aufruf stets maximal 1 Datensatz gelöscht. Wenn Sie mehrere Datensätze löschen wollen, müssen Sie die Funktion mehrmals aufrufen. Diese Einschränkung soll verhindern, dass jemand durch Unachtsamkeit oder aus einem Versehen eine gesamte Tabelle löschen kann.
Bitte beachten Sie: die SQL-Anweisung wird erst ausgeführt, wenn die Funktion $db->write() aufgerufen wird.
global $YANA;
$db = $YANA->connect("guestbook"); /* Die zweite Zeile löschen: */ $db->remove("table.2"); $db->write(); /* erzeugt folgende SQL-Anfrage: DELETE FROM table WHERE primary_key = "2" LIMIT 1; */ /* Die ganze Tabelle "table" löschen: */ for ($i=0; $i < $db->length($table); $i++) { $db->remove("table.*"); } $db->write(); /* erzeugt folgende SQL-Anfrage: DELETE FROM table WHERE primary_key = "2" LIMIT 1; */
global $YANA;
$db = $YANA->connect("guestbook"); if ($db->length("table") === 0) { print "Die Tabelle 'table' ist leer."; } else { print "Die Tabelle 'table' enthält ".$db->length("table")." Datensätze."; }
global $YANA;
$db = $YANA->connect("guestbook"); /* Datenbankverbindung prüfen: */ if ($db->exists() === true) { print "Die Datenbankverbindung ist verfügbar."; } else if ($db->exists() === false) { print "Die Datenbankverbindung ist NICHT verfügbar"; } /* Prüfen ob Tabelle existiert: */ if ($db->exists("table") === true) { print "Die Tabelle 'table' existiert."; } else if ($db->exists("table") === false) { print "Es gibt keine Tabelle mit dem Namen 'table'."; } /* Prüfen ob Datensatz existiert: */ if ($db->exists("table.2") === true) { print "Der Datensatz '2' in der Tabelle 'table' existiert."; } else if ($db->exists("table.2") === false) { print "Es gibt keinen Datensatz '2' in der Tabelle 'table'."; } /* Prüfen ob Feld existiert und einen Wert hat: */ if ($db->exists("table.2.field") === true) { print "Das Feld 'field' im Datensatz '2' in Tabelle 'table' hat einen Wert."; } else if ($db->exists("table.2.field") === false) { print "Das Feld 'field' im Datensatz '2' in Tabelle 'table' existiert nicht oder ist NULL."; } /* Prüfen ob mindestens 1 Feld existiert, dass NOT NULL ist: */ if ($db->exists("table.*.field") === true) { print "Die Spalte 'field' in Tabelle 'table' existiert."; } else if ($db->exists("table.*.field") === false) { print "Die Spalte 'field' in Tabelle 'table' existiert nicht oder alle Werte sind NULL."; }
YANA hat eine Installationsroutine für Datenbanken, welche Sie im Administrationsmenü, in der Basiskonfiguration im Menü "Datenbank Setup" finden. Über dieses Menü kann ein Nutzer alle Tabllen installieren oder Inhalte zwischen dem DBMS und der FlatFile-Datenbank synchronisieren.
Sie können diese Installationsroutine mit eigenen Einträgen "bestücken". Kopieren Sie dazu Ihr Datenbankschema in das Verzeichnis "config/db/". Die SQL-Dateien mit den erforderlichen DDL-Statements für jedes DBMS, welches Sie unterstützen wollen, speichern Sie im Verzeichnis "config/db/.install/". Dort finden Sie verschiedene Unterverzeichnisse für verschiedene Datenbankhersteller, in welchen Sie Ihre Installationsdateien ablegen können. Sie finden dort außerdem eine Datei "readme.txt", welche eine Liste der unterstützten DBMS und den Namen der Verzeichnisse enthält.
Selbstverständlich sollten Sie Ihre SQL-Dateien stets mit dem jeweiligen DBMS testen, bevor Sie diese veröffentlichen ;-)
Für zukünftige Versionen ist geplant, die erforderlichen DDL-Statements direkt aus dem Schema der Datenbank zu generieren. Die SQL-Dateien wären dann nur noch eine optionale Ergänzung.
global $YANA;
$db = $YANA->connect("guestbook"); $db->importSQL('data.sql');
global $YANA;
$db = $YANA->connect("guestbook"); $csv = $db->toString("table"); file_put_contents("table.csv", $csv);
global $YANA;
$db = $YANA->connect("guestbook"); $db->exportStructure("guestbook.config");
Schema-Dateien haben die Endung "*.config" und werden im Verzeichnis "config/db/" gespeichert. Eine Verbindung auf Grundlage einer Schema-Datei wird hergestellt über den PHP-Code: $YANA->connect("Name der Datei ohne Dateiendung");
Das folgende Listing zeigt ein Schema mit allen Elementen und alle gültigen Belegungen. Existieren mehrere mögliche Varianten, dann sind diese die verschiedenen Möglichkeiten durch eine Pipe '|' voneinander getrennt. Bezeichner, die frei gewählt werden können, sind im Text fett hervorgehoben.
/* Das Feld "USE_STRICT" legt fest, ob Queries zur Laufzeit * gegen das Schema validiert werden oder nicht. */ <USE_STRICT>true|false</USE_STRICT> /* Das Feld "READONLY" ist optional. Default = false */ <READONLY>true|false</READONLY> /* Constraints sind boolsche Ausdrücke in PHP-Syntax. * Sie können mit einer bestimmten SQL-Aktion verknüpft werden. * Ergibt der Ausdruck "false" wird die entsprechende Query nicht * abgeschickt und ein Log-Eintrag geschrieben. Andernfalls wird die * Aktion fortgesetzt. * * In Constraints können Sie keine Funktionen aufrufen, mit einer einzigen * Ausnahme: preg_match(); * Außerdem haben Sie Zugriff auf folgende Konstanten: * $VALUE = (für INSERT, UPDATE) Wert der eingefügt wird * $PERMISSION = Zugriffslevel des Nutzers, der die Aktion ausgelöst hat * $OPERATION = SQL-Kommando das gerade durchgeführt wird (SELECT, INSERT, ...) * $TABLE = Name der Zieltabelle (meist die aktuelle Tabelle) * $FIELD = Name der Zielspalte (falls angegeben) * * Beispiele: * <SELECT>true</SELECT> * <UPDATE>false</UPDATE> * <UPDATE>$VALUE > 0 && $VALUE < 500</UPDATE> * <INSERT>$PERMISSION > 50</INSERT> * <INSERT>preg_match('/^[\w\d-_]*$/i', $VALUE)</INSERT> * * Constraints gibt es in YANA seit Version 2.8 . */ <CONSTRAINT> <SELECT>PHP-Code</SELECT> <INSERT>PHP-Code</INSERT> <UPDATE>PHP-Code</UPDATE> <DELETE>PHP-Code</DELETE> </CONSTRAINT> /* Wie Sie vielleicht schon vermutet haben: die Option READONLY=true * und der Constraint UPDATE=false haben beide den gleichen Effekt. */ /* Hier folgt die Definition der Tabellen. */ <TABLES> <Name der Tabelle> <READONLY>true|false</READONLY> <CONSTRAINT> <SELECT>PHP-Code</SELECT> <INSERT>PHP-Code</INSERT> <UPDATE>PHP-Code</UPDATE> <DELETE>PHP-Code</DELETE> </CONSTRAINT> /* Im Feld "PRIMARY_KEY" ist der Name der Spalte anzugeben, welche den Primärschlüssel enthält. */ <PRIMARY_KEY>Name der Spalte</PRIMARY_KEY> /* Im Feld "FOREIGN_KEY" kann eine Liste von Fremdschlüsseln angegeben werden. */ <FOREIGN_KEY> <Name der Zieltabelle>Name der Spalte</Name der Zieltabelle> <andere Zieltabelle>andere Spalte</andere Zieltabelle> </FOREIGN_KEY> /* Hier folgt die Definition der Tabellenspalten. */ <CONTENT> <Name der Spalte> <READONLY>true|false</READONLY> <CONSTRAINT> <SELECT>PHP-Code</SELECT> <INSERT>PHP-Code</INSERT> <UPDATE>PHP-Code</UPDATE> <DELETE>PHP-Code</DELETE> </CONSTRAINT> /* Im Feld "DESCRIPTION" kann ein Beschriftung für diese Spalte angegeben werden. * Sie können hier auch %TOKEN% verwenden, welche Sie zum Beispiel in Ihrem Programm, * oder als Sprachdatei festlegen, um eine Beschriftung in mehreren Sprachen anbieten * zu können. */ <DESCRIPTION>Label der Spalte</DESCRIPTION> /* Die primitiven, skalaren Datentypen "integer", "float" und "string" * entsprechen ihrem Äquivalent in PHP. Zusätzlich wurden weitere nützliche Datentypen * eingeführt. * mail = prüft beim Eintragen automatisch, ob der Wert eine gültige Mailadresse ist * ip = prüft beim Eintragen automatisch, ob der Wert eine gültige IP-Adresse ist * text = für Eingaben aus Textarea-Feldern, führt automatisch zusätzliche Prüfungen * zum Schutz vor Flooding durch * select = ein Aufzählungsdatentyp, dessen Elemente im Feld "DEFAULT" definiert werden, * siehe unten. * array = kann verwendet werden, um PHP-Arrays zu speichern. Diese werden beim Auslesen * des Wertes aus der Datenbank automatisch wieder umgewandelt. */ <TYPE>integer|float|string|text|url|ip|mail|time|select|array</TYPE> <LENGTH>positive integer</LENGTH> /* Das Feld "REQUIRED" legt fest ob ein Feld NULLABLE ist oder nicht. */ <REQUIRED>true|false</REQUIRED> /* Das Feld "DEFAULT" legt einen Wert fest, der automatisch verwendet wird, wenn beim * Anlegen des Datensatzes keine anderen Angaben gemacht werden. */ <DEFAULT>ein Defaultwert</DEFAULT> /* Die Anweisungen für die GUI und das SDK können im Feld "DISPLAY" angegeben werden. * Dazu existieren jeweils zwei Einstellungen: "HIDDEN" und "READONLY". * Wobei "READONLY" bedeutet, dass diese Spalte nicht zum Editieren angezeigt werden soll. * Wie der Name schon sagt, bedeutet "HIDDEN", dass die Spalte in der Ausgabe gar nicht * auftauchen soll. * Es gibt jeweils eine Einstellung, für die Abfragen: "NEW", "EDIT", "VIEW" und "SEARCH". * Die Eigenschaften können jeweils global oder für jede Aktion einzeln gesetzt werden. */ /* Zunächst die Variante mit globalen Einstellungen */ <DISPLAY> <HIDDEN>true|false</HIDDEN> <READONLY>true|false</READONLY> </DISPLAY> /* Nun die Variante mit lokalen Einstellungen für jede Option */ <DISPLAY> <HIDDEN> <NEW>true|false</NEW> <EDIT>true|false</EDIT> <SELECT>true|false</SELECT> <SEARCH>true|false</SEARCH> </HIDDEN> <READONLY> <NEW>true|false</NEW> <EDIT>true|false</EDIT> </READONLY> </DISPLAY> </Name der Spalte> /* * Für die Datentypen integer, ip und time kann für das Feld "REQUIRED" der Wert "AUTO" * gesetzt werden. Dies bedeutet, dass der Wert automatisch erzeugt wird. * Für time = das aktuelle Datum als Unix-Timestamp * Für ip = die IP des Besuchers * Für integer = autoincrement beziehungsweise der Wert einer Sequence */ <Name der Spalte> <TYPE>integer|ip|time</TYPE> <REQUIRED>AUTO</REQUIRED> </Name der Spalte> /* * Für den Datentyp select kann eine Aufzählung der erlaubten Werte angegeben werden. * * Die Semantik kann man sich relativ leicht merken: * + Die GUI stellt Spalten vom Typ select in Formularen als Select-Feld dar. * + Die Darstellung im Schema erinnert ebenfalls an ein Select-Formularfeld in HTML. */ <Name der Spalte> <TYPE>select</TYPE> <DEFAULT> <defaultwert>Beschriftung</defaultwert> <option 1>Beschriftung 1</option 1> <option 2>Beschriftung 2</option 2> </DEFAULT> </Name der Spalte> </CONTENT> </Name der Tabelle> /* Hier können weitere Tabellen folgen. */ </TABLES>
Im Folgenden ein Beispiel für eine Datenbank. Dargestellt ist die Datenstruktur der Gästebuch-Anwendung:
<USE_STRICT>true</USE_STRICT> <READONLY>false</READONLY> <TABLES> <guestbook> <PRIMARY_KEY>guestbook_id</PRIMARY_KEY> <CONTENT> <guestbook_id> <TYPE>integer</TYPE> <LENGTH>5</LENGTH> <DEFAULT>Id (PK)</DEFAULT> <DISPLAY> <HIDDEN>true</HIDDEN> </DISPLAY> </guestbook_id> <profile_id> <TYPE>string</TYPE> <LENGTH>128</LENGTH> <REQUIRED>AUTO</REQUIRED> <DEFAULT>Id (FK)</DEFAULT> <DISPLAY> <HIDDEN>true</HIDDEN> </DISPLAY> </profile_id> <guestbook_ip> <TYPE>ip</TYPE> <LENGTH>15</LENGTH> <REQUIRED>AUTO</REQUIRED> <DISPLAY> <HIDDEN>true</HIDDEN> </DISPLAY> </guestbook_ip> <guestbook_name> <TYPE>string</TYPE> <LENGTH>128</LENGTH> <REQUIRED>true</REQUIRED> <DESCRIPTION>Name</DESCRIPTION> </guestbook_name> <guestbook_message> <TYPE>text</TYPE> <LENGTH>3000</LENGTH> <REQUIRED>true</REQUIRED> <DESCRIPTION>Text</DESCRIPTION> </guestbook_message> <guestbook_mail> <TYPE>mail</TYPE> <LENGTH>255</LENGTH> <DESCRIPTION>Mail</DESCRIPTION> </guestbook_mail> <guestbook_homepage> <TYPE>string</TYPE> <LENGTH>512</LENGTH> <DESCRIPTION>Homepage</DESCRIPTION> </guestbook_homepage> <guestbook_messenger> <DESCRIPTION>Messenger</DESCRIPTION> <TYPE>string</TYPE> <LENGTH>255</LENGTH> </guestbook_messenger> <guestbook_msgtyp> <DESCRIPTION>Typ</DESCRIPTION> <TYPE>select</TYPE> <LENGTH>5</LENGTH> <DEFAULT> <icq>ICQ</icq> <aol>AOL</aol> <yahoo>Yahoo!</yahoo> <msn>MSN</msn> </DEFAULT> </guestbook_msgtyp> <guestbook_opinion> <TYPE>select</TYPE> <LENGTH>1</LENGTH> <CONSTRAINT> <INSERT>$VALUE >= 0 && $VALUE <= 5</INSERT> <UPDATE>$VALUE >= 0 && $VALUE <= 5</UPDATE> </CONSTRAINT> <DEFAULT> <0>unentschlossen</0> <1>sehr gut</1> <2>gut</2> <3>befriedigend</3> <4>ausreichend</4> <5>ungenügend</5> </DEFAULT> <DESCRIPTION>Meinung</DESCRIPTION> </guestbook_opinion> <guestbook_date> <TYPE>time</TYPE> <REQUIRED>AUTO</REQUIRED> <DESCRIPTION>Datum/Zeit</DESCRIPTION> <DISPLAY> <HIDDEN> <NEW>true</NEW> </HIDDEN> </DISPLAY> </guestbook_date> <guestbook_comment> <TYPE>text</TYPE> <LENGTH>1024</LENGTH> <REQUIRED>false</REQUIRED> <DESCRIPTION>Kommentar</DESCRIPTION> <DISPLAY> <READONLY> <EDIT>true</EDIT> </READONLY> </DISPLAY> </guestbook_comment> <guestbook_is_registered> <TYPE>integer</TYPE> <LENGTH>1</LENGTH> <REQUIRED>AUTO</REQUIRED> <DEFAULT>0</DEFAULT> <DISPLAY> <HIDDEN>true</HIDDEN> </DISPLAY> </guestbook_is_registered> </CONTENT> </guestbook> </TABLES>
Die Funktion dirlist() liefert für ein Verzeichnis eine sortierte Liste der enthaltenen Dateien und Verzeichnisse als numerisches Datenfeld zurück. Die obligatorischen Verzeichniseinträge „.“ und „..“ werden nicht aufgelistet. Dateien, deren Dateinamen mit dem Zeichen „.“ beginnen werden ebenfalls nicht aufgelistet. Das betrifft insbesondere Dateinamen wie „.htaccess“ oder „.password“. Die Dateinamen enthalten keine Pfadangaben. Verzeichnisnamen enthalten keinen abschließenden Querstrich „/“.
Der optionale Parameter $filter kann verwendet werden um die Ausgabe auf bestimmte Dateiendungen zu beschränken. Wildcards sind nicht gestattet. Der Dateifilter darf lediglich alphanumerische Zeichen, sowie die Zeichen '.', '-' und '_' enthalten. Andere Zeichen werden beim Aufruf der Funktion automatisch entfernt.
/* alle Einträge eines Verzeichnisses ausgeben */ echo implode("<br>", dirlist("foo/")); /* Ausgabe: foo1.foo2 foo3.foo2 foo4.foo5 foo6.foo7 */
/* alle Einträge mit passender Dateiendung ausgeben */ echo implode("<br>", dirlist('foo/', '*.foo2')); /* Ausgabe: foo1.foo2 foo3.foo2 */ /* ... mit mehreren Dateiendungen */ echo implode("<br>", dirlist('foo/', '*.foo2|*.foo5')); /* Ausgabe: foo1.foo2 foo3.foo2 foo4.foo5 */ /* objektorientierte Variante */ $dirStream = new DirStream("foo/"); $dirStream->read(); $dirlist = $dirStream->dirlist('*.foo2|*.foo5'); echo implode("<br>", $dirlist); /* Hinweis: das Setzen des Dateifilters ist permanent. */ $dirStream->dirlist('*.foo2|*.foo5'); echo $dirStream->length(); /* Ausgabe: 2 */ echo count($dirStream->get()); /* Ausgabe: 2 */ /* Ein erneuter Aufruf von dirlist() setzt den Dateifilter neu */ $dirStream->dirlist(""); echo $dirStream->length(); /* Ausgabe: 4 */
Die Funktionen $dirStream->create($mode) beziehungsweise $dirStream->delete() sind für Erzeugen beziehungsweise Löschen von Verzeichnissen verantwortlich. Der optionale Parameter $mode kann verwendet werden, um unter LINUX/UNIX -Betriebssystemen Zugriffsrechte von Verzeichnissen festzulegen. Der Defaultwert ist 777.
Beispiele für gültige Werte für $mode finden Sie in der folgenden Tabelle. Dabei steht „r“ für „readable“, „w“ für „writeable“ und „x“ für „executeable“.
Besitzer | Gruppe | sonstige Nutzer | Wert |
---|---|---|---|
rwx |
rwx |
rwx |
777 |
rw- |
rw- |
--- |
660 |
rw- |
rw- |
rw- |
666 |
rwx |
r-x |
r-x |
755 |
rwx |
r-x |
--- |
750 |
rwx |
--- |
--- |
700 |
Beispiele für gültige Werte (entsprechend Unix: CHMOD)
$dirStream = new DirStream("foo/"); $dirStream->read(); /* erzeuge das Verzeichnis "foo/" */ $dirStream->create(); /* erzeuge das Verzeichnis "foo/" mit Zugriffsrechten 660 */ $dirStream->create(660); /* Anzahl der Dateien in einem Verzeichnis feststellen */ print "Verzeichnis 'foo/' enthält ".$dirStream->length()." Dateien."; /* lösche das Verzeichnis "foo/" */ $dirStream->delete(); /* lösche das Verzeichnis "foo/" inklusive aller Dateien und Unterverzeichnisse */ $dirStream->delete(true); /* prüfe ob Verzeichnis existiert */ $test = $dirStream->exists(); if ($test === true) { print "Verzeichnis existiert"; } else if ($test === false) { print "Verzeichnis existiert NICHT"; }
Die Funktion getConfigFile() lädt die angegebene Konfigurationsdatei im SML-Format und liefert den Inhalt als PHP-Variable zurück.
/* Lies Inhalte von Datei und gib Inhalte als Array zurück */ $array = getConfigFile("foo.config"); /* Schlüssel in Großbuchstaben (default) */ $array = getConfigFile("foo.config", CASE_UPPER); /* Schlüssel in kleinen Buchstaben */ $array = getConfigFile("foo.config", CASE_LOWER); /* Schlüssel in gemischter Schreibweise */ $array = getConfigFile("foo.config", CASE_MIXED); /* objektorientierte Variante, gemischte Schreibweise */ $configFile = new ConfigFile("foo.config"); $configFile->read(); $array = $configFile->get(); /* objektorientierte Variante, Schlüssel in Großbuchstaben */ $smlFile = new SmlFile("foo.config"); $smlFile->read(); $array = $smlFile->get(); /* Navigieren innerhalb einer SML-Datei Angenommen die Datei "foo.config" hätte folgenden Inhalt: <ROOT> <FOO1> <FOO2>text</FOO2> <FOO3> <0>1</0> <1>foo</1> </FOO3> </FOO1> </ROOT> */ $mixed = $smlFile->get("ROOT.FOO1"); print_r($mixed); /* Diese Abfrage liefert den Teilbaum ROOT.FOO1 mit FOO1 als Wurzelement. Ausgabe: array( "FOO2" => "text", "FOO3" => array ( 0 => 1, 1 => "foo" ) ) */
Die Funktion makeConfig() erzeugt für die übergebene Variable eine Darstellung als SML-Code und liefert diesen als String zurück. Es muss sich entweder um eine Variable mit einem skalaren Wert oder ein Array handeln.
Bitte beachten Sie: die Funktion „makeConfig“ erkennt keine unendlichen Rekursionen. Daher müssen die Datenfelder rekursionsfrei sein. Andernfalls wird durch den Compiler eine Fehlermeldung erzeugt.
/* Speichert die Einträge eines Array in der Datei "foo.config" */ $string = makeConfig($array, "ROOT"); file_put_contents("foo.config", $string); /* ersetzen Sie "ROOT" durch den Namen des Wurzelelements */ /* Benutzen von Großbuchstaben, Kleinbuchstaben und gemischter Schreibweise analog zu getConfigFile() */ $string = makeConfig($array, "ROOT", CASE_UPPER); // groß (default) $string = makeConfig($array, "ROOT", CASE_LOWER); // klein $string = makeConfig($array, "ROOT", CASE_MIXED); // gemischt /* objektorientierte Variante, gemischte Schreibweise */ $configFile = new ConfigFile("foo.config"); $configFile->read(); $configFile->create(); $configFile->insert($string); $configFile->write(); /* objektorientierte Variante, Schlüssel in Großbuchstaben */ $smlFile = new SmlFile("foo.config"); $smlFile->read(); $smlFile->create(); $smlFile->insert($string); $smlFile->write();
Das YANA bietet die Möglichkeit persistente Zählervariablen, also solche deren Wert automatisch gespeichert wird, zu verwenden.
Es gibt zwei Arten von Zählervariablen: solche, die mit IP-Check, welche nur dann zählen, wenn der Nutzer mit der aktuellen IP nicht innerhalb der letzten 3 Stunden eine Veränderung des Zählers bewirkt hat. Und solche ohne IP-Check, welche stets weiter zählen wenn Sie aufgerufen werden.
Im Folgenden einige Beispiele.
/* Erzeuge einen Zähler mit IP-Check */ $counter = new Counter("meine_statistiken", YANA_COUNTER_USE_IP); /* ... oder auch: */ $counter = new Counter("meine_statistiken"); /* Erzeuge einen Zähler ohne IP-Check */ $counter = new Counter("meine_statistiken", YANA_COUNTER_IGNORE_IP); /* Den Zähler "test1" um 1 erhöhen */ $counter->count("test1"); /* Den Zähler "test2" um 1 erhöhen und eine Beschreibung der Änderung speichern */ $counter->count("test2", "Bewertung"); /* Den Zähler "test1" um 3 erhöhen */ $counter->count("test1", "Bewertung", 3); /* Den Zähler "test1" um 2 verringern */ $counter->count("test1", "Bewertung", -2);
$counter = new Counter("meine_statistiken"); /* Den Zählerstand von "test1" abfragen */ $int = $counter->getCount("test1"); /* Die Beschreibung von Zähler "test1" abfragen */ $string = $counter->getInfo("test1"); print $string.":\t".$int; /* Ausgabe Bewertung: 2 */ /* Alle Zähler abfragen */ $array = $counter->getCount("*"); foreach ($array as $a => $b) print $a.":\t".$b;
/* In der Template-Datei fügen Sie folgendes ein: */ <img src=[%"action=graphic_counter&target=0"|href%]>
Mit dem Parameter "target" wählen Sie die Grafik aus. Gültige Werte sind die Zahlen 0-6.
Wert für Target | Darstellung |
---|---|
0 | ![]() |
1 | ![]() |
2 | ![]() |
3 | ![]() |
4 | ![]() |
5 | ![]() |
6 | ![]() |
Versionsinformation: Die Funktionen send_mail und form_mail, sowie die Klasse form_mailer wurden in Version 2.8 umbenannt in sendMail, formMail und formMailer, um der Namenskonvention des Frameworks zu entsprechen. Die Funktion sendMail ist ab Version 2.8 eine statische Funktion der Klasse Mailer. Die Funktion formMail ist ab Version 2.8 eine statische Funktion der Klasse FormMailer.
YANA bietet die Funktion Mailer::mail() zum Versand von Mails, welche Reihe von Sicherheitsvorkehrungen implementiert, welche vor verschiedenen Arten von Header-Injection schützen.
Die Funktion „Mailer::mail“ ist eine gegen Missbrauch und „Header-Injection“ abgesicherte Variante der nativen PHP-Funktion „mail“. Anders als „mail“ werden alle Eingabedaten geprüft und auch nicht alle Header-Informationen, welche „mail“ prinzipiell gestattet sind erlaubt.
Es wird „true“ zurückgegeben, wenn die Mail versandt werden konnte, „false“ sonst. Der Wert „true“ bedeutet jedoch nicht, dass die Mail erfolgreich zugestellt wurde. Er bedeutet lediglich, dass die Eingabedaten im Sinne dieser Funktion syntaktisch korrekt waren.
Die Funktion erzeugt im Header der Mail die zusätzlichen Einträge „x-yana-php-header-protection“ und „x-yana-php-spam-protection“.
Wenn Sie eine Mail empfangen, die über YANA versendet wurde, können Sie im Header der Mail die entsprechenden Einträge prüfen, um zu sehen ob das Framework im Nachrichtentext Unregelmäßigkeiten entdeckt hat.
Aus Sicherheitsgründen gelten folgende Einschränkungen.
Empfänger: $recipient
Der Parameter muss eine
gültige Mailadresse sein gemäß des
regulären
Ausdrucks
(Perl-Syntax)
/^[äöüß\w\d-_\.]{1,}\@[äöüß\w\d-_\.]{2,}\.[\w\d-_\.]{2,}$/i
Betreff: $subject
Alle Sonderzeichen außer
„()äÄüÜöÖß[]“,
alle Tags
sowie alle Zeilenumbrüche werden still (ohne Warnung)
entfernt.
Bei einer Länge von mehr als 128 Zeichen werden alle
nachfolgenden Zeichen still entfernt.
Nachrichtentext: ($text)
Alle '@'-Zeichen werden still durch die
Zeichenkette „[at]“ ersetzt. Bei Textnachrichten
erfolgt ein
automatischer Zeilenumbruch nach 70 spätestens Zeichen. Bei
HTML-Nachrichten werden einige potentiell gefährliche Tags
still entfernt (Blacklist-Ansatz).
Header: $header
Dieser Parameter ist ein assoziatives
Datenfeld. Es darf beliebige X-Header-Daten enthalten, sowie einige
unkritische Header-Informationen (Whitelist-Ansatz).
Die Liste der von Header akzeptierten Parameter lautet:
Parameter | Typ | Default | Beschreibung |
---|---|---|---|
from |
|
n/a |
Eine gültige Mailadresse |
return-path |
|
n/a |
Eine gültige Mailadresse |
cc |
mixed |
n/a |
Entweder eine gültige Mailadresse oder ein numerisches Datenfeld mit mehreren Mailadressen. An alle angegebenen Adressen wird eine Kopie der Nachricht versandt. Anders als bei „bcc“ ist die Liste der Empfänger jedoch für alle Empfänger sichtbar. |
content-type |
string |
text/plain; |
Bestimmt den MIME-Type der Nachricht. Nur MIME-Type und Charset sind als Eingaben erlaubt. Andere Werte werden ignoriert. |
mime-version |
float |
1.0 |
Angabe muss entsprechend folgendes regulären Ausdrucks erfolgen (Perl-Syntax): /^\d\.\d$/ |
content-transfer-encoding |
string |
n/a |
Angabe muss entsprechend folgendes regulären Ausdrucks erfolgen (Perl-Syntax): /^\d{,2}bit$/i |
gültige Werte für Parameter header Funktion Mailer::mail
Die Verwendung von „BCC“ ist aus Sicherheitsgründen nicht gestattet.
Anmerkung: vor dem Versand der E-Mail prüft die Funktion $mailer->send() die Eingabedaten automatisch auf Versuche von Header-Injection und säubert alle Eingaben. Es kann jedoch absolut nichts schaden, wenn Sie die Syntax der Eingabedaten trotzdem auch in Ihrem Skript noch einmal überprüfen bevor Sie die Funktion aufrufen.
Zu diesem Zweck bietet Ihnen YANA die Funktion untaintInput().
Die Funktion verfügt über folgende Parameter:
Parameter |
Typ |
Default |
Beschreibung |
---|---|---|---|
value |
mixed |
n/a |
zu säuberndes Datum |
type |
string |
„“ |
Datentyp Neben den von PHP unterstützten nativen Typen sind noch folgende Werte erlaubt:
|
length |
integer |
0 |
Maximale Länge des Datums |
escape |
integer |
0 |
siehe Tabelle |
Parameterliste untaintInput
Der Parameter $escape kann mit einer der folgenden Konstanten belegt werden.
Bezeichner |
Beschreibung |
---|---|
YANA_ESCAPE_NONE |
keine Änderungen durchführen (Default) |
YANA_ESCAPE_SLASHED |
wandelt einfache und doppelte Anführungszeichen in ihre entsprechenden Escapesequenzen in C-Syntax um |
YANA_ESCAPE_TOKEN |
ersetzt enthaltene Token durch ihre HTML-Entities |
YANA_ESCAPE_CODED |
ersetzt HTML-Symbole, beispielsweise Tagklammern, durch Entities |
YANA_ESCAPE_LINEBREAK |
wandelt alle Whitespace-Zeichen (insbesondere Zeilenumbrüche) in Leerzeichen um |
YANA_ESCAPE_USERTEXT |
zur Behandlung von Text aus Textarea-Feldern |
Gültige Belegungen für den Parameter $escape der Funktion untaintInput
Für INPUT-Felder sollten Sie stets die Funktion untaintInput() mit dem Parameter YANA_ESCAPE_LINEBREAK aufrufen. Das verhindert, dass ein Angreifer Zeilenumbrüche in Ihre Ausgabe schmuggelt. Für TEXTAREA-Felder sollten Sie den Parameter YANA_ESCAPE_USERTEXT verwenden. Dieser verhindert viele Formen von Flooding, indem Zeichenfolgen die sich ständig wiederholen (Copy'n'Paste Flooding) entfernt werden, oder zum Beispiel ellenlange Texte oder Leerzeichen nach einer bestimmten Anzahl von Leerzeichen per Zwang umgebrochen werden, um das Layout Ihrer Seite nicht zu zerstören.
YANA erzeugt eine eigene Log-Datei "yana.log" im Verzeichnis "cache/". Diese Datei wird aber nur geschrieben, wenn Logging aktiviert ist. Dieses Feature ist nach der Installation per Default deaktiviert.
Melden Sie sich als Administrator an und öffnen Sie das Administrationsmenü im Expertenmodus.
Öffnen Sie das "Programmsetup".
Aktivieren Sie die Option "Protokollierung".
Speichern Sie die Änderungen
Durch Aufruf von $YANA->message($STATE, $ERR_CODE [, $REDIRECT]) kann eine Textmeldung erzeugt werden.
DIESER BEFEHL UNTERBRICHT DIE PROGAMMAUSFÜHRUNG SOFORT UND ERZWINGT EINEN OUTPUT! Gehen sie sparsam damit um.
Der Parameter $STATE gibt den Status der Meldung an. Gültige Belegungen sind:
Wert | Beschreibung |
---|---|
OK | Erfolgsmeldung |
ALERT | Hinweis |
ERROR | Fehler |
akzeptierte Belegungen für Parameter $STATE
Der Parameter $ERR_CODE gibt an, welche der gültigen Meldungen angezeigt werden soll. Gültige Werte für $ERR_CODE werden in den Sprachpaketen definiert. Bspw. in der Datei "language/de/message.config". Dort können auch weitere Meldungen hinzugefügt werden.
Gültige Belegungen sind unter anderem (AUSZUG):
Code | Beschreibung | Textauszug |
---|---|---|
200 | Erfolg | Änderungen wurden gespeichert. Vielen Dank !!! |
500 | Allgemeiner Fehler | Es ist ein Fehler aufgetreten... |
403 | Fehler: Zugriff verweigert | Passwort erforderlich. Sie betreten einen geschützten Bereich... |
UNGUELTIGE_EINGABE | Fehler: Falsche Eingabe | Ein gewählter Parameter ist ungültig... |
404 | Fehler: Datei nicht gefunden | Bitte überprüfen Sie die angegebene URL und versuchen Sie es erneut. |
ALLREADY_EXISTS | Fehler: Eintrag doppelt | Es konnte kein neuer Eintrag mit der id "%ID%" erzeugt werden, weil bereits ein anderes Eintrag mit diesem Namen existiert. |
FILE_NOT_CREATED | Fehler: IO-Error | Die Datei "%FILE%" konnte nicht erzeugt werden. |
NOT_WRITEABLE | Fehler: IO-Error | Der Schreibzugriff auf die Ressource "%FILE%" ist gescheitert. Daten konnten nicht gespeichert werden. |
NOT_READABLE | Fehler: IO-Error | Der Zugriff auf die Ressource "%FILE%" ist gescheitert. Daten konnten nicht gelesen werden. |
akzeptierte Belegungen für Parameter $ERR_CODE
Enthaltene Token, wie %FILE% werden ersetzt in der folgenden Weise:
$YANA->setVar('FILE', 'myFile.ext');
$YANA->message('error', 'NOT_READABLE','next_action');
Dies ist eine Alternative zu $YANA->message().
$YANA->report($REPORT) erzeugt ebenfalls eine Textmeldung, bricht das Programm jedoch nicht ab.
Es gibt drei Arten von Meldungen: normale Benachrichtigungen ("message"), Warnungen ("alert") und Fehler ("error"). Für jede dieser Typen gibt es jeweils eine passende Klasse: Message, Alert und Error.
Das folgende Beispiel schreibt eine Meldung in die Log-Datei und erzeugt dann einen Text für die Ausgabe am Bildschirm.
$YANA->report( new log("IO-ERROR: Unable to read file
$a") );
$YANA->report( new error('NOT_READABLE', array('FILE' =>
$a) ) );
Vergleichen Sie den Error-Code mit der Tabelle oben.
Der Parameter $REPORT ist eine Instanz einer der folgenden Klassen:
Klasse | Beschreibung |
---|---|
log | für Ausgabe in Log-Datei |
message | Erfolgsmeldung (Bildschirm) |
warning | Warnung |
alert | Hinweis |
error | Fehler |
akzeptierte Typen für Parameter $REPORT
Der Konstruktor nimmt 2 Parameter: _construct(string $text [, mixed $data]). Der Parameter $text kann ein Error-Code sein, oder auch ein beliebiger Fließtext. Für Bildschirmausgabe sollten Error-Codes verwendet werden. Für Ausgaben in die Log-Datei bietet sich englischer Fliesstext an. Der Parameter $data ist optional und enthält weitere Optionen. Beispielsweise den Datensatz, der nicht gespeichert werden konnte, oder den Namen einer Datei, die gerade nicht geöffnet werden kann.
Das besondere an $YANA->report() ist, dass Sie damit gleichzeitig Textmeldungen in die Log-Datei schreiben UND Meldungen am Bildschirm ausgeben können. Wird die Methode mehrmals aufgerufen, werden mehrere Textmeldungen am Bidlschirm ausgegeben.
$YANA->report( new warning('FILE_NOT_CREATED', array('FILE' => $a)) );
...
$YANA->report( new alert('NOT_WRITEABLE', array('FILE' => $a)) );
...
$YANA->report( new error('500') );
$YANA->report( new log("Input/Output Error in File $a", $lost_data) );
return false;
YANA stellt einen globalen Speicherbereich zur Verfügung, der von allen Plugins gelesen und verändert werden kann. Alle Variablen, die in diesem Bereich gespeichert werden, stehen Ihnen automatisch in allen Skins und Templates für die Ausgabe zur Verfügung. Bitte beachten Sie: der globale Speicherbereich in YANA ist etwas anderes als der global Namespace von PHP.
Innerhalb dieses Speichers werden Werte als ein Baum, in Form von mehrdimensionalen, assoziativen Arrays gespeichert. Der Zugriff auf diesen Speicherbereich erfolgt analog zu Smarty – oder, falls Ihnen der Vergleich besser gefällt, ähnlich wie mit XPath – über einen Schlüssel.
Zum Beispiel:
Die Funktion $YANA->getVar() erlaubt Ihnen das Lesen von Werten im globalen Speicherbereich.
Die Funktion $YANA->setVar() erlaubt Ihnen das Schreiben von Werten in den globalen Speicherbereich.
Dazu bietet YANA die Funktion $YANA->unsetVar(). Ein Beispiel:
Dazu bietet YANA die Funktion $YANA->unsetVar(). Ein Beispiel:
Das "Website-Profil" wird über den URL-Parameter "id" ausgewählt. Jedes Profil kann individuelle Einstellungen haben. Diese Einstellungen werden ebenfalls im globalen Speicherbereich des Frameworks abgelegt. Wird kein Profil gewählt, dann wird das Profil "default" verwendet. De facto müssen Sie als Programmierer sich nicht darum kümmern, welches Profil gewählt ist. Sie müssen nur wissen, dass in den Profildaten Einstellungen, wie die gewählte Hintergrundfarbe der Seite, die bevorzugte Schriftart und andere interessante Daten gespeichert sind, auf die Sie bei Bedarf zugreifen können.
Array ( >> Layout der Website [BGCOLOR] => #F0F0F0 [PFONT] => Arial, Helvetica, sans-serif [BGIMAGE] => [LOGO] => [HSIZE] => [HCOLOR] => [HFONT] => [PSIZE] => [PCOLOR] => >> Gewählte Sprache, Skin und Verzeichnis für Emoticons / Smilies [LANGUAGE] => deutsch.config [SKIN] => default.config [SMILEYDIR] => common_files/smilies/ >> Sonstige Einstellungen [USERMODE] => 1 [AUTO] => 1 [TIMEFORMAT] => 0 >> Protokollierung [LOGGING] => 1 [LOG_LENGTH] => 50 >> Einstellungen für Plugin "rss to html factory" [RSS] => Array ( [FILE] => plugins/rss/test.rss [MAX] => 5 ) >> Einstellungen für Plugin "guestbook" (Gästebuch) [GUESTBOOK] => Array ( [NOREPLY] => noReply@meineAdresse.tld [FLOODING] => 0 [ENTPERPAGE] => 5 [NOTIFICATION] => [SENDMAIL] => [MAIL] => meinName@meineAdresse.tld [FILE] => [SPAMPROTECT] => 1 [PROFILE] => [USE_DB] => ) >> Einstellungen für Plugin "search" (Stichwortsuche) [SEARCH] => Array ( [TARGET] => _self ) >> Einstellungen für Plugin "user_admin" (Nutzerverwaltung) [USER] => Array ( [ALLOW_CREATE] => 0 ) ) */ /* die gewählte Hintergrundfarbe auslesen */ $string = $YANA->getVar("PROFILE.BGCOLOR"); print '<p style="background-color: '.$string.'">test</p>';
Ein CAPTCHA ist eine Methode zum Schutz vor Spam. Dazu wird eine Grafik mit einem Text angezeigt, welchen der Besucher abtippen muss. Ein Mensch kann das mit Leichtigkeit, ein Spam-Bot hingegen kann das nicht. Auf diese Weise kann eine große Menge unerwünschter Werbung vermieden werden.
YANA hat eine Funktion zum Erzeugen einer CAPTCHA-Grafik im PNG-Format (Mime-Type „image/png“), welche einen zufällig erzeugten Code aus Zahlen und Buchstaben enthält. Ein Parameter gibt an, welche Positionsnummer dieser Code in der aktuellen Code-Tabelle hat. Die Codetabelle enthält 10 Einträge und verfällt in einem Zeitraum von 10 Minuten bis etwa 3 Stunden nach dem Aufruf der Funktion automatisch. Wenn die Tabelle abgelaufen ist, erstellt YANA automatisch eine neue Tabelle.
YANA hat eine solche Funktion bereits eingebaut. Sie müssen sich also nicht selbst darum kümmern, sondern es lediglich benutzen.
Das CAPTCHA besteht aus zwei Teilen: eine Grafik mit einem Input-Feld, welche im Template eingebunden werden müssen und einer Abfrage, welche im Quellcode des Plugins eingebunden werden muss und die true beziehungsweise false liefert, wenn die Eingabe korrekt beziehungsweise falsch war.
Dazu folgendes Beispiel:
Die Schnittstelle eines Plugins wird als Datei mit der Endung "*.config" gespeichert. Sie finden diese Dateien im Verzeichnis "plugins/".
/* in der Schnittstellenbeschreibung plugins/foo.config */ <INTERFACE> <name der aktion> <TYPE>primary|default|write|read|security|config</TYPE> /* Type: - "security" für sicherheitsrelevante Funktionen, wie das Prüfen von Passwörtern - "config" gedacht Funktionen zum Editieren von Konfigurationsdateien - "write" für Schreibzugriffe auf dem Dateisystem oder einer Datenbank - "read" für Lesezugriffe auf dem Dateisystem oder einer Datenbank - "default" ist gedacht für Entwickler, die sich unschlüssig sind, wo die Aktion einzuordnen ist */ <MODE>0|1</MODE> /* Mode: - 0 (default) normaler Betriebsmodus - 1 Aktion im Default-Konfiguration ("abgesicherter Modus") starten (für sicherheitskritische Aufgaben) */ <TEMPLATE>Id des Templates (z.Bsp. INDEX)</TEMPLATE> <INSERT>Id des Templates (z.Bsp. MY_TEMPLATE)</INSERT> /* Templates: Namen von Templates für die Ausgabe - das unter "INSERT" angegebene Datei wird in die "TEMPLATE"-Datei eingebettet - "TEMPLATE" bildet also einen statischen "Rahmen" um den Inhalt, Defaultwert ist "INDEX" - Der Name des Templates entspricht dem Namen, der in der Skindatei festgelegt wurde. Zum Vergleich öffnen Sie bspw. die Datei skins/default/default.config . - Das spezielle Template "NULL" unterbindet dass eine Ausgabe erzeugt wird (sehr praktisch wenn die Ausgabe keine HTML-Datei sondern bspw. eine PNG-Grafik werden soll) - Das spezielle Template "MESSAGE" erzeugt eine Textmeldung. */ <PERMISSION>1</PERMISSION> /* Permission: Gibt an, welche Zugriffsrechte für einen Nutzer mindestens erforderlich sind, um die Aktion aufrufen zu können. Der Wert liegt zwischen 0 und 100, wobei der Wert 0 = "keine Beschränkung" bedeutet. Sie können eine Funktion temporär deaktivieren, indem Sie die Permission auf -1 setzen. In diesem Fall kann niemand die Aktion aufrufen. */ <ONSUCCESS> <TEXT>Name der Textmeldung</TEXT> <GOTO>Name der Aktion</GOTO> </ONSUCCESS> <ONERROR> <TEXT>Name der Textmeldung</TEXT> <GOTO>Name der Aktion</GOTO> </ONERROR> /* OnSuccess / OnError: Sie können eine Aktion angeben, auf welche automatisch weitergeleitet werden soll, wenn die Aktion erfolgreich war beziehungsweise, wenn ein Fehler aufgetreten ist. Zusätzlich können Sie eine Textmeldung angeben, welche angezeigt werden soll. Eine Liste der Textmeldungen finden Sie in der Datei "languages/de/message.config". */ </name der aktion> /* ein Beispiel */ <foo> <TYPE>write</TYPE> <MODE>0</MODE> <TEMPLATE>MESSAGE</TEMPLATE> <PERMISSION>75</PERMISSION> <ONSUCCESS> <GOTO>foo_read</GOTO> </ONSUCCESS> <ONERROR> <GOTO>foo_edit</GOTO> </ONERROR> <foo> </INTERFACE> /* in der Plugin-Klasse plugins/foo/plugin.php */ class plugin_foo extends plugin { /* ... */ function foo($ARGS) { # Quelltext der Aktion "foo" if ($test) { return true; # true = SUCCESS -> geht zu Aktion "foo_read" } else { return false; # false = ERROR -> geht zu Aktion "foo_edit" } } function foo_edit($ARGS) { # Quelltext der Aktion "foo_edit" } function foo_read($ARGS) { # Quelltext der Aktion "foo_read" } }
Zuerst sollten Sie mit Hilfe des SDK ein Grundgerüst für Ihr neues Plugin generieren lassen. Dies macht das Anpassen des Quellcodes deutlich einfacher.
Für das Erstellen einer neuen Aktion sind zwei Dinge erforderlich. Einerseits das Schreiben des Quellcodes und andererseits die Registrierung dieser neuen Aktion im Framework selbst durch Publizieren der Schnittstelle. Dadurch wird es überhaupt erst möglich, die Aktion aufzufinden und zu benutzen.
Im Folgenden ein Beispiel: Alle öffentlichen Funktionen der Klasse stellen eine Funktion bereit, die ebenso heißt, wie die Funktion selbst. Also: um eine Aktion "foo" zu erzeugen, erstellen Sie eine Funktion "foo()". Diese rufen Sie in der URL auf über: "index.php?action=foo".
Achten Sie im Folgenden Beispiel auf die "Hot-Spots". Diese markieren Stellen im Skelett der Anwendung, welche mit eigenem Code befüllt werden können.
class plugin_beispiel extends plugin { function plugin_beispiel($plugin_name) { settype($plugin_name,"string"); global $YANA; $this->plugin_name = $plugin_name; } /** * Default event handler * * @param string $event name of the called event in lower-case * @param array $ARGS array of params passed to the function * @return boolean */ function _default($event, $ARGS) { settype($event, "string"); settype($ARGS, "array"); # HOT-SPOT << hier können Sie Aktionen definieren # zum Beispiel mit einer Switch-Anweisung: switch ($event) { case 'my_action1': # HOT-SPOT << Code für Aktion 'my_action1' break; case 'my_action2': # HOT-SPOT << Code für Aktion 'my_action2' break; } return true; } /** * Type: read * Permission: 0 * Templates: index entries * * @param array $ARGS array of params passed to the function * @return boolean */ function guestbook_read_entries ($ARGS) { # HOT-SPOT << Code für Aktion 'guestbook_read_entries' } /* { ... } */ /** * Type: write * Permission: 100 * Templates: MESSAGE * * @param array $ARGS array of params passed to the function * @return boolean */ function guestbook_write_write ($ARGS) { # HOT-SPOT << Code für Aktion 'guestbook_write_write' $YANA->message("OK", "200"); } function my_action ($ARGS) { # HOT-SPOT << Code für Aktion 'my_action' } }
Die „Hot-Spots“, an welchen der Entwickler eigenen Quellcode schreiben oder ergänzen kann, sind in diesem kurzen Beispiel entsprechend hervorgehoben. Die Funktion „my_action“ soll demonstrieren, wie man nachträglich eigene Aktionen zur Schnittstelle der Klasse und damit zum Plugin hinzufügen kann. Beachten Sie die Funktion „_default“. Diese wird von der Basisklasse „plugin“ geerbt und fungiert als „Default event handler“, welcher alle Ereignisse abfängt, die an das Plugin gesendet werden, aber über die Schnittstelle der Klasse nicht implementiert sind. Außerdem fängt diese Funktion Exoten ab, wie beispielsweise Ereignisse welche ungünstigerweise ebenso benannt sind wie der Konstruktor der Klasse selbst, oder solche, welche von der Basisklasse „plugin“ geerbt wurden und somit nicht zur vom Nutzer definierten Schnittstelle der Klasse gehören können. Dies betrifft aus Sicherheitsgründen auch solche, welche in der abgeleiteten Klasse reimplementiert werden. Der Grund hierfür ist, dass diese Methoden öffentlich sind. Sie sind somit Teil einer gemeinsamen Schnittstelle aller von der Klasse „plugin“ abgeleiteten Klassen. Ihre Funktionalität wird folglich gewissermaßen durch die Implementierung der Basisklasse vorgegeben und zugesichert. Sie sollte auch in den abgeleiteten Klassen erhalten bleiben.
Um eine Funktion zu erzeugen, die nicht in der öffentlichen Schnittstelle auftauchen soll, gibt es in PHP 5 die Möglichkeit, die Funktion als "private" zu kennzeichnen. Unter PHP 4 gab es diese Option leider noch nicht. Wenn Sie PHP 4 verwenden wollen, können Sie jedoch den gleichen Effekt erreichen, indem Sie den Namend der Funktion mit einem Unterstrich "_" beginnen. Das Framework wird solche Funktionen automatisch so behandeln, als wären Sie mit "private" gekennzeichnet.
Bitte beachten: damit die neuen Funktionen verfügbar werden, müssen Sie den Plugin-Cache erneuern. Dazu loggen Sie sich als Administrator ein und klicken im Administrationsmenü auf "Liste neu laden".
Zum Bearbeiten von Aktionen bietet YANA die Funktion $YANA->handle(), welche bei Erfolg bool(true) und sonst bool(false) zurück gibt.
Dies bewirkt, dass alle Dateien mit den Endungen "*.php", "*.tmp" und "*.cache" im Verzeichnis „cache/“ des Frameworks gelöscht werden.
© 2001, 2002, 2003, 2004, 2005, 2006Thomas Meyer, www.all-community.de/pub