In dieser Anleitung wird beschrieben wie eigene Module für xentral programmiert werden können.
Jedes Modul besteht aus mindestens einer .php Datei und passenden Templates. Die Struktur bzw. der Aufbau der .php Datei ist vorgegeben. Ein zusammenhängendes Beispiel befindet sich in xentral (vorlage.php).
Die .php Datei ist immer im Ordner www/pages. Der Name der Datei entspricht dem Modulnamen. Die Templates befinden sich im Ordner www/pages/content.
Beispiel:
Wichtig ist, dass sich an diese Namenskonventionen gehalten wird, da das Framework basierend auf diesen Namen automatisch die Module laden kann, bzw. z.B. auch das Rechtesystem automatisch die Actions erkennen kann.
Der Name der App, bzw. das Modul oder einfach gesagt die .php Datei heißt in xentral Modul. In der Datei befindet sich alles, was zu einem Modul bzw. einer App gehört. Um in xentral als Oberfläche zu erscheinen, muss der Benutzer die entsprechenden Rechte haben. Damit xentral weiß, was ein Benutzer aufrufen darf, sind für einzelne Unteroberflächen oder Aktionen eigene “Actions” zu schreiben. Wie diese aufgeteilt werden, ist prinzipiell selbst überlassen. Es muss nur gewusst werden, dass in der Rechteverwaltung diese Actions einem Benutzer von den Rechten her gegeben werden kann oder nicht. Typische Actions sind

