Session Handling in Contao

Contao hat eine sehr einfache Abstraktion zur Handhabung von PHP Session Informationen. Die betreffende Contao-Klasse heißt schlicht Session. Es handelt sich dabei um eine Singelton-Klasse, d. h. wir können über eine statische Methode eine Instanz der Klasse holen:

$session=Session::getInstance();

Damit können wir nun Daten in die Session schreiben und auslesen. Dazu stehen die Methode get() und set() zur Verfügung. Das wars auch schon im groß und ganzen. Die Abstraktion schreibt die Daten im Destruktor in die Session (innerhalb der Klasse werden die Werte als assoziatives Array gespeichert). Das bedeutet, dass zur Laufzeit die Werte in der PHP Session ($_SESSION) nicht sofort zur Verfügung stehen, sondern erst beim nächsten Request.

Um zu prüfen, ob ein Wert bereits hinterlegt wurde, muß auf die get()-Methode zurückgegriffen werden.

Der Entwickler muß sich selbst um eventuelle Nameskonflikte kümmern, denn sonst werden gleiche Schlüssel mit dem jeweils letzten Wert überschrieben. Ein Namespace-Mechanismus gibt es lediglich für die Backend- und Frontend-Session.

Contao: 403/Forbidden auf tl_files

Ich möchte hier kurz festhalten, dass ich Probleme hatte, Bilder aus dem tl_files Verzeichnis direkt aufzurufen. Zuerst dachte ich an eine falsche htaccess Konfiguration. Als ich das jedoch ausschließen konnte, habe ich mir die Dateirechte genauer angeschaut. PHP lief nicht im SafeMode, weshalb die Problematik der unterschiedlichen Benutzer nicht gegeben war. Der Datei selbst hatte ich versuchsweise alle Rechte gegeben (777). Dies führte jedoch nicht zum Erfolg. Bei Aufruf bekam ich immer noch einen 403/Forbidden. Schließlich half mir das System-Check-Tool von Contao auf die Sprünge. Die Verzeichnisse hatten falsche Berechtigungen. Als ich diese auf den empfohlenen Wert setzte (750) konnte ich das Bild (endlich) aufrufen.

Logging in Contao

Contao hat einen sehr einfachen Log-Mechanismus. Die Klasse System hat eine Methode log, die drei Parameter entgegen nimmt:

/**
 * Add a log entry
 * @param string log message
 * @param string e. g. class method name
 * @param string category
 */
 protected function log($strText, $strFunction, $strAction)

Die Einträge werden in der Datenbank in der Tabelle tl_log gespeichert. Continue reading

Ein Blick in ein Contao-Widget

Heute will ich das TextField betrachten. Ich möchte in einem Modul ein einfaches Formular umsetzen und natürlich will ich wenn möglich bestehenden Code wiederverwenden. Eine Textbox möchte ich mit dem Widget TextField umsetzen. Soweit ich das verstanden habe ist ein “Widget” in Contao ein Element in einem Formular. Im Klassenkommentar der abstrakten Klasse Widget steht: “Provide methods to handle form widgets”. Wie sieht TextField nun aus und wie kann es verwendet werden?

Continue reading

Warum ist Contao so schnell?

In letzter Zeit habe ich mich vermehrt mit Contao beschäftigt. Deswegen will ich in diesem Artikel über die technischen Aspekte von Contao beschäftigen und eben auch ein paar Worte zur Programmierung verlieren. Erst vor kurzem hatte ich von einer mittelständigen Firma erfahren, dass Contao im Backend sehr schnell sei und andere Content-Management-Systeme sich davon eine Scheibe abschneiden sollten. Zumindest ist eines richtig: Contao ist schnell. Leo Feyer selbst spricht in seinem Buch “Das offizielle Contao-Buch” von bis ca. 60% schneller als andere CMS. Aber wo Licht ist, ist natürlich auch Schatten. Aber warum ist Contao schnell? Es gibt zwei wichtige Punkte:

  1. Contao verwendet mySQL und die Storage-Engine MyISAM
  2. Contao verzichtet auf ein komplexes ORM. Die Abfragen werden direkt in SQL verfasst.

Informationen über MyISAM habe ich bereits in “Fakten über MyISAM” aufgeführt. Sollte also eine Seite realisiert werden,  bei der mit sehr vielen konkurrierenden Schreibzugriffen zu rechnen ist, dann muß man mit Contao einen erhöhten Aufwand betreiben und Teile der Datenbank beispielsweise unter InnoDB betreiben, z. B. müßte man den Locking- und Transaktionsmechanismus vorwiegend selbst ergänzen.

Das Contao auf ein sogenanntes object-relational mapping, kurz ORM, verzichtet hat den Nachteil, dass der Entwickler mehr Verantwortung beim kreieren seiner SQL-Queries hat. Wer z. B. mit Typo 3 und dem ORM von Extbase gearbeitet hat, der weiß ganz sicher, welche Vorteile ein gutes ORM hat.

