# Erstellen eigener moregroupware Module

In diesem Dokument erfahren Sie mehr dazu, wie Sie eigene Module für moregroupware erstellen können. Es beschreibt ebenso den Aufbau von moregroupware, den Sie benötigen, wenn Sie eigene Module erstellen wollen. Sie sollten nach dem Lesen dieses Dokuments in der Lage sein, eigene Module zu erstellen.

## Verzeichnisstruktur eines Moduls

Ein Modul liegt immer als eigenes Verzeichnis im moregroupware Wurzelverzeichnis. Für weitere Erklärungen nehmen wir das Kontaktmodul als Beispiel. Sie sehen hier die Verzeichnisstruktur des Moduls "Kontakt":

### Verzeichnisstruktur:

Modulverzeichnis

  Das Modulverzeichnis liegt im Wurzelverzeichnis der moregroupware Installation. Es muss zumindest folgende Unterverzeichnisse enthalten: inc, lang und templates. Alle direkt ausgeführten Scripts sollten ebenso in diesem Verzeichis liegen.

"include" Verzeichnis (inc)

  Das Verzeichnis "inc" beinhaltet Dateien mit modulspezifischen Funktionen oder Klassen.

  Eine Datei mit den Namen mmmm_func.inc.php (mmmm = Modulname) wird automatisch in die Scripts eingebunden. Mehr dazu später.

Sprachen (lang)

  Dieser Ordner enthält die Sprachdateien für das Modul und muss folgender Benennung entsprechen: mmmm.xx.lang (mmmm = Modulname, xx = Sprachcode).

  Die Sprachdateien werden automatisch verarbeitet, achten Sie auf richtige Benennung. Mehr dazu im Teil "Übersetzungen von moregroupware".

  Es sollte zumindest eine englische Sprachdatei (mmmm.en.lang) exisiteren. Wenn Sie selbst mehrere Übersetzungen einbringen können, fügen Sie diese Sprachdateien hinzu. Wie Sie oben sehen, gibt es für das Kontaktmodul bereits einige Übersetzungen.
Vorlagen (templates)

  Dieser Ordner enthält keine Dateien, sondern weitere Unterverzeichnisse. "default" ist die Standardvorlage für Ihr Modul, Sie sollten Ihre Vorlagen (Templates) in diesen Zweig platzieren (nicht direkt im Unterverzeichnis). Sie haben die Möglichkeit, weitere Unterverzeichnisse für andere Designs zu erstellen, z.B. "himmelblau". Derzeit wird diese Funktion allerdings nicht unterstützt, platzieren Sie alles im Ordner "default".

Ausgabevorlagen (html / wml)

  In diesem Verzeichnis liegen Ihre Seitenvorlagen. moregroupware bietet Ihnen die Möglichkeit, die Ausgaben in bestimmten Formaten zu gestalten. Derzeit können Sie die Ausgaben in HTML und WML definieren. Für ein neues Modul wird zumindest das Verzeichnis html benötigt, wml ist optional.

Medienverzeichnis (media)

  Dieses Verzeichnis beherbergt alle Bilder, Grafiken und andere Multimediaobjekte, die Sie in Ihrem Modul benötigen.

Ein minimales Modulverzeichnis sollte so aussehen:

### Minimales Modulverzeichnis

## Programmstruktur

Die folgenden Zeilen Code sind aus dem Script contacts/index.php entnommen. Es ist das Hauptscript des Kontaktmoduls. Wichtig für die Einbindung in moregroupware sind die ersten 5 Zeilen.

    <?php
          $myEnv["module"] = "contact";
          $myEnv["output"] = "html";

          include("../config.inc.php");
          include(INCLUDEPATH . "container.inc");

          // adding file revision into global array
          revisionInit("\$Revision: 1.6 $", __FILE__);

Die erste Zeile setzt den Namen des Moduls fest, dieser muss mit dem Verzeichnisname übereinstimmen. Dieser String wird in der kompletten Anwendung für die Pfadangaben verwendet. In der zweiten Zeile wird die Ausgabe festgelegt, normalerweise html.

Die nächsten zwei Zeilen können Sie ohne Änderungen in Ihr Script übernehmen. Im nächsten Kapitel wird näher darauf eingegangen.

In der letzten Zeile wird die Revisionsnummer der Datei in ein globales Array übergeben, um die Fehlersuche zu vereinfachen.

### Verwenden Sie niemals include($var/myinclude.php)!

Bitte verwenden Sie niemals die Funktion include wie oben beschrieben. Dadurch entsteht ein großes Sicherheitsloch. Arbeiten Sie nach folgendem Beispiel: include(ROOTPATH . "/folder/myinclude.php")

Greifen Sie immer mit $HTTP_*_VARS auf Dateieingaben zurück! Verlassen Sie sich nicht darauf, dass die Option "register_globals" aktiviert ist.

### Greifen Sie nicht manuell auf die Datenbank zu!