Wenn möglich sollte sich immer an diese Konvention gehalten werden. Es ist z.B. so, dass “list” automatisch versucht wird zu starten, wenn das Modul ohne Action aufgerufen wird.
Der Aufruf der Module mit den passenden Actions kann über die URL geschehen.
index.php?module=mymodule&action=list
Als weitere Besonderheit ist zu beachten, dass als GET Parameter aktuell meist nur "id" für die Übergabe des Primärschlüssels für den aktuellen Datensatz und "cmd" für die Übergabe eines “Unterkommandos für das Action”, wenn notwendig, zu verwenden sind.
Alle weiteren Parameter werden als POST übergeben.
Eine Datei sieht minimal so aus:
<?php
//WAWIFILEONLYON VERSION=ALL
class mymodule {
var $app;
function __construct(&$app, $internal = false) {
$this->app=&$app;
if($internal)return;
$this->app->ActionHandlerInit($this);
// from here define all action handlers the module has
$this->app->ActionHandler("list", "MymodulList");
$this->app->ActionHandler("create", "MyModuleCreate");
$this->app->ActionHandler("edit", "MyModuleEdit");
$this->app->ActionHandlerListen($app);
}
function MyModuleList()
{
$this->app->Tpl->Parse("PAGE", "existenzgruender_list.tpl");
}
Passend das Template in
www/pages/content/mymodule_list.tpl
<!-- WAWIFILEONLYON VERSION=ALL -->
<!-- belongs to tabview -->
<div id="tabs">
<ul>
<li><a href="#tabs-1">test</a></li>
</ul>
<!-- end belongs to tabview -->
<!-- first tab -->
<div id="tabs-1">
[MESSAGE.]
[TAB1]
[TAB1NEXT]
</div>
<!-- close tab view -->
</div>
Im Konstruktor ist die Definition der ActionHandler ersichtlich. Das sind die einzelnen Unteroberflächen. xentral erlaubt den Aufruf nur, wenn der Benutzer die entsprechenden Rechte hat. D.h. es muss sich nicht als Entwickler darum gekümmert werden, ob der Benutzer das aktuell darf oder nicht, da sich darum das Framework selbständig kümmert.
Jedes Action muss im Konstruktor registriert werden.
$this->app->ActionHandler("edit", "MyModuleEdit");
Im ersten Parameter steht der Name, der über index.php?module=meinmodul&action=edit angegeben wird. Im zweiten Parameter ist der lokale Methodenname. D.h. in dieser Datei muss es eine Methode MeinmodulEdit geben, die dann automatisch aufgerufen wird.
function MyModuleEdit()
{
}
Für die Ausgabe von Oberflächen gibt es ein Templatesystem. Im wesentlichen sind diese .tpl Dateien die HTML Stücke bzw. Teiloberflächen die xentral übergeben werden, damit der Benutzer seine Oberflächen sieht. In der PHP Datei sollten keine kompletten HTML Strukturen stehen, sondern nur Inhalte die in das Template gefüllt werden. Muss eine spezielle Tabelle in PHP erstellt werden (wobei gewusst werden muss, dass es Mechanismen für Tabellen in xentral gibt) wäre es in Ordnung wenn maximal die Tabelleninhalte per PHP (also die und Tags) erstellt werden. Aber mehr sollte es eigentlich nicht sein. Alles andere kann direkt in die .tpl Datei. Inhalte kommen in die .tpl Datei immer über Templatevariablen. Das sind in eckigen Klammern komplett groß geschriebene Variablen z.B. [DATUM], [STRASSE], [FORMVAL1_ADRESSE] Diese Werte im Template können mit den beiden Methoden "Set" und "Add" befüllt werden. Mit "Set" wird der komplette Inhalt der Variable überschrieben. Mit Add bleibt der bestehende Inhalt, der zuvor mit Set oder Add definiert worden ist, bestehen und wird entsprechend hinten angehängt.
Beispiele:
$this->app->Tpl->Set("NAME", $name_from_db);
$this->app->Tpl->Add("NAME", "Hans");
Der komplette Inhalt eines Templates kann wiederum einer Templatevariable übergeben werden. So kann z.B. die Oberfläche eines ActionHandlers an xentral übergeben werden, in dem das Template nach [PAGE] ausgegeben wird.
Am Ende des ActionHandler befindet sich daher meist folgende Zeile:
$this->app->Tpl->Parse("PAGE", "mymodule_list.tpl");
D.h. es wird das Template mit den gesamten zuvor gefüllten Variablen in die neue Variable PAGE geschrieben. xentral gibt diese später, wenn die notwendigen Rechte, etc. vergeben hat, aus.
$output = $this->app->Tpl->Output("mymodule_list.tpl);
git the template directly into the $output variable.
Im folgenden wird beschrieben, wie Standardfunktionen mit xentral abgebildet werden. Alle Module sollten nach diesem Schema entwickelt werden.
Auf die Datenbank wird mit xentral über das Modul $this->app->DB zugegriffen. Hier gibt es verschiedene Methoden. Es sollte immer diese verwendet und nicht mit anderen zugegriffen werden. Um z.B. an die Adressdaten einer Adresse zu kommen, kann die Methode SelectArr verwendet werden:
$this->app->DB->SelectArr("SELECT * FROM ...");
gibt ein zweitdimensionales Array aus
$this->app->DB->Select("SELECT number FROM article WHERE id = '$id' LIMIT 1");
Diese gibt ein einzelnen Wert aus, falls sich genau eine Spalte und eine Zeile aus dem Query ergibt. Sonst wird ein Array ausgegeben
Abfrage ohne direkte Ausgabe
$query = $this->app->DB->Query("SELECT * FROM article WHERE project = '$project'");
Holen der nächsten Zeile aus dem Query
$row = $this->app->DB->Fetch_Array($query);
Freigeben der Resource
$this->app->DB->free($query);
Datensätze hinzufügen:
$this->app->DB->Insert("INSERT INTO article (number, name_en) VALUES ('10000','examplearticle');
Holen der Datensatz-Id nach dem Insert
$id = $this->app->DB->GetInsertID();
Um einen Datensatz zu ändern:
$this->app->DB->Update("UPDATE article SET project = '1' WHERE id = '$id'");
Auf Variablen eines Formulars wird immer über das Modul Secure zugegriffen. Das stellt unter anderem sicher, dass die Inhalte keine SQL Injection oder ähnliches enthalten. Es darf in xentral nie direkt auf $_GET und $_POST zugegriffen werden.
Beispiele:
Oft muss gewusst werden, welcher Benutzer aktuell etwas durchführt, weil z.B. bei der eigenen Zeiterfassung die Datensätze mit der eigenen ID verknüpft gehört oder allgemein, wenn etwas benutzerspezifisch durchgeführt oder gespeichert werden soll.
Für viele Standardwidgets gibt es in xentral fertige Mechanismen.
Ein DatePicker kann einfach aktiviert werden:
$this->app->YUI->DatePicker("date");
<input type="text" id="date" name="date">
Oft gibt es in xentral Felder bei denen lostippt wird und dann weitere Sachen vorgeschlagen werden. Das ist z.B. ein AutoComplete
Verfügbare Variablen
$heading ist ein Array mit den Tabellenüberschriften $heading = array ('Beleg- Nr','Kundennummer','Kunde','Umsatz','Menü');
$width gibt die Breiten der Spalten in % an. $width = array('20%','20%','29%','10','1%');
$findcols Für jede Spalte muss der Sortierungsaudruck angeben $findcols = array('a.belegnr','adr.kundennummer','adr.name','a.umsatz_netto','a.id');
$searchsql Gibt die Spalten / Ausdrücke in der gesucht werden kann. $searchsql = array('a.belegnr', 'adr.kundennummer','adr.name','adr.ort'); $defaultorderGibt die Spalte an nach der Standardmäßig sortiert werden soll (Zählung beginnt ab 1).
$defaultorder = 5;//Sortierung nach id
$defaultorderdesc Gibt an ob die Standardsortierung aufsteigend (0) oder absteigend (1) erfolgen soll. $defaultorderdesc = 1; //Absteigend sortiert
$sql Enthält das SQL-Query mit Spalten und FROM-Anteil, allerdings ohne WHERE, GROUP BY, SORT oder LIMIT $sql = "SELECT SQL_CALC_FOUND_ROWS a.id,a.belegnr, adr.kundennummer,a.name,format(a.umsatz_netto,2) , a.id FROM auftrag a LEFT JOIN adresse adr ON a.adresse = a.id"
$where Enthält die Bestandteile der WHERE abfrage ohne das Schlüsselwort WHERE $where = "a.status != 'angelegt'";
$count Gibt das komplette Query an, dass die Anzahl der Datensätze zurückgibt. $count = "SELECT count(id) FROM auftrag WHERE status != 'angelegt'";
$menucol Gibt die Position der Menüspalte an. Dies ist notwendig falls Minidetails eingebunden werden. $menucol = 5;
$alignright Sollen Spalten rechtsbündig angezeigt werden (z.B. bei Beträgen), kann dies in der Variable $alignright angegben werden. Dies geschieht in einem Array mit den Spaltennummern als Elemente. $alignright = array(4); //Umsatzspalte wird rechtsbündig
$sumcol Es kann eine Summierung der angezeigen Datensätze angezeigt werden im Footer der Tabelle $sumcol = 4; die Umsätze werden summiert angzeigt.Ab Xentral 16.4 kann dies auch als array geschrieben werden, falls mehrere Spalten summiert werden.
xentral zieht automatisch aus dem ActionHandler Informationen im Konstruktor, die Infos für die Rechteverwaltung.
Um ein Widget zu erweitern, muss das Originalwidget inkludiert werden und die Original-Klasse mit einem Custom angehängt und überladen werden. Beispiel Auftragwidget:
<?php
include_once ("widget.order.php");
class WidgetOrderCustom extends WidgetOrder
{
...
Um das Programmieren zu vereinfachen kann in www/index.php die Zeile 'error_reporting(E_ERROR);' zu 'error_reporting(E_ALL);' geändert werden. Dadurch werden Syntaxfehler nicht mehr vom Parser verschluckt. Allerdings sollte die Option wieder auf den ursprünglichen Status zurückgesetzt werden, wenn diese nicht mehr gebraucht wird, da unter Umständen sensible Daten ausgegeben werden können.