AddOn-Programmierung für das FS2
Ziel dieses Tutorials soll es sein dir die Eigenheiten bei der AddOn-Programmierung für das Frogsystem 2 näher zu bringen. Dabei geht es vor allem um die Integration in das System.
Es kann nicht die Aufgabe dieses Tutorials sein dir PHP, SQL oder sogar HTML beizubringen, dazu gibt es bereits genügend andere wirkliche gute Tutorials im Internet. Deswegen ist die eigentliche Programmierung, des mit diesem Tutotrial erstellten AddOns, nur rudimentär und wird sich ausschließlich um Varianten des bekannten "Hello World" drehen.
Voraussetzung für dieses Tutorial ist lediglich eine funktionierende Frogsystem 2 Installation der aktuellen Version. Und natürlich musst du auch direkten Zugriff auf das Datei-System und den MySQL-Server haben.
Auf geht's!
Wie üblich wollen wir auch hier damit beginnen, eine einfache Datei zu erstellen, die uns die Nachricht "Hello World" ausgibt. Für Ausgaben bietet sich in einem CMS natürlich der öffentliche Bereich einer Seite an.
Über Adressen
Im Frogsystem 2 sind das die Seiten, die über die URL mit ?go= aufgerufen werden. Die entsprechenden Dateien dazu befinden sich im Data-Ordner ⇒[FS2]/data/.
Nachdem evtl. Alias-Weiterleitungen durchgeführt wurden, sucht das System nach einer Datei in diesem Ordner, die genauso heißt, wie das, was hinter dem ?go= steht. Der Übersicht halber lassen wir aber die Dateiendung ".php" weg. Das Frogsystem 2 fügt diese dann automatisch hinzu.
Eine Sonderstellung besitzt hier natürlich die Artikel-Funktion, für die unabhängig davon, ob eine Datei im Data-Ordner liegt, ?go=-Adressen angelegt werden.
Die Reihenfolge, nach der ?go=-Adressen überprüft werden, ist also:
Findet sich keine Datei und kein Artikel, wird die 404-Fehlerseite ausgegeben (die aber wie andere Dateien auch im Data-Ordner liegt).
Das erste Script
Jetzt erstellen wir aber erstmal unser erstes Script. Also einfach mal im Data-Ordner die Datei "helloworld.php" anlegen und diesen Inhalt einfügen:
<?php //PHP Klammern werden ab sofort nicht mehr extra angegeben echo "Hello World"; ?>
Wenn wir die Datei jetzt über ?go=helloworld aufrufen, erhalten wir eine Ausgabe, die so ähnlich wie auf dem Bild aussehen sollte (roter Rahmen). Das führt uns zu einem ersten wichtigen Prinzip der FS2-Programmierung.
Um Inhalte an den vorgesehenen Stelle auszugeben, kann im Frogsystem 2 nicht einfach der PHP-Befehl echo verwendet werden. Am richtigen Platz ausgeben werden nur die Inhalte, die am Ende des Scripts in der Variable $template gespeichert sind.
Daher gibt es zwei Möglichkeiten um unseren Fehler zu korrigieren. Wir könnten echo weiter nutzen und die Ausgabe mit dem PHP-Ausgabepuffer regeln, oder einfach echo durch $template ersetzen. In diesem Tutotial werden wir der Einfachheit halber die zweite Möglichkeit einsetzen. Dennoch sind beide Varianten prinzipiell gleichwertig.
Versuchen wir es also einmal mit diesem Code:
$template = "Hello World";
Wenn wir uns jetzt die Seite anschauen, sieht das Ganze doch schon viel besser aus (oder sollte es zumindest).
Nun wollen wir ja eigentlich mehr machen, als nur einen einfachen Text ausgeben und damit die Welt zu begrüßen. Eigentlich würden wir gerne alles mögliche begrüßen, und über das AdminCP einstellen können, wer gerade an der Reihe ist.
Die Datenbank
Das FS2 setzt im Hintergrund auf eine MySQL-Datenbank. Am einfachsten lässt sich diese über das Tool phpmyadmin verwalten, aber jeder andere Zugang ist natürlich genauso möglich.
Grundsätzlich verwendet das FS2 mehrere Tabellen, die dann die dann die entsprechenden Daten enthalten. Jede Tabelle beginnt dabei mit einem Präfix, dass während der Installation festgelegt wurde (Standard: fs2_, wird hier synonym für alle Präfixe verwendet). Es folgt dann der Name des Unter-Systems oder AddOns, für welche die Tabelle die größte Relevanz besitzt. Mit weiteren Unterstrichen können dann noch Spezialisierungen der Tabellen angegeben werden. So gibt es z.B. eine Tabelle fs2_news, die den Hauptinhalt von News speichert, aber auch eine Tabelle fs2_news_config, in der die Einstellungen für das News-System zu finden sind.
Wir wollen nun also konfigurieren können, wenn wir mit unserem AddOn begrüßen. Deswegen erstellen wir uns jetzt eine neue Tabelle fs2_hello_config mit den Feldern id (Typ: TINYINT( 1 ), Standard: 1) und hello_name (Typ: VARCHAR( 100 ), Standard: "World"). Außerdem erstellen wir uns gleich einen Datensatz dazu. Wir können beides einfach mit Hilfe von phpmyadmin machen oder diesen Befehl verwenden:
CREATE TABLE `fs2_hello_config` ( `id` TINYINT( 1 ) NOT NULL DEFAULT '1', `hello_name` VARCHAR( 100 ) NULL DEFAULT 'World' ); INSERT INTO `fs2_hello_config` (`id`,`hello_name`) VALUES ('1', 'World');
Ein Name muss her
Bei der Erklärung, wie Tabellen Namen aufgebaut sind, ist dir vielleicht aufgefallen, dass dort von einem Addon-Namen die Rede ist. Diese Namen sind wichtig, damit sich sich verschiedenen Addons nicht in die Quere kommen.
Wenn wir unser Addon auf der offiziellen Seite einstellen möchten, wird unter anderem auch darauf geachtet, dass wir einen eindeutigen Addon-Namen gewählt haben. Festlegen müssen wir einen Titel, der Groß-/Kleinschreibung oder Sonderzeichen enthalten darf und einen Tag, der als Präfix z.B. bei Tabellen dient, klein geschrieben werden muss und keine Sonderzeichen enthalten darf, aber immer noch mit dem Titel in Verbindung stehen sollte.
Für unser kleines Addon haben wir aber noch keine richtigen Namen gefunden. Da wir ja irgendwelche Sachen begrüßen wollen, nennen wir es einfach "Hello!". (Das Ausrufezeichen macht den Titel erst so richtig cool!) Den zugehörigen Tag "hello", haben im SQL-Teil schon mit eingebaut.
Im nächsten Schritt erstellen wir eine einfache Konfigurationsseite um den Namen des zu Begrüßenden komfortabel ändern zu können und erstellen dazu die entsprechenden Rechte für Mitarbeiter.
AdminCP-Seiten
Alle Seiten, die im AdminCP verwendet werden, sind unter "[FS2]/admin/" abgelegt. Sie beginnen mit dem Namen der Gruppe oder des Addons, gefolgt von einer genaueren Bezeichnung der Funktion der Seite.
/////////////////////// //// Update Config //// /////////////////////// if ( $_POST['hello_name'] && $_POST['hello_name'] != "" ) { // security functions $_POST['hello_name'] = savesql ( $_POST['hello_name'] ); // MySQL-Queries mysql_query ( " UPDATE `".$global_config_arr['pref']."hello_config` SET `hello_name` = '".$_POST['hello_name']."' WHERE `id` = '1' ", $db ); // system messages systext ( $TEXT["admin"]->get("changes_saved"), $TEXT["admin"]->get("info"), FALSE, $TEXT["admin"]->get("icon_save_ok") ); // Unset Vars unset ( $_POST ); } ///////////////////// //// Config Form //// ///////////////////// if ( TRUE ) { // Display Error Messages if ( isset ( $_POST['sended'] ) ) { systext ( $TEXT["admin"]->get("changes_not_saved")."<br>".$TEXT["admin"]->get("form_not_filled"), $TEXT["admin"]->get("error"), TRUE, $TEXT["admin"]->get("icon_save_error") ); // Load Data from DB into Post } else { $index = mysql_query ( " SELECT * FROM ".$global_config_arr['pref']."hello_config WHERE `id` = '1' ", $db); $config_arr = mysql_fetch_assoc($index); putintopost ( $config_arr ); } // security functions $_POST['hello_name'] = killhtml ( $_POST['hello_name'] ); // Display Form echo' <form action="" method="post"> <input type="hidden" name="go" value="hello_config"> <input type="hidden" name="sended" value="1"> <table class="configtable" cellpadding="4" cellspacing="0"> <tr><td class="line" colspan="4">Allgemeine Einstellungen</td></tr> <tr> <td class="config"> Ziel der Begrüßung:<br> <span class="small">Person oder Sache, die begrüßt werden soll.</span> </td> <td class="config"> <input class="text input_width" name="hello_name" maxlength="100" value="'.$_POST['hello_name'].'"> </td> </tr> <tr><td class="space"></td></tr> <tr> <td class="buttontd" colspan="2"> <button class="button_new" type="submit"> '.$TEXT["admin"]->get("button_arrow").' '.$TEXT["admin"]->get("save_changes_button").' </button> </td> </tr> </table> </form> '; }
siehe auch: Beispiel & Erklärung einer Konfigurationsseite im AdminCP
Zugriffsrechte & Links anlegen
Im AdminCP des Frogsystem 2 werden die Navigations-Menüs entsprechend der Zugriffsrechte eines eingeloggten Users gesetzt. Dazu muss jeder Seite ein entsprechendes Recht zugeordnet werden. Prinzipiell muss man für jede Seite ein Recht anlegen. Es kann nicht ein und dasselbe Recht für zwei Seiten genutzt werden. Es ist allerdings möglich Sub-Rechte zu definieren, die zusätzlich innerhalb einer Seite verwendet werden sollen.
Schauen wir uns dazu einmal die Tabelle fs2_admin_cp an:
Bis auf die Linkgruppe sollte alles klar sein. Linkgruppen fassen die einzelnen Links innerhalb des Menüs optisch zu einer Gruppe zusammen. Diese Gruppen werden in der Tabelle fs2_admin_groups festgelegt:
Auch diese Tabelle sollte größtenteils selbsterklärend sein. group_id nutzt einfach einen fortlaufenden Index. menu_id bezieht sich auf das obere Menü, das selbst in der Tabelle fs2_admin_cp durch die Startseiten erzeugt wird, welche "-1" als group_id nutzen (und somit als Bereich inkl. zugehöriger Startseite definiert werden).
Addons sollten sich entweder in einen der bestehende Bereiche oder den Sonderbereich "AddOns" einbinden. Ein eigener Bereich muss bei der Überprüfung gesonderte Auflagen erfüllen.
Da es sich bei unserem AddOn um Inhalt handelt, wollen wir es auch entsprechend in den content-Bereich eingliedern, wir erstellen also folgende Gruppe:
INSERT INTO `fs2_admin_groups` (`group_title`, `menu_id`, `group_pos`) VALUES ('Hello!', 'content', '99');
Die 99 als Position innherhalb des Bereichs soll lediglich dafür sorgen, dass unser AddOn immer ganz unten angezeigt wird.
Mit der soeben erzeugten Gruppe können wir jetzt auch unserer eigentliches Recht bzw. den Link anlegen.
INSERT INTO `fs2_admin_cp` (`page_id`, `group_id`, `page_title`, `page_link`, `page_file`, `page_pos`, `page_int_sub_perm`) VALUES ('hello_config', '27', 'Konfiguration', 'Konfiguration', 'hello_config.php', '1', '0');
group_id variiert natürlich und muss später nur intern vom Installationsscript ermittelt werden. Einmal aus- und einloggen und wir finden unsere brandneue Konfigurationsseite im AdminCP. (Gilt nur für Admins, bei allen anderen Benutzern muss vorher natürlich noch über die Benutzerverwaltung das neue Recht gesetzt werden.)
Ausgabe anpassen
Zu guter Letzt bauen wir in unsere Ausgabeseite helloworld.php noch die Abfrage des Config-Wertes aus der Datenbank ein:
////////////////////// //// Config Array //// ////////////////////// $index = mysql_query ( " SELECT * FROM `".$global_config_arr['pref']."hello_config` WHERE `id` = '1' ", $db ); $config_arr = mysql_fetch_assoc ( $index ); $template = "Hello " . stripslashes ( $config_arr['hello_name'] ) . "!";
siehe auch: Beispiel & Erklärung einer Frontend-Seite
Da wir uns dazu entschieden haben das Programm "Hello!" zu nennen, sollten wir eigentlich die Datei auch in "hello.php" umbenennen.
Da uns das aber zu viel Arbeit ist und da wir das Alias-System kennen lernen sollen, beleiben wir bei dem alten Namen und legen einen Alias an. Das geht ganz einfach unter System→Aliasse, die Maske ist selbsterklärend.
Nach dem wir schon den Inhalt der Begrüßung variabel gestaltet haben, wollen wir zum Schluss auch noch das Design über ein Template gestalten. Dazu müssen wir eine spezielle Template-Seite für das Admin-CP anlegen und abschließend die Ausgabe-Datei auf dieses neue Template zugreifen lassen.
Template bearbeiten
Die Template Bearbeitung findet im Admin-CP statt. Dazu wird ein normales PHP-Skript mit dem Namen hello_template.php angelegt, das aber intern auf eine besondere API zugreift. Wir speichern das Skript mit folgendem Inhalt:
// Set $go-Value if ( $go == "tpl_hello" ) { $TEMPLATE_GO = "tpl_hello"; } else { $TEMPLATE_GO = "hello_template"; } $TEMPLATE_FILE = "hello.tpl"; $TEMPLATE_EDIT = array(); $TEMPLATE_EDIT[] = array ( name => "HELLO", title => "Hello!-Design", description => "Darstellung der Hello!-Begrüßungsseite", rows => 20, cols => 66, help => array ( array ( tag => "hello_name", text => "Name der Person oder Sache, die begrüßt werden soll." ), ) ); // Intialise Editor echo templatepage_init ( $TEMPLATE_EDIT, $TEMPLATE_GO, $TEMPLATE_FILE );
siehe auch: Beispiel & Erklärung einer Template-Seite im AdminCP
Die im Skript angegebene Template-Datei hello.tpl wird vom System beim ersten Speichern automatisch erzeugt.
Die Einbindung der Seite funktioniert wie gehabt über das Rechte-System. Da wir wollen, dass die Template-Bearbeitung sowohl in der AddOn-Gruppe "Hello!", als auch unter Styles→Templates angezeigt wird, legen wir zwei Einträge an:
INSERT INTO `fs2_admin_cp` (`page_id`, `group_id`, `page_title`, `page_link`, `page_file`, `page_pos`, `page_int_sub_perm`) VALUES ('hello_template', '27', 'Template bearbeiten', 'Template', 'hello_template.php', '2', '0'), ('tpl_hello', '22', '„Hello!“ bearbeiten', 'Hello!', 'hello_template.php', '99', '0')
Template verwenden
Beim ersten Bearbeiten erhalten wir den Hinweis, dass die Template-Datei wie gewünscht vom System erstellt wurde.
Für unsere Zwecke reicht es vorerst aus, wenn wir ein einfaches Template einfügen und speichern:
<div align="center">Hello <b>{..hello_name..}</b>!</div>
Das Ausgabe-Skript wird nun noch wie folgt angepasst:
////////////////////// //// Config Array //// ////////////////////// $index = mysql_query ( " SELECT * FROM `".$global_config_arr['pref']."hello_config` WHERE `id` = '1' ", $db ); $config_arr = mysql_fetch_assoc ( $index ); ////////////////////// //// Get Template //// ////////////////////// $template = new template(); $template->setFile("hello.tpl"); $template->load("HELLO"); $template->tag("hello_name", stripslashes ( $config_arr['hello_name'] ) ); $template = $template->display();
siehe auch: Beispiel & Erklärung einer Frontend-Seite
Wenn wir uns jetzt die Ausgabe anschauen, können wir feststellen, dass unser AddOn endlich fertig ist:
Jedes AddOn muss ein eigenes Installations und Deinstallations-Skript mitbringen. Da für die aktuelle Version (Alix 5) keine allgemeine Form dieser Skritpe vorgesehen ist, sind wir beim Erstellen mehr oder weniger frei. Dennoch gibt es einige Hinweise die wir beachten müssen:
Allgemein
Installation
Deinstallation
siehe auch: Beispiel & Erklärung eines De- bzw. Installations-Skripts