From 402254ca7e075b6effb323bb16a5e83670fb6979 Mon Sep 17 00:00:00 2001 From: Drak Date: Thu, 29 Mar 2012 17:15:37 +0545 Subject: [PATCH] [HttpFoundation] Changed meta-data responsibility to SessionStorageInterface Added cookie_lifetime to the meta-data. This allows to know how old a cookie is and when the cookie will expire. --- .../HttpFoundation/Session/Session.php | 15 ++---- .../Session/{ => Storage}/MetaBag.php | 40 ++++++++++++---- .../Storage/MockArraySessionStorage.php | 44 ++++++++++++++++-- .../Storage/MockFileSessionStorage.php | 5 ++ .../Session/Storage/NativeSessionStorage.php | 46 +++++++++++++++++-- .../Tests/Session/SessionTest.php | 5 +- .../Session/{ => Storage}/MetaBagTest.php | 6 +-- 7 files changed, 126 insertions(+), 35 deletions(-) rename src/Symfony/Component/HttpFoundation/Session/{ => Storage}/MetaBag.php (71%) rename src/Symfony/Component/HttpFoundation/Tests/Session/{ => Storage}/MetaBagTest.php (93%) diff --git a/src/Symfony/Component/HttpFoundation/Session/Session.php b/src/Symfony/Component/HttpFoundation/Session/Session.php index d67cc55220..a049622ea4 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Session.php +++ b/src/Symfony/Component/HttpFoundation/Session/Session.php @@ -11,6 +11,7 @@ namespace Symfony\Component\HttpFoundation\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MetaBag; use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; @@ -46,20 +47,14 @@ 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, MetaBag $meta = null) + public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null) { $this->storage = $storage ?: new NativeSessionStorage(); @@ -70,10 +65,6 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable $flashes = $flashes ?: new FlashBag(); $this->flashName = $flashes->getName(); $this->registerBag($flashes); - - $metaBag = $meta ?: new MetaBag(); - $this->metaName = $metaBag->getName(); - $this->registerBag($metaBag); } /** @@ -225,7 +216,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable */ public function getMeta() { - return $this->getBag($this->metaName); + return $this->storage->getMetaBag(); } /** diff --git a/src/Symfony/Component/HttpFoundation/Session/MetaBag.php b/src/Symfony/Component/HttpFoundation/Session/Storage/MetaBag.php similarity index 71% rename from src/Symfony/Component/HttpFoundation/Session/MetaBag.php rename to src/Symfony/Component/HttpFoundation/Session/Storage/MetaBag.php index 53b9bf6a33..4506687316 100644 --- a/src/Symfony/Component/HttpFoundation/Session/MetaBag.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/MetaBag.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\HttpFoundation\Session; +namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; @@ -47,12 +47,12 @@ class MetaBag implements SessionBagInterface /** * Constructor. * - * @param string $storageKey The key used to store flashes in the session. + * @param string $storageKey The key used to store bag in the session. */ public function __construct($storageKey = '_sf2_meta') { $this->storageKey = $storageKey; - $this->meta = array('created' => 0, 'lastused' => 0); + $this->meta = array('created' => 0, 'lastused' => 0, 'lifetime' => 0); } /** @@ -66,21 +66,23 @@ class MetaBag implements SessionBagInterface $this->lastUsed = $this->meta['lastused']; $this->meta['lastused'] = time(); } else { - $this->meta['created'] = $this->meta['lastused'] = $this->lastUsed = time(); + $this->stampCreated(); } } /** - * {@inheritdoc} + * Gets the lifetime that this cooke was set with. + * + * @return integer */ - public function getName() + public function getLifetime() { - return $this->name; + return $this->meta['lifetime']; } - public function setName($name) + public function stampNew() { - $this->name = $name; + $this->stampCreated(); } /** @@ -118,4 +120,24 @@ class MetaBag implements SessionBagInterface { // nothing to do } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + private function stampCreated() + { + $timeStamp = time();//(null === $timeStamp) ? time() : $timeStamp; + $this->meta['created'] = $this->meta['lastused'] = $this->lastUsed = $timeStamp; + $this->meta['lifetime'] = ini_get('session.cookie_lifetime'); + } } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php index 6f1e279f41..3dc8fa1a87 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php @@ -12,6 +12,7 @@ namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; +use Symfony\Component\HttpFoundation\Session\Storage\MetaBag; /** * MockArraySessionStorage mocks the session for unit tests. @@ -52,14 +53,21 @@ class MockArraySessionStorage implements SessionStorageInterface */ protected $data = array(); + /** + * @var MetaBag + */ + protected $metaBag; + /** * Constructor. * - * @param string $name Session name + * @param string $name Session name + * @param MetaBag $metaBag MetaBag instance. */ - public function __construct($name = 'MOCKSESSID') + public function __construct($name = 'MOCKSESSID', MetaBag $metaBag = null) { $this->name = $name; + $this->setMetaBag($metaBag); } /** @@ -100,6 +108,10 @@ class MockArraySessionStorage implements SessionStorageInterface $this->start(); } + if ($destroy) { + $this->metaBag->stampNew(); + } + $this->id = $this->generateId(); return true; @@ -191,6 +203,30 @@ class MockArraySessionStorage implements SessionStorageInterface return $this->bags[$name]; } + /** + * Sets the metabag. + * + * @param MetaBag $metaBag + */ + public function setMetaBag(MetaBag $metaBag = null) + { + if (null === $metaBag) { + $metaBag = new MetaBag(); + } + + $this->metaBag = $metaBag; + } + + /** + * Gets the MetaBag. + * + * @return MetaBag + */ + public function getMetaBag() + { + return $this->metaBag; + } + /** * Generates a session ID. * @@ -206,7 +242,9 @@ class MockArraySessionStorage implements SessionStorageInterface protected function loadSession() { - foreach ($this->bags as $bag) { + $bags = array_merge($this->bags, array($this->metaBag)); + + foreach ($bags as $bag) { $key = $bag->getStorageKey(); $this->data[$key] = isset($this->data[$key]) ? $this->data[$key] : array(); $bag->initialize($this->data[$key]); diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php index 24457319f9..f39d4e9c9f 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php @@ -75,8 +75,13 @@ class MockFileSessionStorage extends MockArraySessionStorage */ public function regenerate($destroy = false) { + if (!$this->started) { + $this->start(); + } + if ($destroy) { $this->destroy(); + $this->metaBag->stampNew(); } $this->id = $this->generateId(); diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index ed591cad21..fd3fb8a99c 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -12,6 +12,7 @@ namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; +use Symfony\Component\HttpFoundation\Session\Storage\MetaBag; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; @@ -45,6 +46,11 @@ class NativeSessionStorage implements SessionStorageInterface */ protected $saveHandler; + /** + * @var MetaBag + */ + protected $metaBag; + /** * Constructor. * @@ -83,10 +89,11 @@ class NativeSessionStorage implements SessionStorageInterface * upload_progress.min-freq, "1" * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset=" * - * @param array $options Session configuration options. - * @param object $handler SessionHandlerInterface. + * @param array $options Session configuration options. + * @param object $handler SessionHandlerInterface. + * @param MetaBag $handler MetaBag. */ - public function __construct(array $options = array(), $handler = null) + public function __construct(array $options = array(), $handler = null, MetaBag $metaBag = null) { // sensible defaults ini_set('session.auto_start', 0); // by default we prefer to explicitly start the session using the class. @@ -99,6 +106,7 @@ class NativeSessionStorage implements SessionStorageInterface register_shutdown_function('session_write_close'); } + $this->setMetaBag($metaBag); $this->setOptions($options); $this->setSaveHandler($handler); } @@ -189,6 +197,10 @@ class NativeSessionStorage implements SessionStorageInterface */ public function regenerate($destroy = false) { + if ($destroy) { + $this->metaBag->stampNew(); + } + return session_regenerate_id($destroy); } @@ -249,6 +261,30 @@ class NativeSessionStorage implements SessionStorageInterface return $this->bags[$name]; } + /** + * Sets the metabag. + * + * @param MetaBag $metaBag + */ + public function setMetaBag(MetaBag $metaBag = null) + { + if (null === $metaBag) { + $metaBag = new MetaBag(); + } + + $this->metaBag = $metaBag; + } + + /** + * Gets the MetaBag. + * + * @return MetaBag + */ + public function getMetaBag() + { + return $this->metaBag; + } + /** * Sets session.* ini variables. * @@ -338,7 +374,9 @@ class NativeSessionStorage implements SessionStorageInterface $session = &$_SESSION; } - foreach ($this->bags as $bag) { + $bags = array_merge($this->bags, array($this->metaBag)); + + foreach ($bags as $bag) { $key = $bag->getStorageKey(); $session[$key] = isset($session[$key]) ? $session[$key] : array(); $bag->initialize($session[$key]); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php index 9505a7450d..cb903369c6 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php @@ -257,9 +257,6 @@ class SessionTest extends \PHPUnit_Framework_TestCase 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())); + $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\MetaBag', $this->session->getMeta()); } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/MetaBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/MetaBagTest.php similarity index 93% rename from src/Symfony/Component/HttpFoundation/Tests/Session/MetaBagTest.php rename to src/Symfony/Component/HttpFoundation/Tests/Session/Storage/MetaBagTest.php index f0bd48cf92..45730e8aa7 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/MetaBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/MetaBagTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\HttpFoundation\Tests\Session; +namespace Symfony\Component\HttpFoundation\Tests\Session\Storage; -use Symfony\Component\HttpFoundation\Session\MetaBag; +use Symfony\Component\HttpFoundation\Session\Storage\MetaBag; /** * Test class for MetaBag. @@ -43,7 +43,7 @@ class MetaBagTest extends \PHPUnit_Framework_TestCase public function testInitialize() { - $p = new \ReflectionProperty('Symfony\Component\HttpFoundation\Session\MetaBag', 'meta'); + $p = new \ReflectionProperty('Symfony\Component\HttpFoundation\Session\Storage\MetaBag', 'meta'); $p->setAccessible(true); $bag1 = new MetaBag();