Aufbau

Guite edited this page Nov 12, 2014 · 3 revisions
Clone this wiki locally

=== Aufbau eines Moduls === Ein Zikula-Modul ist aus verschiedenen Dateien aufgebaut, die in einem gemeinsamen Verzeichnis liegen. Dieses Verzeichnis trägt den Systemnamen des Moduls. Diese Verzeichnis wiederum wird im ''/modules/''-Verzeichnis von Zikula abgelegt.

'''Beispiel:''' Das Verzeichnis von Pagesetter heißt ''/pagesetter/'' - Der Displayname wird in diesem Fall im Gegensatz zu dem Systemnamen groß geschrieben. Den Displaynamen kann ein Webmaster in der Modul-Verwaltung selbst ändern, wie er will. Entsprechend egal ist es, wie der Systemname eines Moduls lautet - hauptsache er kommt im System nur einmal vor. Wenn Du also planst ein neues Modul zu schreiben und es zu veröffentlichen, solltest Du Dich vorher erkundigen, ob es schon ein Modul mit diesem Namen gibt.

=== Elemente === Ein Modul besteht aus folgenden Teilen:

==== Persistenzschicht / Installation ==== Zu jedem Modul gehören 3 Installationsdateien:

{| border=1 class="wikitable" |''/modules/MODULNAME/pnversion.php'' |Metadaten |/Module/pnversion |- | ''/modules/MODULNAME/pntables.php'' | Model | /Module/pntables |- | ''/modules/MODULNAME/pninit.php'' | Installationsroutinen, Upgrades usw. | /Module/pninit |}

==== Domänenschicht / API ====

Die API ist dafür zuständig, die Daten aus der Datenbank zu holen, sie hinein zu schreiben, zu verändern und zu löschen. Typischerweise wird die API aufgeteilt in Admin-Funktionen und User-Funktionen:

  • pnuserapi.php
  • pnadminapi.php

In der pnuserapi.php befinden sind die get-Funktionen, mit denen die Daten angezeigt (SELECT, COUNT, ..) werden: Als Liste oder einzeln. In der pnadminapi.php befinden sich die Funktionen zur Manipulation der Daten: INSERT, UPDATE, DELETE. Außerdem gibt es hier einen Helfer-Funktion, die die Zikula-Administration benötigt, um in der Administration das Modul-Menü anzuzeigen:

 pnModURL('example', 'user', 'view'),
                         'text' => pnML('_EXAMPLE_USERVIEW'));

    // Hier wird ein Link hinzugefügt, der bestimmte Zugriffsrechte erfordert
    if (SecurityUtil::checkPermission('example::', '::', ACCESS_ADMIN)) {
        $links[] = array('url' => pnModURL('example', 'admin', 'config'), 'text' => _MODIFYCONFIG);
    }

    // Fertig
    return $links;
}

API-Funktionen geben '''niemals''' HTML zurück. Stattdessen sollten sie immer Arrays oder Objekte - oder einfache Daten - zurückgeben.

==== Funktionsnamen ==== Die Namen von API-Funktionen sind nach diesem Schema aufgebaut: MODULENAME_APITYP_FUNKTIONSNAME

  • Eine Funktion in der pnuser.php des Moduls "example" heißt entsprechend: ''example_userapi_irgendwas()''
  • Eine Funktion in der pnadmin.php des Moduls "example" heißt entsprechend: ''example_adminapi_irgendwas()''

Du kannst auch neben der User- und Admin-API andere APIs anbieten. Zum Beispiel:

  • pnconvertapi.php - Dort heißen Funktionen dann nach dem Schema: ''example_convertapi_irgendwas()''

==== API-Funktionen aufrufen ==== Mit pnModAPIfunc() kannst Du API-Funktionen des eigenen oder anderer Module aufrufen:

pnModAPIfunc('MODULENAME', 'API-TYP', 'FUNKTION', array('PARAM1' => 'VALUE1') )

Also zum Beispiel:

pnModAPIfunc('example', 'user', 'get', array('uid' => 1) )

Ruft dann ''example_userapi_get($params)'' auf.

==== Tipp ====

Du solltest Objekt-orientiert arbeiten. Dazu kannst Du unter ''/modules/MODULENAME/pnclasses/'' Deine Klassen ablegen. Die APIs benutzt du dann nur als Wrapper. Die sind jetzt noch nötig, da nicht alle Teile des System Objekt-orientiert sind und man zum Beispiel aus Templates zur Zeit nur auf API-Funktionen zugreifen kann.

==== Kontrollschicht ====

Die Funktionen aus der Kontrollschicht sind dann die Funktionen, die die Benutzer per URL aufrufen. Sie nehmen sozusagen den Benutzerwunsch auf, und holen sich per API die nötigen Daten aus der Persistenzschicht (Datenbank). Diese Art Funktionen können genau wie die API-Funktionen auf verschiedene Dateien im Hauptverzeichnis des Moduls verteilt werden. Zum Beispiel:

  • pnuser.php
  • pnadmin.php

