[HttpFoundation] Added some basic meta-data to Session

This commit allows applications to know certain meta-data about the session
Session storage is designed to only store some data against a session ID
so this method is necessary to be compatible with any session handler, including
native handlers.
This commit is contained in:
Drak 2012-03-28 21:07:12 +05:45
parent 0c7b2911bc
commit 29bd787b7e
5 changed files with 300 additions and 27 deletions

View File

@ -0,0 +1,121 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Session;
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
/**
* Metadata container.
*
* Adds standard meta data to the session.
*
* @author Drak <drak@zikula.org>
*/
class MetaBag implements SessionBagInterface
{
/**
* @var string
*/
private $name = '__meta';
/**
* @var string
*/
private $storageKey;
/**
* @var array
*/
protected $meta = array();
/**
* Unix timestamp.
*
* @var integer
*/
private $lastUsed;
/**
* Constructor.
*
* @param string $storageKey The key used to store flashes in the session.
*/
public function __construct($storageKey = '_sf2_meta')
{
$this->storageKey = $storageKey;
$this->meta = array('created' => 0, 'lastused' => 0);
}
/**
* {@inheritdoc}
*/
public function initialize(array &$meta)
{
$this->meta = &$meta;
if (isset($meta['created'])) {
$this->lastUsed = $this->meta['lastused'];
$this->meta['lastused'] = time();
} else {
$this->meta['created'] = $this->meta['lastused'] = $this->lastUsed = time();
}
}
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
/**
* {@inheritdoc}
*/
public function getStorageKey()
{
return $this->storageKey;
}
/**
* Gets the created timestamp meta data.
*
* @return integer Unix timestamp
*/
public function getCreated()
{
return $this->meta['created'];
}
/**
* Gets the last used meta data.
*
* @return integer Unix timestamp
*/
public function getLastUsed()
{
return $this->lastUsed;
}
/**
* {@inheritdoc}
*/
public function clear()
{
// nothing to do
}
}

View File

@ -46,24 +46,34 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
private $attributeName;
/**
* @var string
*/
private $metaName;
/**
* Constructor.
*
* @param SessionStorageInterface $storage A SessionStorageInterface instance.
* @param AttributeBagInterface $attributes An AttributeBagInterface instance, (defaults null for default AttributeBag)
* @param FlashBagInterface $flashes A FlashBagInterface instance (defaults null for default FlashBag)
* @param MetaBag $meta A MetaBag instance (defaults null for default MetaBag)
*/
public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)
public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null, MetaBag $meta = null)
{
$this->storage = $storage ?: new NativeSessionStorage();
$attributeBag = $attributes ?: new AttributeBag();
$this->attributeName = $attributeBag->getName();
$this->registerBag($attributeBag);
$attributes = $attributes ?: new AttributeBag();
$this->attributeName = $attributes->getName();
$this->registerBag($attributes);
$flashBag = $flashes ?: new FlashBag();
$this->flashName = $flashBag->getName();
$this->registerBag($flashBag);
$flashes = $flashes ?: new FlashBag();
$this->flashName = $flashes->getName();
$this->registerBag($flashes);
$metaBag = $meta ?: new MetaBag();
$this->metaName = $metaBag->getName();
$this->registerBag($metaBag);
}
/**
@ -130,6 +140,26 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
$this->storage->getBag($this->attributeName)->clear();
}
/**
* Returns an iterator for attributes.
*
* @return \ArrayIterator An \ArrayIterator instance
*/
public function getIterator()
{
return new \ArrayIterator($this->storage->getBag($this->attributeName)->all());
}
/**
* Returns the number of attributes.
*
* @return int The number of attributes
*/
public function count()
{
return count($this->storage->getBag($this->attributeName)->all());
}
/**
* {@inheritdoc}
*/
@ -188,6 +218,16 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
$this->storage->setName($name);
}
/**
* Gets session meta.
*
* @return MetaBag
*/
public function getMeta()
{
return $this->getBag($this->metaName);
}
/**
* Registers a SessionBagInterface with the session.
*
@ -310,24 +350,4 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
{
return $this->getBag($this->flashName)->clear();
}
/**
* Returns an iterator for attributes.
*
* @return \ArrayIterator An \ArrayIterator instance
*/
public function getIterator()
{
return new \ArrayIterator($this->storage->getBag('attributes')->all());
}
/**
* Returns the number of attributes.
*
* @return int The number of attributes
*/
public function count()
{
return count($this->storage->getBag('attributes')->all());
}
}