Wenn Sie Parameter wie $appconf["dbuser"] oder andere datenbankbasierenden Parameter entdecken, verwenden Sie diese nicht für eigene Datenbankverbindungen. Dazu bietet sich das automatisch generierte $conn ADOdb Objekt an, mehr dazu später.

## Wozu dient die Datei config.inc.php

Die Datei config.inc.php wird während der Installationsroutine erstellt. Darin werden wichtige Parameter für moregroupware gespeichert. Alle Parameter sind im Array $appconf gespeichert. Hier sehen Sie ein Beispiel:

    <?php
          // this file is auto-generated by setup, only modify if you are sure what you do
          // Config File
          // Moregroupware.org
          // programmed by Marc Logemann
          // 01/04/01 (c)
          $appconf["dbvendor"] = "mysql";
          $appconf["dbhost"] = "localhost";
          $appconf["dbuser"] = "mgwuser";
          $appconf["dbpassword"] = "mgwpass";
          $appconf["dbname"] = "moregw";
          $appconf["rooturl"] = "http://localhost/moregroupware";
          $appconf["rootpath"] = "/home/apache/moregroupware";
          $appconf["theme"] = "default";
          $appconf["auth_method"]= "sql";
          $appconf["auth_ldaptype"]= "0";//0 for openldap; 1 for ADSI
          $appconf["auth_ldaphost"] = "";
          $appconf["auth_ldapbase"] = "";
          $appconf["auth_ldapuid"] = "";
          $appconf["auth_ldappasswd"] = "";
          $appconf["auth_ldapsuffixe"] = "";
          $appconf["create_accounts_on_login"] = 0;
          $appconf["mgw_version"] = "";
          $appconf["mgw_releasedate"] = "";
          $appconf["def_language"] = "de";
          $appconf["def_charset"] = "iso-8859-1";
          $appconf["html_compressor"] = false;
          $appconf["html_compressor_debug"] = false;
          define("SMARTY_DIR", "/home/apache/mgw/include/smarty/");
          define("ROOTPATH","/home/apache/mgw");
          define("INCLUDEPATH","/home/apache/mgw/include/");
          ?>

Wissenswert ist, das Ihr Script, das mit den oben beschriebenen Zeilen beginnt, Zugang zum Array $appconf hat. Sie können benötigte Einstellungen direkt einbinden, wie z.B. $appconf["rooturl"] oder $appconf["rootpath"]. Sie können auch über die Konstanten ROOTPATH und INCLUDEPATH zurückgreifen, um Ihre Dateien einzubinden.

## Wozu dient die Datei container.inc?

Die Datei container.inc ist eine Sammlung von anderen Includes. Alle Includes werden in dieser Datei zusammengefasst. Alle darin enthaltenen Dateien beinhalte keine weiteren Includes. So existieren nur 2 Stufen von Includes: Die Datei container.inc und alle darin enthaltenen Includes. Unten der Inhalt der Datei container.inc:

    <?php
          /* $Id: coding_addmodule.xml,v 1.6 2003/11/01 21:41:06 emailtotom Exp $ */

          require_once(SMARTY_DIR . "Smarty.class.php");

          // definition of moregroupware class, holding application vars
          include(INCLUDEPATH . 'mgw.class.inc');

          // functions for translation
          include(INCLUDEPATH . 'lang.inc');

          // array for tracking file revision number used in sql error report screen
          $Revisions_array = Array();

          // important functions like connect to database
          include(INCLUDEPATH . 'userfunc.inc');

          // definition of moregroupware version and label
          include(INCLUDEPATH . 'version.inc');

          // Auto-Assigns for template engine and global definitions
          include(INCLUDEPATH . 'appconfig.inc');

          // include module specific functions if present (they are now in module/inc)
          // must be named module_func.inc.php (i.e. calendar_func.inc.php)
          if(file_exists(ROOTPATH . "/modules/" . $myEnv["module"]. "/inc/" . $myEnv["module"] . "_func.inc.php")) {
          include(ROOTPATH . "/modules/" . $myEnv["module"] . "/inc/" . $myEnv["module"] . "_func.inc.php");
          }

          // help system
          if(file_exists(ROOTPATH."/modules/".$myEnv["module"]."/help/index.".$MGW->spkz.".html")) $smarty->assign("helpurl", $myEnv["module"]."/help/index.".$MGW->spkz.".html");
          elseif(file_exists(ROOTPATH."/modules/".$myEnv["module"]."/help/index.en.html")) $smarty->assign("helpurl", $myEnv["module"]."/help/index.en.html");
          elseif(file_exists(ROOTPATH."/modules/general/help/index.".$MGW->spkz.".html")) $smarty->assign("helpurl","general/help/nohelp.".$MGW->spkz.".html");
          else $smarty->assign("helpurl","general/help/nohelp.en.html");

          // include module autoexecution of several things like translation, authentication, and more
          include(INCLUDEPATH . 'module_exec.inc');
          ?>

Im nächsten Abschnitt werden die Includes näher erklärt.

### require_once(SMARTY_DIR . "Smarty.class.php");

