Geschrieben von Christian Schnettelker

Schlagwörter: , ,

Sessions in Joomla

Neue Projekte, neue Herausforderungen. Für die Kostenberechnung innerhalb eines Auftritts, welche sich über mehrere Seiten erstreckt, benötigte ich die Funktion, dass gewählte Einstellungen der einzelnen Seiten zwischengespeichert werden.

Diese Daten sollen a) später bei Neuaufruf der Seiten geändert werden können und b) anschließend für die endgültige Berechnung zur Verfügung stehen.
Joomla Session Handling
Üblicherweise macht man sowas mit sogenannten „Sessions“, über PHP und eine Session-ID sind die abgespeicherten Daten dann zugänglich. Session-Programmierung in PHP ist nichts Neues und es gibt im Netz hunderttausende gute (und schlechte) Anleitungen dazu.

In meinem ersten HTML-Entwurf der Seite funktionierte auch alles soweit ganz gut, mal abgesehen davon, dass bei abgeschalteten Cookies, in denen die Sesssion-ID abgelegt wird, wie erwartet nichts mehr lief.

Kollision

Bei der Übertragung des Entwurfes hin zu Joomla stand ich jedoch vor dem Phänomen, dass die vorab programmierte Session-Verwaltung nicht arbeiten wollte, es wurden einfach keine Daten abgespeichert, egal, was ich probierte.

Wieder einmal war es eine Recherche im Netz, die mich darauf brachte, dass die nativen PHP-Sessions mit der in Joomla eingebauten Session-Verwaltung kollidieren können. Ich erfuhr weiter, dass Joomla eine eingebaute Session-Verwaltung besitzt, die sich nutzen lässt. Dieses Vorgehen hat die folgenden Vorteile:

  • Relativ einfaches Handling, Joomla übernimmt die meiste Arbeit
  • Die Session-Daten werden von Joomla in der MySQL-Datenbank gespeichert
  • Alle Session-Daten werden verschlüsselt

Um das Rad nicht neu erfinden zu müssen stellte ich also meine PHP-Programmierung entsprechend um. Leider gab es einmal mehr Probleme mit unvollständigen Code-Bespielen, die erst nach Modifikationen wirklich funktionierten – entweder hat man hier schlampig gearbeitet oder geht von Voraussetzungen aus, die mir nicht bekannt sind. Wie auch immer…

Code-Beispiele für den Zugriff auf Joomla-Sessions

…hier die Funktion, die die Session-Verarbeitung initialisiert:

function __session_init()
   {
   define( '_JEXEC', 1 );
   define( 'JPATH_BASE', realpath(dirname(__FILE__) . '/..' ));
   define( 'DS', DIRECTORY_SEPARATOR );

   require_once( JPATH_BASE .DS. 'includes' .DS. 'defines.php' );
   require_once( JPATH_BASE .DS. 'includes' .DS. 'framework.php' );

   $mainframe =& JFactory::getApplication( 'site' );
   $mainframe->initialise();

   // Wenn noch nicht initialisiert Daten jetzt zurücksetzen,
   // andernfalls Zugriffszähler erhöhen
   $session =& JFactory::getSession();
   if ( $session->get( 'is_init' ) != true ) ____session_reset();
   else { $n = $session->get( 'counter' );
          $session->set( 'counter',++$n );
        }
   }

Der untere Teil nach dem Kommentar ist optional, ich überprüfe hier, ob die Initialisierung erfolgt ist und zähle mit, wieviele Zugriffe stattgefunden haben.

Wichtig ist, den Pfad zu <joomla-installation>/includes/defines.php und <joomla-installation>/includes/framework.php in JPATH_BASE korrekt anzugeben, da diese über require_once() zwingend benötigt werden. Da mein PHP-Skript in <joomla-installation>/php/ liegt muss ich folgerichtig, von realpath(dirname(__FILE__)) ausgehend, das php-Verzeichnis per /.. verlassen, damit die Pfadangabe stimmt.

