Ich habe mal kurz etwas zusammengeschrieben, fr die Leute, die sich mit phpChrystal intensiver beschftigen (readme in /cvsroot/phpchrystal/phpchrystal/onlinedocu/CVS-DEVELOPER):
---CUT---
Understandig phpChrystal
---
Fr alle zuknftigen Modul- oder CVS-Entwickler, drfte die grundlegende Struktur von
phpChrystal sicherlich interessant sein.
Aus diesem Grund soll diese Readme einen Einblick in den Aufbau des Intranetsystems
und bestimmten charakteristischen Merkmalen bieten.

Fangen wir mit der "Schale" an: Die einzelnen Module liegen generell immer im Mainordner
in dem phpChrystal installiert worden ist, also z.B. /phpChrystal.
Alle Module fangen mit dem Prefix "php" an, der darauf folgende Name kennzeichnet die Bedeutung
des Moduls, so dass man z.B. bei "phpLogin.php" sofort wei, dass es sich um die Login-Prozeduren
handelt.
Zu jedem Modul gehrt eine XML-Datei im Ordner /xmlmods/[language] ([language] ist die aktuell
ausgewhlte Sprache des Intranetsystems, z.B. "german"). Die Datei lautet dann genau so wie der Modulname,
also z.B. statt "phpLogin.php" "phpLogin.xml".
Der Aufbau der XML-Datei ist relativ einfach zu verstehen:

XML-Modul-Datei:
---
Der Abschnitt <entry id = "modul">...</entry> legt die Eigenschaften des Moduls fest.
In den vorherigen Versionen fanden die Einstellungen noch in den eigentlichen Modulen statt, dies wurde
aber gendert, damit die Einstellungen auch in andere Sprachen bersetzt werden knnen.

Die Abschnitte <entry id = "include">...</entry> legt die zu ladenden Klassen-Dateien im Ordner
/classes fest. Soetwas gab es bis zur Version 0.065 bei den einzelnen Modulen nicht. Vorher war es mglich
gewesen, alle Klassen sofort anzusprechen. Allerdings hat das Developer-Team die Module nun ausgelagert
und dadurch einen groen Performance-Vorsprung erreicht.

Die Abschnitte <entry id = "usermenu">...</entry> legen Submenu-Eintrge in dem Usermenu von phpChrystal
fest. Hierbei existiert der Tag <link cmd = "[my_cmd]">[name of link]</link>.
[my_cmd] wird an den Link in den Submenu-Eintrgen hinzugefgt, so dass der Link dann folgendermaen aussieht:
<a href="phpLogin.php?cmd=my_cmd">name of link</a>

Die Abschnitte <entry id = "adminmenu">...</entry> sind analog zu "usermenu" zu betrachten, nur dass sie
in der Administration von phpChrystal erscheinen.

Sprachdateien:
---
Neben den XML-Moduldateien  gehrt auch eine Sprachdatei zu den Modulen. Diese PHP-Datei trgt den Namen des
Moduls mit einem angehngten ".lang.php", also z.B. "phpLogin.lang.php".
Die Sprachdatei wird whrend des Aufrufes einer Modul-Seite geladen, dabei wird assoziative Array $lang[]
(Hash fr Perl-Programmierer) global verfgbar gemacht.
Die Array-Eintrge haben folgende Form: "modul.entry" => "[text]".
Der Programmierer kann spter diesen Texten Parameter bergeben. Dazu existiert die Funktion
  $cxml->printString($lang['modul.entry'],$param_1,$param_2,...)
Hierbei wird aus dem Array $lang der Key 'modul.entry' geladen und zwei Parameter bergeben.
Die Parameter knnen mittels dem XML-Makro XML::PARAM::[number_of_param] angesprochen werden.
So htte z.B. der Text "Heute ist ein XML::PARAM::1 Tag zum XML::PARAM::2" mit dem Aufruf
  $cxml->printString($lang['my_text'],"schner","Sterben")
den Effekt, dass der String "Heute ist ein schner Tag zum Sterben" zurckgegeben wird.
Der Einsatz der Parameter ist besonders bei Variablen (Benutzernamen etc.) sinnvoll und auerdem kann
man dadurch die Satzstellung anderer Sprachen (Englisch, Spanisch etc.) bercksichtigen.

Der Stanard-Aufbau eines Moduls:
---
Der erste Abschnitt eines Moduls startet eine neue Session und definiert das Modul.
Danach kommen die wichtigen Design-Befehle:

  ((preg_match("/cmd_update/i",$cmd,$ret)) || (preg_match("/cmd_userupdate/i",$cmd,$ret))) ? (($opts[ref] = 1) && ($opts[ref_time] = 1) && ($cdesign->var_iAdmin = "1")) : ($opts[noopt]);
