Sessionhandling in Extbase

Inspired by the article from Daniel Pötzinger how to implement session handling in Extbase, i have written some simple classes to implement a flexible and testable session storage management. Maybe it´s useful for others. But always be careful and bare in mind, that serializing some objects can lead to big problems. So maybe you have to implement some serialization logic in the magic methods __wakeup and __sleep of your object.

The Interface

/* * *************************************************************
 *  Copyright notice
 *
 *  (c) 2010 Sebastian Schreiber
 *  Contact: me@schreibersebastian.de
 *  All rights reserved
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ************************************************************* */

/**
 *
 * @package TYPO3
 * @subpackage ssch_fluid_extbase_helper
 *
 * @author Sebastian Schreiber <me@schreibersebastian.de>
 *
 * $Id: $
 */
interface Tx_SschFluidExtbaseHelper_Utility_Session_Storage_StorageInterface extends t3lib_Singleton {

    /**
     * @param mixed $data
     */
    public function isSerializable($data);

    /**
     * @param string $key
     * @param string $type
     */
    public function read($key, $type = '');

    /**
     * @param string $key
     * @param mixed $data
     * @param string $type
     */
    public function write($key, $data, $type = '');

    /**
     * @param string $key
     * @param string $type
     */
    public function remove($key, $type = '');

    /**
     * @param string $key
     * @param string $type
     */
    public function has($key, $type = '');

    /**
     * @param object $object
     * @param string $key
     * @param string $type
     */
    public function storeObject($object, $key = NULL, $type = '');

    /**
     * @param string
     * @return mixed
     */
    public function getObject($key, $type = '');

    /**
     * @return object
     */
    public function getUser();
}

The SessionStorage Class, which initalizes the concrete session storage object:

/* * *************************************************************
 *  Copyright notice
 *
 *  (c) 2010 Sebastian Schreiber
 *  Contact: me@schreibersebastian.de
 *  All rights reserved
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ************************************************************* */

/**
 *
 * @package TYPO3
 * @subpackage ssch_fluid_extbase_helper
 *
 * @author Sebastian Schreiber <me@schreibersebastian.de>
 *
 * $Id: $
 *
 *
 * @see http://robertlemke.de/blog/posts/2010/08/19/session-handling-and-object-serialization
 * TODO: We have deal with this issues still in this implementation. It is not yet implemented
 */
class Tx_SschFluidExtbaseHelper_Utility_Session_Storage_SessionStorage implements Tx_SschFluidExtbaseHelper_Utility_Session_Storage_StorageInterface {

    /**
     *
     * @var
     */
    protected $concreteSessionManager = NULL;
    /**
     *
     * @var Tx_Extbase_Object_ObjectManagerInterface
     */
    protected $objectManager = NULL;

    /**
     * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
     * @return void
     */
    public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
        $this->objectManager = $objectManager;
        $this->initializeConcreteSessionManager();
    }

    /**
     * @return void
     */
    protected function initializeConcreteSessionManager() {
        if (TYPO3_MODE === 'FE') {
            $this->concreteSessionManager = $this->objectManager->get('Tx_SschFluidExtbaseHelper_Utility_Session_Storage_FeSessionStorage');
        } else {
            $this->concreteSessionManager = $this->objectManager->get('Tx_SschFluidExtbaseHelper_Utility_Session_Storage_BeSessionStorage');
        }
    }

    /**
     *
     * @param mixed $data
     * @return true
     */
    public function  isSerializable($data) {
        return $this->concreteSessionManager->isSerializable($data);
    }

    /**
     *
     * @param string $key
     */
    public function read($key, $type = 'ses') {
        return $this->concreteSessionManager->read($key, $type);
    }

    /**
     * Write data to session
     * @param string $key
     * @param mixed $data
     */
    public function write($key, $data, $type = 'ses') {
        $this->concreteSessionManager->write($key, $data, $type);
    }

    /**
     *
     * @param string $key
     * @return boolean
     */
    public function has($key, $type = 'ses') {
        return $this->concreteSessionManager->has($key, $type);
    }

    /**
     *
     * @param string $key
     */
    public function remove($key, $type = 'ses') {
        $this->concreteSessionManager->remove($key, $type);
    }

    /**
     * @param object
     * @param string
     */
    public function storeObject($object, $key = NULL, $type = 'ses') {
        $this->concreteSessionManager->storeObject($object, $key, $type);
    }

    /**
     * @param string
     * @return mixed
     */
    public function getObject($key, $type = 'ses') {
        return $this->concreteSessionManager->getObject($key, $type);
    }

    /**
     *
     * @return object
     */
    public function  getUser() {
        return $this->concreteSessionManager->getUser();
    }

    /**
     *
     * @return Tx_SschFluidExtbaseHelper_Utility_Session_Storage_AbstractSessionStorage
     */
    public function getConcreteSessionManager() {
        return $this->concreteSessionManager;
    }
}