Natürlich können Sie die Pfade auch direkt angeben, dass ist viel einfacher, sieht dann aber nicht so wunderbar verwirrend aus. Den Quark mit dem DIRECTORY_SEPARATOR habe ich mal so gelassen, auch das lässt sich direkt über /includes/ „verdrahten“.

Hier der Vollständigkeit halber meine oben referenzierte Funktion zum Reset der Daten:

function ____session_reset()
   {
   $session =& JFactory::getSession();
   $session->set( 'is_init', true );
   $session->set( 'counter', 0 );
   $session->set( 'name', "undefiniert" );
   $session->set( 'beruf', "undefiniert" );
   }

Statt die Einträge mit „undefiniert“ zu überschreiben lassen sich diese auch mittels $session->clear(‘name‘); komplett löschen. Das Schreiben von Daten in die Session funktioniert dann wiefolgt:

 __session_init();
   $session =& JFactory::getSession();
   $session->set( 'name', "Winnetou" );
   $session->set( 'beruf', "Häuptling der Apachen" );

So einfach ist das! Wenn Daten aus z.B. einem Formular übernommen werden sollen schreiben Sie etwas wie:

 __session_init();
   $session =& JFactory::getSession();
   $session->set( 'name', $_POST['name'] );
   $session->set( 'beruf', $_POST['beruf'] );

Um später die Daten aus der Session wieder auszulesen:

 __session_init();
   $session =& JFactory::getSession();
   $name = $session->get( 'name' );
   $beruf = $session->get( 'beruf' );

Wichtig ist, dass vor jedem Zugriff auf die Daten __session_init() aufgerufen wird, sonst funktioniert es nicht – das kennen Sie aber wahrscheinlich von den nativen PHP-Sessions. Zuguterletzt wollen Sie vielleicht aufräumen, das erledigt der folgende Code:

 __session_init();
   $session =& JFactory::getSession();
   $session->destroy();

Soweit ich es verstanden habe besorgt Joomla das Löschen von abgelaufenen Sessions aus der Datenbank automatisch, darum brauchen wir uns also nicht zu kümmern. Die Laufzeit einer Session ist über

   $session->getExpire();

abrufbar, bei mir wird von dieser Funktion ein Wert von 7200 zurückgegeben, was 7200 Minuten (5 Tage) entspricht. Alle Funktionen der Klasse JSession sind unter docs.joomla.org/API17:JSession aufgelistet. Noch ein Hinweis, in der Joomla-Konfigurationsdatei configuration.php steht der Session-Handler in der Voreinstellung auf

public $session_handler = 'database';

Das bedeutet, dass Joomla die Sessions wie gewünscht in der MySQL-Datenbank abgelegt. Falls hier „none“ stehen sollte werden die Sessions als Datei im Server gespeichert.

Cookies deaktiviert

Wie bereits erwähnt kann es vorkommen, dass der Nutzer seinen Browser so eingestellt hat, dass dieser keine Cookies zulässt. In diesem Falle funktioniert auch die Session-Verwaltung mit Joomla nicht korrekt, daher leite ich diese Nutzer per Javascript auf eine Hinweisseite weiter, z.B. so:

function areCookiesEnabled() {
   document.cookie = "__verify=1";
   var supportsCookies = document.cookie.length >= 1 &&
   document.cookie.indexOf( "__verify=1" ) !== -1;
   var thePast = new Date( 1980,9,11 );
   document.cookie="__verify=1;expires=" + thePast.toUTCString();
   return supportsCookies;
   }
if ( !areCookiesEnabled() ) window.location.href = "http://www.manoftaste.de/fehler/cookies-deaktiviert.html";

Das wars…

Wie immer hoffe ich, dass alles korrekt ist und dem einen oder anderen weiterhilft. Falls dies der Fall ist oder Sie einen Fehler gefunden haben bzw. eine Anmerkung einbringen möchten freue ich mich, wenn Sie einen Kommentar hinterlassen.

Kommentare

Kommentare

Kommentar schreiben

Aufgrund neuer rechtlicher Bestimmungen habe ich die Kommentarfunktion meines Blogs vorübergehend deaktiviert und muss Sie vorerst bitten, Kommentare per Email an mail [at] manoftaste.de zu senden.