Extbase: Session-Handler selbstgebastelt

TYPO3Extbase bietet in Sachen Persistenz ein grandioses Framework. Das Speichern von Objekten in der Datenbank ist Dank der Repositories kein Problem, die Hauptarbeit – die Verbindung zur Datenbank, Entscheidung ob INSERT oder UPDATE, die Generierung entsprechender Queries – wird dem Entwickler vom Framework abgenommen. Was die Speicherung von Objekten in der PHP-Session – zum Beispiel zur Implementierung eines Warenkorbes – angeht, kommt Extbase leider derzeit etwas stiefmütterlich daher. Abhilfe schafft ein selbstgebastelter Session-Handler, der als Work-Around bis zur Implementierung der Sessionbehandlung in Extbase dienen kann.

Ein eine Klasse für das Arbeiten mit der PHP-Session könnte in etwa so aussehen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Tx_MyExt_Domain_Session_SessionHandler implements t3lib_Singleton {
 
	/**
	 * Returns the object stored in the user´s PHP session
	 * @return Object the stored object
	 */
	public function restoreFromSession() {
		$sessionData = $GLOBALS['TSFE']->fe_user->getKey('ses', 'tx_myext_pi1');
		return unserialize($sessionData);
	}
 
	/**
	 * Writes an object into the PHP session
	 * @param	$object	any serializable object to store into the session
	 * @return	Tx_MyExt_Domain_Session_SessionHandler this
	 */
	public function writeToSession($object) {
		$sessionData = serialize($object);
		$GLOBALS['TSFE']->fe_user->setKey('ses', 'tx_myext_pi1', $sessionData);
		$GLOBALS['TSFE']->fe_user->storeSessionData();
		return $this;
	}
 
	/**
	 * Cleans up the session: removes the stored object from the PHP session
	 * @return	Tx_MyExt_Domain_Session_SessionHandler this
	 */
	public function cleanUpSession() {
		$GLOBALS['TSFE']->fe_user->setKey('ses', 'tx_myext_pi1', NULL);
		$GLOBALS['TSFE']->fe_user->storeSessionData();
		return $this;
	}
}

Im Controller könnten über das Repository mittels des SessionHandlers dann beliebige Objekte in der Session gespeichert werden und in der nächsten Action wieder vom Repository ausgelesen werden.

Ein kleines Beispiel:

Das Repository könnte in etwa so aussehen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Tx_MyExt_Domain_Repository_ObjectRepository extends Tx_Extbase_Persistence_Repository {
 
	/**
	 * The session handler
	 * @var Tx_MyExt_Domain_Session_SessionHandler
	 */
	protected $sessionHandler = NULL;
 
	public function __construct() {
		parent::__construct();
		// get an instance of the session handler
		$this->sessionHandler = t3lib_div::makeInstance('Tx_MyExt_Domain_Session_SessionHandler');
	}
 
	/**
	 * Returns the object stored in the user´s PHP session
	 * @return Tx_MyExt_Domain_Model_Object the stored Object
	 */
	public function findBySession() {
		return $this->sessionHandler->restoreFromSession();
	}
 
	/**
	 * Writes the object into the PHP session
	 * @return	Tx_MyExt_Domain_Repository_OjectRepository this
	 */
	public function writeToSession(Tx_MyExt_Domain_Model_Object $object) {
		$this->sessionHandler->writeToSession($object);
		return $this;
	}
 
	/**
	 * Cleans up the session: removes the stored object from the PHP session
	 * @return	Tx_MyExt_Domain_Repository_ObjectRepository this
	 */
	public function cleanUpSession() {
		$this->sessionHandler->cleanUpSession();
		return $this;
	}
}

Und ein kleiner Controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Tx_MyExt_Controller_SessionTestController extends Tx_Extbase_MVC_Controller_ActionController {
 
	/**
	 * The object repository
	 * @var Tx_MyExt_Domain_Repository_ObjectRepository
	 */
	protected $objectRepository = NULL;
 
	public function initializeAction() {
		// get an instance of the OBJECT repository
		$this->objectRepository = t3lib_div::makeInstance('Tx_MyExt_Domain_Repository_ObjectRepository');
	}
 
	public function storeObjectIntoSessionAction(Tx_MyExt_Domain_Model_Object $object) {
		$this->objectRepository->writeToSession($object);
		// ... do the usual stuff here, assign data to the view, redirect, whatever...
		$this->view->assign('object', $object);
	}
 
	public function restoreObjectFromSessionAction() {
		$object = $this->objectRepository->findBySession();
		$this->view->assign('object', $object);
	}
}

Im Repository stehen nun Methoden zum Auffinden und Speichern von Objekten in der PHP-Session mittels des Session-Handlers zur Verfügung. Das Repository fragt nun nicht die Datenbank-Wrapper ab, sondern bemüht den Session-Handler, der wiederum mit Hilfe des TYPO3-internen Session-Handlings der Klasse t3lib_div die zuvor Objekte ausliest oder speichert. Dabei werden die Objekte zuvor serialisiert bzw. vor der Rückgabe deserialisiert.
Dem Controller ist es letztendlich egal wo das Repository die Objekte herzaubert, Hauptsache es kommen auch die an, die er angefordert hat.

Am Rande:
Der Session-Handler implementiert das Interface t3lib_Singleton, wird vom TYPO3-Framework also nur ein einziges Mal instantiiert, sofern man die Instanz über t3lib_div::makeInstance() erzeugt. Ein “richtiger” Singleton wäre natürlich auch denkbar. Allerdings würde man sich damit von den Framework-Konzepten lösen. Ob das gut oder schlecht wäre, steht auf einem anderen Blatt.

8 Gedanken zu „Extbase: Session-Handler selbstgebastelt

  1. Jacco Van der Post

    Hi, I am using this in an old extension and it worked great, thanks a lot.
    However on TYPO3 6.2 this doesn’t work anymore.

    PHP Catchable Fatal Error: Argument 1 passed to TYPO3\CMS\Extbase\Persistence\Repository::__construct() must implement interface TYPO3\CMS\Extbase\Object\ObjectManagerInterface, none given

    It’s caused by public function __construct()

    Could you perhaps please update this so it works for 6.2?

    Thanks Jacco

    Antworten
  2. Xandi

    Vielen Dank, funktioniert wunderbar.

    Eine Kleinigkeit ist mir aufgefallen:
    protected $orderRepository = NULL;
    sollte wohl
    protected $objectRepository = NULL;
    heißen.

    Viele Grüße,
    Xandi

    Antworten
  3. Michael

    Klasse!
    Genau das habe ich gesucht.
    Da brauche ich das “Rad” nicht neu zu erfinden. ;-)

    Solche kleinen Schnipsel sind sehr hilfreich, und sparen Zeit bei der Umsetzung von Problemstellungen.

    Danke für das “zur Verfügung stellen”.

    Grüße
    Michael

    Antworten

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>