In order to share some functionality between the different concrete session storage classes, i created the following abstract class:

/* * *************************************************************
 *  Copyright notice
 *
 *  (c) 2010 Sebastian Schreiber
 *  Contact: me@schreibersebastian.de
 *  All rights reserved
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ************************************************************* */

/**
 *
 * @package TYPO3
 * @subpackage ssch_fluid_extbase_helper
 *
 * @author Sebastian Schreiber <me@schreibersebastian.de>
 *
 * $Id: AbstractSessionStorage.php 94 2012-02-13 11:46:17Z schreiberten $
 *
 *
 * @see http://robertlemke.de/blog/posts/2010/08/19/session-handling-and-object-serialization
 * TODO: We have deal with this issues still in this implementation. It is not yet implemented
 */
abstract class Tx_SschFluidExtbaseHelper_Utility_Session_Storage_AbstractSessionStorage implements Tx_SschFluidExtbaseHelper_Utility_Session_Storage_StorageInterface {

    /**
     * @var string
     */
    protected $sessionNamespace = 'ssch_fluid_extbase_helper';

    /**
     * Check whether the data is serializable or not
     * @param mixed $data
     * @return boolean
     */
    public function isSerializable($data) {
        if (is_object($data) || is_array($data)) {
            return TRUE;
        }
        return FALSE;
    }

    /**
     *
     * @param string $key
     */
    protected function getKey($key) {
        return $this->sessionNamespace . $key;
    }

    /**
     * Writes a object to the session if the key is empty it used the classname
     * @param object $object
     * @param string $key
     * @return	void
     */
    public function storeObject($object, $key = NULL, $type = 'ses') {
        if (is_null($key)) {
            $key = get_class($object);
        }
        if ($this->isSerializable($object)) {
            $this->write($key, serialize($object), $type);
        } else {
            throw new InvalidArgumentException(sprintf('The object %s is not serializable.', get_class($object)));
        }
    }

    /**
     * Writes something to storage
     * @param string $key
     * @return	object
     */
    public function getObject($key, $type = 'ses') {
        return unserialize($this->read($key, $type));
    }

    /**
     *
     * @return string
     */
    public function getSessionNamespace() {
        return $this->sessionNamespace;
    }

    /**
     *
     * @param string $sessionNamespace
     */
    public function setSessionNamespace($sessionNamespace) {
        $this->sessionNamespace = $sessionNamespace;
    }

}

And now the concrete session storage classes for the backend and frontend

<?php

/* * *************************************************************
 *  Copyright notice
 *
 *  (c) 2010 Sebastian Schreiber
 *  Contact: me@schreibersebastian.de
 *  All rights reserved
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ************************************************************* */

/**
 *
 * @package TYPO3
 * @subpackage ssch_fluid_extbase_helper
 *
 * @author Sebastian Schreiber <me@schreibersebastian.de>
 *
 * $Id: FeSessionStorage.php 77 2011-12-17 15:44:24Z schreiberten $
 *
 *
 * @see http://robertlemke.de/blog/posts/2010/08/19/session-handling-and-object-serialization
 * TODO: We have deal with this issues still in this implementation. It is not yet implemented
 */