Diese Zeile ladet die Klassen von Smarty, die auch von anderen Includes (z.B: appconf.inc) und den Benutzerscripts verwendet werden. Ohne dieser Zeile kann eine Ausgabe gemacht werden.

### include(INCLUDEPATH .'mgw.class.inc');

Die MGW Klasse ist in der Session in Form eines Objekts gespeichert. Dieses Objekt enthält entsprechende Daten wie Sprachcode, Benutzername oder Benutzerrechte. Über dieses Objekt werden verschiedenste Abfragen gemacht, ohne auf die Datenbank zurückzugreifen. Eine nähere Beschreibung erfolgt später, weil diese Klasse sehr wichtig für Ihr Modul ist.

### include(INCLUDEPATH .'lang.inc');

Dieses Include verarbeitet die Sprachdateien und wird ebenso im Include appconf.inc und in Ihrem Script benötigt.

### include(INCLUDEPATH .'userfunc.inc');

An diesem Ort werden nützliche, systemweite Funktionen gespeichert. Diese Funktionen können in jedem Modul brauchbar sein. Platzieren Sie keine Funktionen für Aufgaben Ihres Moduls darin.

### include(INCLUDEPATH .'version.inc');

Im einfachsten Include werden nur die Releasenummer und der Name des Produkts gespeichert, die an verschiedenen Plätzen in moregroupware angezeicht werden, z.B. in der Statusleiste.

### include(INCLUDEPATH .'appconfig.inc');

Dies ist das komplexeste Include, es erledigt eine Menge von Funktionen, anschließend eine Liste, die für Programmierer interessant ist:

- Erstellung der Variable $appconf["gentemplates"], die zum allgemeinen Vorlagenverzeichnis (general/templates/html) zeigt. Sie wird zum Einbinden von HTML Teilen aus dem allgemeinen Ordner anstatt der Vorlagen aus dem Modulverzeichnis. In der Vorlage selbst können Sie diese Variable mit {$gentemplates} ansprechen.

- Erstellung der Variable $appconf["imgpath"] und $appconf["imgpathgeneral"], die den Pfad zum Bilderverzeichnis ("media") des Moduls oder des allgemeinen Bilderverzeichnis enthält. Sie werden diese Variable in der Vorlage benötigen und können Sie mit {$imgpath} und {$imgpathgeneral} ansprechen.

- Erstellung des $smarty Objekts, das die Ausgabe Ihres Moduls übernimmt. Sie werden Methoden wie $smarty->assign(), $smarty->append() oder $smarty->display() benötigen.

- Die Session wird in diesem Include gestartet.

- Folgende Variablen werden automatisch erstellt und können direkt in der Vorlage angesprochen werden: {$PHPSESSID} (akutelle Session des Benutzers), {$rooturl}, {$username}, {$userfullname}, {$phpself}, {$gwversion}, {$gwtitle}. Wenn Sie die Bedeutung nicht genau kennen, fügen Sie die Variable einfach in eine Vorlage ein und warten auf das Ergebnis.

- Erstellung der Menüleiste.

### include(INCLUDE .'module_exec.inc');

Das Modul module_exec ist das einzige Include, das Sie von außen ansteuern können. Die Operationen im Modul können durch Variablen beeinflußt werden. Lesen Sie dazu mehr im nächsten Abschnitt.

## Spezielle Eigenschaften von module_exec.inc

Sehen Sie sich das Script einmal an:

            // Authentication of User according his session (its not the main auth)
            if($myEnv["auth"] !== false) checkLogin();

            // Connect to database and return $db object
            if($myEnv["connectdb"] !== false) $db = connect_database();

            // do module translation and give back a hashmap with all keys and values
            if($myEnv["translate"] !== false) $hashmap = setLocaledText($MGW->spkz, $myEnv["module"]);

            // get user settingw and return them in $settings hashmap
            if($myEnv["getsettings"] !== false) $settings = get_settings($myEnv["module"]);

            // call standard module submenu (smenu.inc) and integrate it
            if($myEnv["stdsmenu"] !== false)
            if(file_exists(ROOTPATH . "/" . $myEnv["module"]. "/inc/smenu.inc"))
            include(ROOTPATH . "/" . $myEnv["module"] . "/inc/smenu.inc");
            else
            echo "<b>Error: </b>Program cannot find Submenu-Definition File (smenu.inc) in module \"inc\" folder. Please create this file or set \$myEnv[stdsmenu] to false in your program and define it there.";

Wie Sie sehen können, übernimmt das Include fünf Aufgaben:

- Überprüfen der akutellen Anmeldung (und Neuanmeldung, wenn ein Fehler auftritt)

- Verbindung zur Datenbank und Übergabe des Objekts $db

- Übersetzung des aktuellen Moduls und Übergabe in das Array $hashmap

- Übergabe von Einstellungen für das aktuelle Modul und den aktuell angemeldeten Benutzer (derzeit nicht in Verwendung)

- Erstellung des Untermenüs

...