From d4e51b7029b94520a804c6dc726854ef79f913c1 Mon Sep 17 00:00:00 2001 From: Andrew Berry Date: Fri, 21 Oct 2011 16:58:45 -0700 Subject: [PATCH 1/4] Updated session flashes to allow multiple types of flash message and updated tests refs #2510 refs #1863 --- .../Component/HttpFoundation/Session.php | 81 ++++++++++++++----- .../Component/HttpFoundation/SessionTest.php | 11 ++- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session.php b/src/Symfony/Component/HttpFoundation/Session.php index 721a6c7240b99..9c3d398e94c7e 100644 --- a/src/Symfony/Component/HttpFoundation/Session.php +++ b/src/Symfony/Component/HttpFoundation/Session.php @@ -37,8 +37,8 @@ class Session implements \Serializable public function __construct(SessionStorageInterface $storage) { $this->storage = $storage; - $this->flashes = array(); - $this->oldFlashes = array(); + $this->flashes = array('status' => array()); + $this->oldFlashes = array('status' => array()); $this->attributes = array(); $this->started = false; $this->closed = false; @@ -174,7 +174,7 @@ public function clear() } $this->attributes = array(); - $this->flashes = array(); + $this->flashes = array('status' => array()); } /** @@ -216,28 +216,54 @@ public function getId() } /** - * Gets the flash messages. + * Gets the flash messages of a given type. * + * @param string $type * @return array */ - public function getFlashes() + public function getFlashes($type = 'status') { + return $this->flashes[$type]; + } + + /** + * Gets the flash messages. + * + * @return array + */ + public function getAllFlashes() { return $this->flashes; } + /** + * Sets the flash messages of a specific type. + * + * @param array $values + * @param string $type + */ + public function setFlashes($values, $type = 'status') + { + if (false === $this->started) { + $this->start(); + } + + $this->flashes[$type] = $values; + $this->oldFlashes = array('status' => array()); + } + /** * Sets the flash messages. * * @param array $values */ - public function setFlashes($values) + public function setAllFlashes($values) { if (false === $this->started) { $this->start(); } $this->flashes = $values; - $this->oldFlashes = array(); + $this->oldFlashes = array('status' => array()); } /** @@ -248,9 +274,11 @@ public function setFlashes($values) * * @return string */ - public function getFlash($name, $default = null) + public function getFlash($name, $default = null, $type = 'status') { - return array_key_exists($name, $this->flashes) ? $this->flashes[$name] : $default; + if (array_key_exists($type, $this->flashes)) { + return array_key_exists($name, $this->flashes[$type]) ? $this->flashes[$type][$name] : $default; + } } /** @@ -258,31 +286,33 @@ public function getFlash($name, $default = null) * * @param string $name * @param string $value + * @param string $type */ - public function setFlash($name, $value) + public function setFlash($name, $value, $type = 'status') { if (false === $this->started) { $this->start(); } - $this->flashes[$name] = $value; - unset($this->oldFlashes[$name]); + $this->flashes[$type][$name] = $value; + unset($this->oldFlashes[$type][$name]); } /** * Checks whether a flash message exists. * * @param string $name + * @param string $type * * @return Boolean */ - public function hasFlash($name) + public function hasFlash($name, $type = 'status') { if (false === $this->started) { $this->start(); } - return array_key_exists($name, $this->flashes); + return array_key_exists($name, $this->flashes[$type]); } /** @@ -290,13 +320,13 @@ public function hasFlash($name) * * @param string $name */ - public function removeFlash($name) + public function removeFlash($name, $type = 'status') { if (false === $this->started) { $this->start(); } - unset($this->flashes[$name]); + unset($this->flashes[$type][$name]); } /** @@ -308,8 +338,19 @@ public function clearFlashes() $this->start(); } - $this->flashes = array(); - $this->oldFlashes = array(); + $this->flashes = array('status' => array()); + $this->oldFlashes = array('status' => array()); + } + + /** + * Adds a generic flash message to the session. + * + * @param string $type + * + * @return array + */ + public function addFlash($value) { + $this->flashes['status'][] = $value; } public function save() @@ -318,7 +359,9 @@ public function save() $this->start(); } - $this->flashes = array_diff_key($this->flashes, $this->oldFlashes); + foreach ($this->flashes as $type => $flashes) { + $this->flashes[$type] = array_diff_key($flashes, $this->oldFlashes[$type]); + } $this->storage->write('_symfony2', array( 'attributes' => $this->attributes, diff --git a/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php b/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php index d5f615a6b1370..c3f2807373df2 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php @@ -59,6 +59,11 @@ public function testFlash() $this->session->setFlashes($flashes); $this->assertSame($flashes, $this->session->getFlashes()); + + $this->session->clearFlashes(); + $this->session->addFlash('foo'); + $compare = $this->session->getFlashes(); + $this->assertSame($compare, array(0 => 'foo')); } public function testFlashesAreFlushedWhenNeeded() @@ -149,7 +154,7 @@ public function testSave() $this->session->set('foo', 'bar'); $this->session->save(); - $compare = array('_symfony2' => array('attributes' => array('foo' => 'bar'), 'flashes' => array())); + $compare = array('_symfony2' => array('attributes' => array('foo' => 'bar'), 'flashes' => array('status' => array()))); $r = new \ReflectionObject($this->storage); $p = $r->getProperty('data'); @@ -179,7 +184,7 @@ public function testSavedOnDestruct() $expected = array( 'attributes'=>array('foo'=>'bar'), - 'flashes'=>array(), + 'flashes'=>array('status' => array()), ); $saved = $this->storage->read('_symfony2'); $this->assertSame($expected, $saved); @@ -195,7 +200,7 @@ public function testSavedOnDestructAfterManualSave() $expected = array( 'attributes'=>array('foo'=>'bar'), - 'flashes'=>array(), + 'flashes'=>array('status' => array()), ); $saved = $this->storage->read('_symfony2'); $this->assertSame($expected, $saved); From 45ef16d59f1cfa32f01471763450873def8bc949 Mon Sep 17 00:00:00 2001 From: Drak Date: Wed, 2 Nov 2011 15:09:38 +0545 Subject: [PATCH 2/4] Corrected CS, added tests and added sanity checking refs #2510 refs #1863 --- .../Component/HttpFoundation/Session.php | 33 +++++++++++--- .../Component/HttpFoundation/SessionTest.php | 44 +++++++++++++++++++ 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session.php b/src/Symfony/Component/HttpFoundation/Session.php index 9c3d398e94c7e..931b5d190c204 100644 --- a/src/Symfony/Component/HttpFoundation/Session.php +++ b/src/Symfony/Component/HttpFoundation/Session.php @@ -219,10 +219,17 @@ public function getId() * Gets the flash messages of a given type. * * @param string $type + * + * @throws \InvalidArgumentException If non-existing $type is requested. + * * @return array */ public function getFlashes($type = 'status') { + if (!isset($this->flashes[$type])) { + throw new \InvalidArgumentException(sprintf('Flash message type %s does not exist', $type)); + } + return $this->flashes[$type]; } @@ -231,7 +238,8 @@ public function getFlashes($type = 'status') * * @return array */ - public function getAllFlashes() { + public function getAllFlashes() + { return $this->flashes; } @@ -271,14 +279,18 @@ public function setAllFlashes($values) * * @param string $name * @param string|null $default + * + * @throws InvalidArgumentException If unknown type specified. * - * @return string + * @return mixed */ public function getFlash($name, $default = null, $type = 'status') { - if (array_key_exists($type, $this->flashes)) { - return array_key_exists($name, $this->flashes[$type]) ? $this->flashes[$type][$name] : $default; + if (!isset($this->flashes[$type])) { + throw new \InvalidArgumentException(sprintf('Unknown flash message type %s', $type)); } + + return array_key_exists($name, $this->flashes[$type]) ? $this->flashes[$type][$name] : $default; } /** @@ -303,6 +315,8 @@ public function setFlash($name, $value, $type = 'status') * * @param string $name * @param string $type + * + * @throws InvalidArgumentException If unknown type specified. * * @return Boolean */ @@ -311,6 +325,10 @@ public function hasFlash($name, $type = 'status') if (false === $this->started) { $this->start(); } + + if (!isset($this->flashes[$type])) { + throw new \InvalidArgumentException(sprintf('Unknown flash message type %s', $type)); + } return array_key_exists($name, $this->flashes[$type]); } @@ -326,7 +344,9 @@ public function removeFlash($name, $type = 'status') $this->start(); } - unset($this->flashes[$type][$name]); + if (isset($this->flashes[$type])) { + unset($this->flashes[$type][$name]); + } } /** @@ -349,7 +369,8 @@ public function clearFlashes() * * @return array */ - public function addFlash($value) { + public function addFlash($value) + { $this->flashes['status'][] = $value; } diff --git a/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php b/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php index c3f2807373df2..83070c64a7da1 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php @@ -65,6 +65,50 @@ public function testFlash() $compare = $this->session->getFlashes(); $this->assertSame($compare, array(0 => 'foo')); } + + /** + * @expectedException InvalidArgumentException + */ + public function testGetFlashException() + { + $this->session->getFlash('foo', null, 'notexisting'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testHasFlashException() + { + $this->session->hasFlash('foo', 'notexisting'); + } + + public function testGetFlashes() + { + $this->assertEquals(array(), $this->session->getFlashes('status')); + $this->session->setFlash('status', 'hello'); + $this->assertEquals(array('status' => 'hello'), $this->session->getFlashes('status')); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testGetFlashesException() + { + $this->session->getFlashes('notexisting'); + } + + public function testSetFlashes() + { + $this->session->setFlashes(array('hello', 'world')); + $this->assertEquals(array('hello', 'world'), $this->session->getFlashes('status')); + } + + public function testAllFlashes() + { + $this->assertEquals(array('status' => array()), $this->session->getAllFlashes()); + $this->session->setAllFlashes(array('status' => array('hello', 'world'))); + $this->assertEquals(array('status' => array('hello', 'world')), $this->session->getAllFlashes()); + } public function testFlashesAreFlushedWhenNeeded() { From 00187c9593e222ed8839c289e41073eb4e52e301 Mon Sep 17 00:00:00 2001 From: Drak Date: Wed, 2 Nov 2011 19:54:22 +0545 Subject: [PATCH 3/4] Use constant for default flash type. This is much more IDE friendly. --- .../Component/HttpFoundation/Session.php | 35 +++++++++++-------- .../Component/HttpFoundation/SessionTest.php | 20 +++++------ 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session.php b/src/Symfony/Component/HttpFoundation/Session.php index 931b5d190c204..510c8b9709977 100644 --- a/src/Symfony/Component/HttpFoundation/Session.php +++ b/src/Symfony/Component/HttpFoundation/Session.php @@ -22,6 +22,10 @@ */ class Session implements \Serializable { + const FLASH_INFO = 'info'; + const FLASH_WARNING = 'warning'; + const FLASH_ERROR = 'error'; + protected $storage; protected $started; protected $attributes; @@ -37,8 +41,8 @@ class Session implements \Serializable public function __construct(SessionStorageInterface $storage) { $this->storage = $storage; - $this->flashes = array('status' => array()); - $this->oldFlashes = array('status' => array()); + $this->flashes = array(self::FLASH_INFO => array()); + $this->oldFlashes = array(self::FLASH_INFO => array()); $this->attributes = array(); $this->started = false; $this->closed = false; @@ -174,7 +178,7 @@ public function clear() } $this->attributes = array(); - $this->flashes = array('status' => array()); + $this->flashes = array(self::FLASH_INFO => array()); } /** @@ -224,7 +228,7 @@ public function getId() * * @return array */ - public function getFlashes($type = 'status') + public function getFlashes($type = self::FLASH_INFO) { if (!isset($this->flashes[$type])) { throw new \InvalidArgumentException(sprintf('Flash message type %s does not exist', $type)); @@ -249,14 +253,14 @@ public function getAllFlashes() * @param array $values * @param string $type */ - public function setFlashes($values, $type = 'status') + public function setFlashes($values, $type = self::FLASH_INFO) { if (false === $this->started) { $this->start(); } $this->flashes[$type] = $values; - $this->oldFlashes = array('status' => array()); + $this->oldFlashes = array(self::FLASH_INFO => array()); } /** @@ -271,7 +275,7 @@ public function setAllFlashes($values) } $this->flashes = $values; - $this->oldFlashes = array('status' => array()); + $this->oldFlashes = array(self::FLASH_INFO => array()); } /** @@ -284,7 +288,7 @@ public function setAllFlashes($values) * * @return mixed */ - public function getFlash($name, $default = null, $type = 'status') + public function getFlash($name, $default = null, $type = self::FLASH_INFO) { if (!isset($this->flashes[$type])) { throw new \InvalidArgumentException(sprintf('Unknown flash message type %s', $type)); @@ -300,7 +304,7 @@ public function getFlash($name, $default = null, $type = 'status') * @param string $value * @param string $type */ - public function setFlash($name, $value, $type = 'status') + public function setFlash($name, $value, $type = self::FLASH_INFO) { if (false === $this->started) { $this->start(); @@ -320,7 +324,7 @@ public function setFlash($name, $value, $type = 'status') * * @return Boolean */ - public function hasFlash($name, $type = 'status') + public function hasFlash($name, $type = self::FLASH_INFO) { if (false === $this->started) { $this->start(); @@ -338,7 +342,7 @@ public function hasFlash($name, $type = 'status') * * @param string $name */ - public function removeFlash($name, $type = 'status') + public function removeFlash($name, $type = self::FLASH_INFO) { if (false === $this->started) { $this->start(); @@ -358,20 +362,21 @@ public function clearFlashes() $this->start(); } - $this->flashes = array('status' => array()); - $this->oldFlashes = array('status' => array()); + $this->flashes = array(self::FLASH_INFO => array()); + $this->oldFlashes = array(self::FLASH_INFO => array()); } /** * Adds a generic flash message to the session. * + * @param string $value * @param string $type * * @return array */ - public function addFlash($value) + public function addFlash($value, $type = self::FLASH_INFO) { - $this->flashes['status'][] = $value; + $this->flashes[$type][] = $value; } public function save() diff --git a/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php b/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php index 83070c64a7da1..e1a28fa526549 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php @@ -84,9 +84,9 @@ public function testHasFlashException() public function testGetFlashes() { - $this->assertEquals(array(), $this->session->getFlashes('status')); - $this->session->setFlash('status', 'hello'); - $this->assertEquals(array('status' => 'hello'), $this->session->getFlashes('status')); + $this->assertEquals(array(), $this->session->getFlashes(Session::FLASH_INFO)); + $this->session->setFlash(Session::FLASH_INFO, 'hello'); + $this->assertEquals(array(Session::FLASH_INFO => 'hello'), $this->session->getFlashes(Session::FLASH_INFO)); } /** @@ -100,14 +100,14 @@ public function testGetFlashesException() public function testSetFlashes() { $this->session->setFlashes(array('hello', 'world')); - $this->assertEquals(array('hello', 'world'), $this->session->getFlashes('status')); + $this->assertEquals(array('hello', 'world'), $this->session->getFlashes(Session::FLASH_INFO)); } public function testAllFlashes() { - $this->assertEquals(array('status' => array()), $this->session->getAllFlashes()); - $this->session->setAllFlashes(array('status' => array('hello', 'world'))); - $this->assertEquals(array('status' => array('hello', 'world')), $this->session->getAllFlashes()); + $this->assertEquals(array(Session::FLASH_INFO => array()), $this->session->getAllFlashes()); + $this->session->setAllFlashes(array(Session::FLASH_INFO => array('hello', 'world'))); + $this->assertEquals(array(Session::FLASH_INFO => array('hello', 'world')), $this->session->getAllFlashes()); } public function testFlashesAreFlushedWhenNeeded() @@ -198,7 +198,7 @@ public function testSave() $this->session->set('foo', 'bar'); $this->session->save(); - $compare = array('_symfony2' => array('attributes' => array('foo' => 'bar'), 'flashes' => array('status' => array()))); + $compare = array('_symfony2' => array('attributes' => array('foo' => 'bar'), 'flashes' => array(Session::FLASH_INFO => array()))); $r = new \ReflectionObject($this->storage); $p = $r->getProperty('data'); @@ -228,7 +228,7 @@ public function testSavedOnDestruct() $expected = array( 'attributes'=>array('foo'=>'bar'), - 'flashes'=>array('status' => array()), + 'flashes'=>array(Session::FLASH_INFO => array()), ); $saved = $this->storage->read('_symfony2'); $this->assertSame($expected, $saved); @@ -244,7 +244,7 @@ public function testSavedOnDestructAfterManualSave() $expected = array( 'attributes'=>array('foo'=>'bar'), - 'flashes'=>array('status' => array()), + 'flashes'=>array(Session::FLASH_INFO => array()), ); $saved = $this->storage->read('_symfony2'); $this->assertSame($expected, $saved); From 30976519d3b232bc71d95f92e4df0fe0de0e1b4b Mon Sep 17 00:00:00 2001 From: Drak Date: Wed, 2 Nov 2011 20:40:30 +0545 Subject: [PATCH 4/4] Sanity checking on storage driver unserialize() and updated docblocks. --- .../Component/HttpFoundation/Session.php | 25 ++++++++++++++++--- .../Component/HttpFoundation/SessionTest.php | 16 ++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session.php b/src/Symfony/Component/HttpFoundation/Session.php index 510c8b9709977..f40237676e4ab 100644 --- a/src/Symfony/Component/HttpFoundation/Session.php +++ b/src/Symfony/Component/HttpFoundation/Session.php @@ -371,14 +371,15 @@ public function clearFlashes() * * @param string $value * @param string $type - * - * @return array */ public function addFlash($value, $type = self::FLASH_INFO) { $this->flashes[$type][] = $value; } + /** + * Save session. + */ public function save() { if (false === $this->started) { @@ -396,6 +397,8 @@ public function save() } /** + * Close the session without writing saving it. + * * This method should be called when you don't want the session to be saved * when the Session object is garbaged collected (useful for instance when * you want to simulate the interaction of several users/sessions in a single @@ -413,14 +416,30 @@ public function __destruct() } } + /** + * Serialize the session storage driver. + * + * @return string + */ public function serialize() { return serialize($this->storage); } + /** + * Unserialize the SessionStorage. + * + * @param type $serialized + * + * @throws \InvalidArgumentException If serialized string is not an instance of SessionStorageInterface + */ public function unserialize($serialized) { - $this->storage = unserialize($serialized); + $storage = unserialize($serialized); + if (!$storage instanceof SessionStorageInterface) { + throw new \InvalidArgumentException('Serialized string passed does not unserialze to an instance of Symfony\\Component\\HttpFoundation\\SessionStorageInterface'); + } + $this->storage = $storage; $this->attributes = array(); $this->started = false; } diff --git a/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php b/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php index e1a28fa526549..9a03b5cd1edab 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php @@ -22,7 +22,14 @@ */ class SessionTest extends \PHPUnit_Framework_TestCase { + /** + * @var SessionStorage + */ protected $storage; + + /** + * @var Session + */ protected $session; public function setUp() @@ -190,6 +197,15 @@ public function testSerialize() $this->assertEquals($_storage->getValue($this->session), $this->storage, 'storage match'); } + + /** + * @expectedException InvalidArgumentException + */ + public function testUnserializeException() + { + $serialized = serialize('not an instance of SessionStorage'); + $this->session->unserialize($serialized); + } public function testSave() {