class Tx_SschFluidExtbaseHelper_Utility_Session_Storage_FeSessionStorage extends Tx_SschFluidExtbaseHelper_Utility_Session_Storage_AbstractSessionStorage {

    /**
     * Read session data
     * @param string $key
     * @return mixed
     */
    public function read($key, $type = 'ses') {
        $sessionData = $this->getFeUser()->getKey($type, $this->getKey($key));
        if ($sessionData == '') {
            return '';
        }
        return $sessionData;
    }

    /**
     * Has some key or not
     * @param string $key
     * @return boolean
     */
    public function has($key, $type = 'ses') {
        $sessionData = $this->getFeUser()->getKey($type, $this->getKey($key));
        if ($sessionData == '') {
            return FALSE;
        }
        return TRUE;
    }

    /**
     * Write data to session
     * @param string $key
     * @param mixed $data
     * @return void
     */
    public function write($key, $data, $type = 'ses') {        
        $this->getFeUser()->setKey($type, $this->getKey($key), $data);
        $this->getFeUser()->storeSessionData();
    }

    /**
     * Remove data from session
     * @param string $key
     * @return void
     */
    public function remove($key, $type = 'ses') {
        if ($this->has($key, $type)) {
            $this->write($key, NULL, $type);
        }
    }

    /**
     *
     * @param string $type
     */
    protected function setUserDataChanged($type = 'ses') {
        switch ($type) {
            case 'ses':
                $this->getFeUser()->sesData_change = 1;
                break;
            case 'user':
                $this->getFeUser()->userData_change = 1;
                break;
            default:
                $this->getFeUser()->sesData_change = 1;
                break;
        }
    }

    /**
     *
     * @return tslib_feUserAuth
     */
    protected function getFeUser() {
        return $GLOBALS['TSFE']->fe_user;
    }

    /**
     *
     * @return tslib_feUserAuth
     */
    public function getUser() {
        return $this->getFeUser();
    }

}

And now the two concrete session handling classes for the Frontend and Backend

/* * *************************************************************
 *  Copyright notice
 *
 *  (c) 2010 Sebastian Schreiber
 *  Contact: me@schreibersebastian.de
 *  All rights reserved
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ************************************************************* */

/**
 *
 * @package TYPO3
 * @subpackage ssch_fluid_extbase_helper
 *
 * @author Sebastian Schreiber <me@schreibersebastian.de>
 *
 * $Id: BeSessionStorage.php 75 2011-12-09 14:26:47Z schreiberten $
 *
 *
 * @see http://robertlemke.de/blog/posts/2010/08/19/session-handling-and-object-serialization
 * TODO: We have deal with this issues still in this implementation. It is not yet implemented
 */
class Tx_SschFluidExtbaseHelper_Utility_Session_Storage_BeSessionStorage extends Tx_SschFluidExtbaseHelper_Utility_Session_Storage_AbstractSessionStorage {

    /**
     * Get session data
     * @param string $key
     * @return mixed
     */
    public function read($key, $type = '') {
        return $this->getBeUser()->getSessionData($this->getKey($key));
    }

    /**
     * Write data to session
     * @param string $key
     * @param mixed $data
     * @return void
     */
    public function write($key, $data, $type = '') {
        $this->getBeUser()->setAndSaveSessionData($this->getKey($key), $data);
    }