View File

@ -164,4 +164,27 @@ interface SessionInterface
* @api
*/
function clear();
/**
* Gets session meta.
*
* @return MetaBag
*/
public function getMeta();
/**
* Registers a SessionBagInterface with the session.
*
* @param SessionBagInterface $bag
*/
public function registerBag(SessionBagInterface $bag);
/**
* Get's a bag instance.
*
* @param string $name
*
* @return SessionBagInterface
*/
public function getBag($name);
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\HttpFoundation\Tests\Session;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\MetaBag;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
@ -253,4 +254,12 @@ class SessionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(2, count($this->session));
}
public function testGetMeta()
{
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\MetaBag', $this->session->getMeta());
$metaBag = new MetaBag();
$session = new Session($this->storage, new AttributeBag(), new FlashBag(), $metaBag);
$this->assertSame($metaBag, $session->getBag($metaBag->getName()));
}
}

View File

@ -0,0 +1,100 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Tests\Component\HttpFoundation\Session;
use Symfony\Component\HttpFoundation\Session\MetaBag;
/**
* Test class for MetaBag.
*/
class MetaBagTest extends \PHPUnit_Framework_TestCase
{
/**
* @var MetaBag
*/
protected $bag;
/**
* @var array
*/
protected $array = array();
protected function setUp()
{
$this->bag = new MetaBag();
$this->array = array('created' => 1234567, 'lastused' => 12345678);
$this->bag->initialize($this->array);
}
protected function tearDown()
{
$this->array = array();
$this->bag = null;
}
public function testInitialize()
{
$p = new \ReflectionProperty('Symfony\Component\HttpFoundation\Session\MetaBag', 'meta');
$p->setAccessible(true);
$bag1 = new MetaBag();
$array = array();
$bag1->initialize($array);
$this->assertGreaterThanOrEqual(time(), $bag1->getCreated());
$this->assertEquals($bag1->getCreated(), $bag1->getLastUsed());
sleep(1);
$bag2 = new MetaBag();
$array2 = $p->getValue($bag1);
$bag2->initialize($array2);
$this->assertEquals($bag1->getCreated(), $bag2->getCreated());
$this->assertEquals($bag1->getLastUsed(), $bag2->getLastUsed());
$this->assertEquals($bag2->getCreated(), $bag2->getLastUsed());
sleep(1);
$bag3 = new MetaBag();
$array3 = $p->getValue($bag2);
$bag3->initialize($array3);
$this->assertEquals($bag1->getCreated(), $bag3->getCreated());
$this->assertGreaterThan($bag2->getLastUsed(), $bag3->getLastUsed());
$this->assertNotEquals($bag3->getCreated(), $bag3->getLastUsed());
}
public function testGetSetName()
{
$this->assertEquals('__meta', $this->bag->getName());
$this->bag->setName('foo');
$this->assertEquals('foo', $this->bag->getName());
}
public function testGetStorageKey()
{
$this->assertEquals('_sf2_meta', $this->bag->getStorageKey());
}
public function testGetCreated()
{
$this->assertEquals(1234567, $this->bag->getCreated());
}
public function testGetLastUsed()
{
$this->assertLessThanOrEqual(time(), $this->bag->getLastUsed());
}
public function testClear()
{
$this->bag->clear();
}
}