Hier ist die Aufteilung so, dass in der pnuser.php quasi das Frontend steckt - all das, was normal User sehen sollen. Und in der pnadmin.php stecken die Admin-Funktione fürs Backend: Konfiguration usw.

Daneben ist es möglich weitere Typen einzuführen. Eine Reihe Module nutzt zum Beispiel pnedit.php für alle UPDATE-, INSERT- und DELETE-Vörgänge, da sie sowohl aus dem Frontend wie auch aus dem Backend aufgerufen werden könnten.

Die Aufteilung in die Dateien hat mehr einen logischen als einen praktischen Hintergrund - es können auch einfach alle Funktionen in der pnuser.php landen...

==== Funktionsnamen ====

Die Funktionen in diesen Dateien werden so ähnlich benannt wie in der API. Zum Beispiel:

  • example_user_display($params) - in der pnuser.php
  • example_admin_main($params) - in der pnadmin.php

==== Verlinken ====

Um eine solche Funktion aufzurufen, benutzt Du URLs wie diese:

  • ''index.php?module=example&type=user&func=display&exampleid=1'' - Du siehst, dass hier wieder die Teile des Funktionsnamens auftauchen. Alle weiteren Parameter werden der Funktion als Array weitergereicht. Übrigens kannst Du in URLs den type=user weglassen. Der ist Default-Typ und wir von Zikula angenommen, wenn kein Typ angegeben ist.
  • ''index.php?module=example&type=admin&func=main'' - Diese URL ruft die main-Funktion aus der pnadmin.php auf. Main ist aber auch die Default-Funktion, die aufgerufen wird, wenn keine angegeben ist.
  • ''index.php?module=example'' - diese URL würde entsprechend Zikula annehmen lassen, dass type=user und func=main des Moduls "example" gemeint sind.

==== Inhalt ====

Eine Funktion in der Kontrollschicht sollte im Prinzip so aussehen, dass sie die nötigen Daten per API holt, sie vorbereitet und dann der Präsentationsschicht übergibt, um dem Benutzer die Ausgaben zu zeigen. Die Präsentationsschicht ist in diesem Fall ein pnRender-Objekt. pnRender ist eine Zikula-Klasse, die von /Smarty erbt. Entsprechend stehen Dir zunächst mal alle Methoden zur Verfügung, die [http://smarty.net Smarty] bietet.

Zunächst aber musst Du pnRender instantiieren. Um nicht unnötig viele Objekte vorzuhalten, benutzt Du am besten folgende Methode, die das Objekt nur instantiiert, wenn keines vorhanden ist. Sonst wird das vorhandene benutzt:


Die wichtigste und die am häufigsten benutzte Methode ist danach wohl:

assign('parameter', $wert);

In dieser Art übergibst Du alle Daten an das $render-Objekt. Zu Schluss gibst Du noch an, wie das Template heißt, an dass Du die Daten übergeben möchtest:

fetch('example_user_display.htm');

Damit schließt eine typische Funktion in der Kontrollschicht.

Du siehst, dass sich im Namen des Templates der Name der Funktion widerspiegelt. Das macht das auffinden des passenden Templates zu einer URL leichter.

==== Präsentationsschicht ====

Es sollten keine Ausgabe direkt aus dem PHP gemacht werden - echo() ist verboten. Wie oben erklärt sollten alle Daten an die Präsentationsschicht übergeben werden. Diese regelt die Ausgaben über Templates. '''Weiterlesen:''' [[/Templates|Was sind Templates?]]

Die Templates liegen unter ''/modules/MODULNAME/pntemplates'' und wie oben geschildert, sollten sie nach den Funktionen benannt werden, die sie aufrufen, damit sie leichter zu finden sind.

==== Beispiel ====

  • Stellen wir uns vor in der Kontrollschicht gäbe es eine Funktion dieser Art:
assign('parameter', 'Hello '.$paramswer.'!' );

    // Ans Template übergeben
    return $render->fetch('example_user_test.htm');
}
  • Dann könnte in dem Template example_user_test.htm stehen:

  • Dann rufst Du die URL auf: ''index.php?module=example&type=user&func=test&wer=World''

  • Im Browser erschiene dann im Layout der Site:

'''Hello World! '''

=== Übersicht ===

Hier noch einmal alle 4 Teile in der Übersicht und wo Du sie findest:

'''Persistenzschicht'''

  • ''/modules/MODULNAME/pnversion.php''
  • ''/modules/MODULNAME/pntables.php''
  • ''/modules/MODULNAME/pninit.php''

'''Domänenschicht / API'''

  • ''/modules/MODULNAME/pnuserapi.php''
  • ''/modules/MODULNAME/pnadminapi.php''
  • ''/modules/MODULNAME/pnclasses/''

'''Kontrollschicht'''

  • ''/modules/MODULNAME/pnuser.php''
  • ''/modules/MODULNAME/pnadmin.php''

'''Präsentationsschicht'''

  • ''/modules/MODULNAME/pntemplates/''

Daneben gibt es noch eine Reihe anderer Techniken in Zikula, die in weiteren Artikeln erklärt werden sollen.