    /**
     * Remove data from session
     * @param string $key
     */
    public function remove($key, $type = '') {
        if ($this->has($key)) {
            unset($sesDat[$this->getKey($key)]);
            $this->getBeUser()->user['ses_data'] = (!empty($sesDat) ? serialize($sesDat) : '');
            $GLOBALS['TYPO3_DB']->exec_UPDATEquery($this->getBeUser()->session_table, 'ses_id=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->getBeUser()->user['ses_id'], $this->getBeUser()->session_table), array('ses_data' => $this->getBeUser()->user['ses_data']));
        }
    }

    /**
     * Has key in session or not
     * @param string $key
     * @return boolean
     */
    public function has($key, $type = '') {
        $sesDat = unserialize($this->getBeUser()->user['ses_data']);
        return isset($sesDat[$this->getKey($key)]) ? TRUE : FALSE;
    }

    /**
     *
     * @return t3lib_beUserAuth
     */
    protected function getBeUser() {
        return $GLOBALS['BE_USER'];
    }

    /**
     *
     * @return t3lib_beUserAuth
     */
    public function getUser() {
        return $this->getBeUser();
    }

}
/* * *************************************************************
 *  Copyright notice
 *
 *  (c) 2010 Sebastian Schreiber
 *  Contact: me@schreibersebastian.de
 *  All rights reserved
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ************************************************************* */

/**
 *
 * @package TYPO3
 * @subpackage ssch_fluid_extbase_helper
 *
 * @author Sebastian Schreiber <me@schreibersebastian.de>
 *
 * $Id: FeSessionStorage.php 77 2011-12-17 15:44:24Z schreiberten $
 *
 *
 * @see http://robertlemke.de/blog/posts/2010/08/19/session-handling-and-object-serialization
 * TODO: We have deal with this issues still in this implementation. It is not yet implemented
 */
class Tx_SschFluidExtbaseHelper_Utility_Session_Storage_FeSessionStorage extends Tx_SschFluidExtbaseHelper_Utility_Session_Storage_AbstractSessionStorage {

    /**
     * Read session data
     * @param string $key
     * @return mixed
     */
    public function read($key, $type = 'ses') {
        $sessionData = $this->getFeUser()->getKey($type, $this->getKey($key));
        if ($sessionData == '') {
            return '';
        }
        return $sessionData;
    }

    /**
     * Has some key or not
     * @param string $key
     * @return boolean
     */
    public function has($key, $type = 'ses') {
        $sessionData = $this->getFeUser()->getKey($type, $this->getKey($key));
        if ($sessionData == '') {
            return FALSE;
        }
        return TRUE;
    }

    /**
     * Write data to session
     * @param string $key
     * @param mixed $data
     * @return void
     */
    public function write($key, $data, $type = 'ses') {        
        $this->getFeUser()->setKey($type, $this->getKey($key), $data);
        $this->getFeUser()->storeSessionData();
    }

    /**
     * Remove data from session
     * @param string $key
     * @return void
     */
    public function remove($key, $type = 'ses') {
        if ($this->has($key, $type)) {
            $this->write($key, NULL, $type);
        }
    }

    /**
     *
     * @param string $type
     */
    protected function setUserDataChanged($type = 'ses') {
        switch ($type) {
            case 'ses':
                $this->getFeUser()->sesData_change = 1;
                break;
            case 'user':
                $this->getFeUser()->userData_change = 1;
                break;
            default:
                $this->getFeUser()->sesData_change = 1;
                break;
        }
    }

    /**
     *
     * @return tslib_feUserAuth
     */
    protected function getFeUser() {
        return $GLOBALS['TSFE']->fe_user;
    }

    /**
     *
     * @return tslib_feUserAuth
     */
    public function getUser() {
        return $this->getFeUser();
    }
}

Now, you have a nice session abstraction at hand.

Veröffentlicht von

avatar

Sebastian Schreiber

Ich bin 1980 in Bergisch Gladbach geboren. Nach dem Abitur und Zivildienst habe ich 2000 an der Fachhochschule Lippe & Höxter das Studium der Medienproduktin begonnen und nach längeren Aufenthalten in Valencia und Berlin 2003 das Studium mit dem Abschluss Bachelor of Science in Medienproduktion abgeschlossen. Nach einer Festanstellung kurz nach dem Studium in einer kleinen Webagentur in Köln mit Schwerpunkt TYPO3 bin ich nun seit 2008 freiberuflicher Webentwickler.

Schreibe einen Kommentar

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