Diese ?:-If-Abfrage bewirkt, dass - wenn der String "cmd_update" oder "cmd_userupdate" in der URL vorhanden ist - die vorherige
Seite mit einer Verzgerung von einer Sekunde ($opts[ref_time] = 1) geladen wird ($opts[ref] = 1).

  if ($naked) {...}
Falls die Variable "naked" in der URL bergeben wurde, wird nach dem Aufruf des Moduls das Fenster auf eine
Minimal-Version resizt.

  $cdesign->createSiteHeader($opts);
Hier wird die HTML-Ausgabe gestartet und die Datei /templates/[template_name]/my.header geladen.
Auerdem wird mit diesem Befehl etwaige Redirects erzeugt.

  $cdesign->createSiteLayers($opts);
Hier wird nun die Datei /templates[template_name]/my.body geladen.

  if ((preg_match("/admin_/i",$cmd,$ret)) && session_is_registered("active_login"))
  {
    $opts[banner_links] = "images/adm.jpg";
    $cdesign->createModulesMenu($menu,"admin");
  }
Falls nun mit URL die Variable "cmd" bergeben wurde (z.B. cmd=admin_overview), diese Variable den String "admin_"
(kennzeichnet Administrations-Seiten eines Moduls) enthlt und der User als Administrator eingeloggt ist,
wird nun das Modul-Men aus der /xmlmods/[language]/[modulname].xml geladen (alle <entry id = "adminmenu">...</entry>-Eintrge).

  $cdesign->createInnerTable($opts);
Der Tabellen-Header wird nun an den Browser ausgegeben.

Nun folgen die einzelnen $cmd-Abfragen des Moduls. Wurde die Variable "cmd" nicht in der URL bergeben,
wird am Ende der Modul-Datei mit dem Befehl

  else
  {
    $cfunc->faultExt($cxml->printString($lang_def['fault.not_registered']));
  }

die Standard-Fehlermeldung "Dieser String ist nicht registriert" aus der /xmlmods/[language]/[language].lang.php geladen.

Geschlossen wird das Modul mit der Anweisung
  $cdesign->createSiteFooter($opts);
Hierbei wird nun die Datei /templates/[my_template]/my.footer geladen.

Funktionen und Rckgabewerte
---
Alle Funktionen, die Daten aus der MySQL-Datenbank laden ($cuser->getDBData()) etc. geben entweder BOOL
als Wert zurck oder aber ein assoziatives Array, welches generell bei mehreren mglichen Datenbankeintrgen
so aufgebaut ist, dass es wie folgt aufgebaut ist:
  $m_ar[[entry_id]]["key"] => "value";
[entry_id] ist hierbei die eine Zahl, beginnend bei "0", die mit einer for()-Schleife durchlaufen werden kann.
"key" ist der Schlssel auf den man zugreifen will.

Ausgabe der einzelnen Texte
---
Fr die Ausgabe der Texte wurde eine spezielle Klasse in /classes/CLayout.php entwickelt (die sogenannte Sovereign-Engine).
Sie parst alle Strings und bietet die Mglichkeit, dass mit nur wenigen nderungen in der CLayout.php
die einzelnen Tabellen-Strukturen gendert werden knnen.

Der wichtigste Befehl der $cl-Klasse ist
  $cl->cells2Noopt([col_1],[col_2],[return]);
Hierbei wird eine Tabellen-Zeile wie folgt erzeugt
  <tr>
    <td class=left>[col_1]</td><td class=right>[col_2]</td>
  </tr>
[return] legt fest, ob der String zurckgegeben ("return") oder aber sofort an den Browser gesendet werden soll ("out").

Daneben existiert u.a. die Funktion
  $cl->TableText($p_cl);
$p_cl ist ein Array, welches aus den einzelnen Spalten-Eintrgen zusammensetzt, z.B.:
  $p_cl[0][text] = "erster_text";
  $p_cl[0][p_class] = "left";
  $p_cl[1][text] = "zweiter_text";
  $p_cl[1][p_class] = "top";
  $p_cl[1][colspan] = "2";
wrde bedeuten, dass folgende Tabellen-Zeile generiert wird:
  <tr>
    <td class=left>erster_text</td>
    <td class=top colspan=2>zweiter_text</td>
  </tr>
Man muss sich die $cl-Funktionen wie eingefasse HTML-Befehle in einem Array vorstellen.