Klassen in Contao überschreiben

Um Klassen in einem Contao Modul zu überschreiben, wird in der config/config.php die eigene Klasse registriert:

$GLOBALS['FE_MOD']['navigationMenu']['navigation'] = ModuleMeineUeberschriebeneNavigationKlasse

Wir wollen ja eine bestehende Klasse erweitern, deswegen muß sich der Eintrag mit einem bestehenden Modul decken. Am besten schaut man dazu in das entsprechende Modul. Anschließend definiert man die Klasse im eigenen Modul-Ordner. Bitte darauf achten, dass der Ordner im Alphabet nach dem zu überschreibenden Modul kommt, da Contao die Module in alphabetischer Reihenfolge einliest. Die Klasse selbst leitet dann von der bereits vorhandenen Klasse ab:

class ModuleMeineUeberschriebeneNavigationKlasse extends ModuleNavigation
{
  // Hier wird Funktionalität überschrieben / erweitert
}

Ein eigener inputType in Contao

Ursprünglich wollte ich nur den Wert des tstamp Feldes eines Contao Backend Modules als Informationsfeld anzeigen lassen. Ich dachte, dass gibts sicherlich und deswegen schaute ich auf die Contao Dokumentation “Internal structure of a Data Container Array” unter den bereits vorhandenen Feldern nach. Zu meiner Verwunderung gab es da unter Felder nur folgende Liste:

  • text Textfeld
  • password Passwortfeld
  • textarea Textarea
  • select Drop-Down-Menü
  • checkbox Checkbox
  • radio Radio-Button
  • radioTable Tabelle mit Bildern und Radio-Buttons
  • inputUnit Textfeld mit Drop-Down-Menü zur Auswahl der Einheit
  • trbl Vier Textfelder mit Drop-Down-Menü zur Auswahl der Einheit
  • chmod CHMOD-Tabelle
  • pageTree Seitenbaum
  • fileTree Dateibaum
  • tableWizard Tabellenassistent
  • listWizard Listenassistent
  • optionWizard Optionsassistent
  • moduleWizard Modulassistent
  • checkboxWizard Checkbox-Assistent

Abgesehen von den ganzen Exoten gab es kein Feld, dass den Wert nur als “Label”, also als einfachen String anzeigt. In meinem Fall benötige ich ein Feld, dass einen Timestamp in ein Datum umwandelt und im Backend anzeigt.

Continue reading

CSS und Javascript Dateien in einem Contao Modul einbinden

CSS und Javascript Dateien können sehr pragmatisch in einem Contao Modul eingebunden werden. Folgender Code demonstriert das:

// append custom js
$GLOBALS['TL_JAVASCRIPT'][] = '/system/modules/meinmodul/html/js/common.js';
 
// append custom css
$GLOBALS['TL_CSS'][] = '/system/modules/meinmodul/html/css/search.css';

Als einziges muß man beachten, dass man im eventuell überschriebene fe_page-Template die Variablen <?php echo $this->stylesheets; ?> und <?php echo $this->head; ?> nicht entfernt hat. Es gibt noch eine weitere Variable, die in diesem Zusammenhang ganz interessant ist:

$GLOBALS['TL_HEAD'][] = '<script type="text/javascript">// <![CDATA[
mce:0
// ]]></script>';

Wie wir hier sehen, kann man damit auch leicht eigene Javascript-Blöcke in den Head-Bereich der Seite bekommen.

Falls man jedoch Javascript am Ende der Seite benötigt, kann dies über

$GLOBALS['TL_MOOTOOLS'][]='<script ... />

in die Seite einbinden. Wer sich etwas tiefer damit befassen will, kann ja einen Blick in die Datei \system\modules\frontend\PageRegular.php wagen. Dort werden diese Variablen ausgewertet und dem Template hinzugefügt.

Update

Weil ich immer wieder mal gefragt werde, hier auch der Weg, wie man eigenes CSS und Javascript über Contao einbinden kann, ohne ein Modul zu programmieren:

In der Theme einfach unter den Experten-Einstellungen in den zusätzliche <head>-Tags beliebige CSS und Javascript-Dateien einbinden:

Contao: CSS und Javascript im Backend einbinden

 

Contao und InnoDB

Irgendwo im Internet habe ich gelesen, dass das Installationstool nicht mit InnoDB funktioniere. Jedoch hat das Anlegen einer neuen Tabelle mit der Contao Version 2.9.4 ohne Probleme funktioniert. Was nicht ging, ist der Wechsel der Engine einer bestehenden Tabelle von MyISAM zu InnoDB. Dies ist aber auch besser so und sollte immer manuell durchgeführt werden.