Kommen wir zum nächsten Teil meiner kleinen Reihe zur Extension-Entwicklung. Heute habe ich mich mal mit dem Entwurf der Klassenstruktur und den ersten Programmierschritten auseinandergesetzt.
UML-Entwurf
Vor Beginn der Programmierung habe ich ein UML-Klassendiagramm angefertigt, dass den grundlegenden Aufbau der Klassenstruktur zeigt. Zunächst habe ich nur grob die Klassen modelliert und einige wichtige Methoden definiert, da ich die Integration meiner Klassen in die TYPO3-Extension erstmal testen wollte. Zur Modellierung habe ich ArgoUML verwendet, das die Möglichkeit bietet, PHP5-Quellcode aus dem Modell generieren zu lassen. Daher stehen einige ArgoUML-spezifische Informationen und Kommentare im Quellcode, was aber nicht weiter schlimm sein dürfte. Nur die erste Zeile jeder generierten Datei error_reporting(E_ALL);
musste ich entfernen, da die Seite sonst aufgrund der zahlreichen “index not defined“-Fehler aus TYPO3 abstürzt.
Nach ein wenig Rumtesten bin ich zum Entschluss gekommen, meine Extension wie folgt abzubilden. Das Diagramm dürfte selbsterklärend sein, bis auf die Tatsache, dass ich überall, wo Arrays als Variablen übergeben werden, int eintragen musste, da ArgoUML sonst einen neuen Datentypen java_lang_Array erzeugt, den ich jedesmal händisch im Quellcode entfernen musste.
Einbinden der eigenen Klassen in die Plugin-Klasse
Die Plugin-Klasse tx_smemployeelist_pi1 kümmert sich um die Beschaffung der Datensätze aus der Datenbank und das Umwandeln in Arrays, die meine “eigenen” Klassen verarbeiten können. Somit bleiben diese später unabhängig von TYPO3 nutzbar. Vereinfacht gesagt werden alle Objekte unter Übergabe eines einzigen Arrays erzeugt, das die benötigten Daten für alle Attribute enthält. Damit verlagere ich die Verantwortung für die richtige “Zusammenstellung” dieser Arrays in die Plugin-Klasse (Methode CreateEmployeeFromDBRecord() erstellt z.B. solch ein Array für ein Employee-Objekt aus einem Datenbankeintrag).
Die benötigten Klassen müssen zunächst einmal in pi1/class.tx_smemployeelist_pi1.php inkludiert werden. Dazu habe ich eine Konstante definiert, die den absoluten Pfad der Extension enthält und dann jede benötigte Datei inkludiert.
/**
* The absolute path of the extension's directory.
*/
define('EMPLIST_ABSPATH', t3lib_extMgm::extPath('sm_employeelist'));
/**
* A single employee.
*/
require_once(EMPLIST_ABSPATH . 'classes/class.Employee.php');
Als Nächstes habe ich dann Methoden definiert, die meine Objekte erzeugen, wie z.B. die folgende, die aus einem Eintrag aus fe_users ein Employee-Objekt erstellt. Nun kann ich bequem mit meinen eigenen Objekten arbeiten.
/**
* Creates an Employee object from a fe_users DB-record.
*
* @param array $r The fe_user DB record.
* @return Employee An Employee object.
*/
private function CreateEmployeeFromDBRecord($r)
{
// fields from fe_users that can be used without transformation
$fields = array(
'id' => 'uid',
'title' => 'title',
'address' => 'address',
'zip' => 'zip',
'city' => 'city',
'country' => 'country',
'birthday' => 'birthday',
'image' => 'image',
'sex' => 'tx_smemployeelist_sex',
'hobbies' => 'tx_smemployeelist_hobbies',
'signature' => 'tx_smemployeelist_abbr',
'company' => 'company',
'firstentry' => 'tx_smemployeelist_firstentry',
'telephone' => 'telephone',
'fax' => 'fax',
'email' => 'email',
'website' => 'www',
'description' => 'tx_smemployeelist_description',
'username' => 'username',
'ipaddress' => 'tx_smemployeelist_ipaddress',
'lastwinlogon' => 'tx_smemployeelist_lastwinlogon',
'settings' => 'tx_smemployeelist_settings'
);
$e = array();
foreach ($fields as $k=>$v)
{
$e[$k] = $v;
}
// fields that need to be transformed
$name = explode(',', $r['name']);
$e['lastname'] = $name[0];
$e['firstname'] = $name[1];
// get departments and positions
$e['departments'] = array();
$depts = explode(',', $r['usergroup']);
foreach ($depts as $d)
{
$e['departments'][] = $this->departments[$d];
}
$e['positions'] = array();
$pos = explode(',', $r['tx_smemployeelist_positions']);
foreach ($pos as $p)
{
$e['positions'][] = $this->positions[$p];
}
return new Employee($e);
}
Nun kann ich wie folgt einen Mitarbeiter erstellen und seinen Namen ausgeben lassen (in Klasse tx_smemployeelist_pi1).
$res = $this->pi_exec_query('fe_users', 0, '');
$r = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
try
{
$emp = $this->CreateEmployeeFromDBRecord($r);
$content= $emp->GetFullName();
}
catch (Exception $e)
{
$content = $e->getMessage();
}
Das war’s auch schon wieder. Je nachdem, wie ich nun vorankomme, werde ich dann mal weitere interessante Details der Extension-Entwicklung veröffentlichen…