diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md
index e9e84485df..eedee05546 100644
--- a/CHANGELOG-2.1.md
+++ b/CHANGELOG-2.1.md
@@ -305,6 +305,9 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
attributes storage behaviour from 2.0.x (default).
* Added `Symfony\Component\HttpFoundation\Attribute\NamespacedAttributeBag` for
namespace session attributes.
+ * Flash API can stores messages in an array so there may be multiple messages
+ per flash type. The old `Session` class API remains without BC break as it
+ will single messages as before.
### HttpKernel
diff --git a/UPGRADE-2.1.md b/UPGRADE-2.1.md
index 386cf36a49..b859a143cb 100644
--- a/UPGRADE-2.1.md
+++ b/UPGRADE-2.1.md
@@ -306,16 +306,6 @@ UPGRADE FROM 2.0 to 2.1
Before:
- ```
- {% if app.session.hasFlash('notice') %}
-
- {{ app.session.flash('notice') }}
-
- {% endif %}
- ```
-
- After:
-
```
{% if app.session.flashbag.has('notice') %}
@@ -323,14 +313,25 @@ UPGRADE FROM 2.0 to 2.1
{% endif %}
```
+ After:
+
+ ```
+ {% for flashMessage in app.session.flashbag.get('notice') %}
+
+ {{ flashMessage }}
+
+ {% endfor %}
+ ```
You can process all flash messges in a single loop with:
```
- {% for type, flashMessage in app.session.flashbag.all() %}
-
- {{ flashMessage }}
-
+ {% for type, flashMessages in app.session.flashbag.all() %}
+ {% for flashMessage in flashMessages) %}
+
+ {{ flashMessage }}
+
+ {% endfor %}
{% endfor %}
```
diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/SessionHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/SessionHelper.php
index c6628172f2..aac3f6dd7b 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/SessionHelper.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/SessionHelper.php
@@ -46,9 +46,9 @@ class SessionHelper extends Helper
return $this->session->get($name, $default);
}
- public function getFlash($name, $default = null)
+ public function getFlash($name, array $default = array())
{
- return $this->session->getFlashBag()->get($name);
+ return $this->session->getFlashBag()->get($name, $default);
}
public function getFlashes()
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php
index b1c4334cde..5b45131e29 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php
@@ -62,7 +62,7 @@ class SessionController extends ContainerAware
$session = $request->getSession();
if ($session->getFlashBag()->has('notice')) {
- $output = $session->getFlashBag()->get('notice');
+ list($output) = $session->getFlashBag()->get('notice');
} else {
$output = 'No flash was set.';
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/SessionHelperTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/SessionHelperTest.php
index ce8c91b173..e73445d211 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/SessionHelperTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/SessionHelperTest.php
@@ -42,13 +42,13 @@ class SessionHelperTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($helper->hasFlash('notice'));
- $this->assertEquals('bar', $helper->getFlash('notice'));
+ $this->assertEquals(array('bar'), $helper->getFlash('notice'));
}
public function testGetFlashes()
{
$helper = new SessionHelper($this->request);
- $this->assertEquals(array('notice' => 'bar'), $helper->getFlashes());
+ $this->assertEquals(array('notice' => array('bar')), $helper->getFlashes());
}
public function testGet()
diff --git a/src/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php b/src/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php
index 10257847e8..b47962fc26 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php
@@ -75,7 +75,15 @@ class AutoExpireFlashBag implements FlashBagInterface
/**
* {@inheritdoc}
*/
- public function peek($type, $default = null)
+ public function add($type, $message)
+ {
+ $this->flashes['new'][$type][] = $message;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peek($type, array $default = array())
{
return $this->has($type) ? $this->flashes['display'][$type] : $default;
}
@@ -91,7 +99,7 @@ class AutoExpireFlashBag implements FlashBagInterface
/**
* {@inheritdoc}
*/
- public function get($type, $default = null)
+ public function get($type, array $default = array())
{
$return = $default;
@@ -129,9 +137,9 @@ class AutoExpireFlashBag implements FlashBagInterface
/**
* {@inheritdoc}
*/
- public function set($type, $message)
+ public function set($type, $messages)
{
- $this->flashes['new'][$type] = $message;
+ $this->flashes['new'][$type] = (array)$messages;
}
/**
@@ -139,7 +147,7 @@ class AutoExpireFlashBag implements FlashBagInterface
*/
public function has($type)
{
- return array_key_exists($type, $this->flashes['display']);
+ return array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type];
}
/**
@@ -163,9 +171,6 @@ class AutoExpireFlashBag implements FlashBagInterface
*/
public function clear()
{
- $return = $this->all();
- $this->flashes = array('display' => array(), 'new' => array());
-
- return $return;
+ return $this->all();
}
}
diff --git a/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php b/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php
index eea1600cc3..ce9308e154 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php
@@ -68,7 +68,15 @@ class FlashBag implements FlashBagInterface, \IteratorAggregate, \Countable
/**
* {@inheritdoc}
*/
- public function peek($type, $default = null)
+ public function add($type, $message)
+ {
+ $this->flashes[$type][] = $message;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peek($type, array $default =array())
{
return $this->has($type) ? $this->flashes[$type] : $default;
}
@@ -84,7 +92,7 @@ class FlashBag implements FlashBagInterface, \IteratorAggregate, \Countable
/**
* {@inheritdoc}
*/
- public function get($type, $default = null)
+ public function get($type, array $default = array())
{
if (!$this->has($type)) {
return $default;
@@ -111,9 +119,9 @@ class FlashBag implements FlashBagInterface, \IteratorAggregate, \Countable
/**
* {@inheritdoc}
*/
- public function set($type, $message)
+ public function set($type, $messages)
{
- $this->flashes[$type] = $message;
+ $this->flashes[$type] = (array) $messages;
}
/**
@@ -129,7 +137,7 @@ class FlashBag implements FlashBagInterface, \IteratorAggregate, \Countable
*/
public function has($type)
{
- return array_key_exists($type, $this->flashes);
+ return array_key_exists($type, $this->flashes) && $this->flashes[$type];
}
/**
diff --git a/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php b/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php
index 0c45d74bb7..48ccf05f00 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php
@@ -32,11 +32,11 @@ interface FlashBagInterface extends SessionBagInterface
* Gets flash message for a given type.
*
* @param string $type Message category type.
- * @param string $default Default value if $type doee not exist.
+ * @param array $default Default value if $type doee not exist.
*
* @return string
*/
- function peek($type, $default = null);
+ function peek($type, array $default = array());
/**
* Gets all flash messages.
@@ -49,11 +49,11 @@ interface FlashBagInterface extends SessionBagInterface
* Gets and clears flash from the stack.
*
* @param string $type
- * @param string $default Default value if $type doee not exist.
+ * @param array $default Default value if $type doee not exist.
*
* @return string
*/
- function get($type, $default = null);
+ function get($type, array $default = array());
/**
* Gets and clears flashes from the stack.
diff --git a/src/Symfony/Component/HttpFoundation/Session/Session.php b/src/Symfony/Component/HttpFoundation/Session/Session.php
index 31e879f4c1..145f96440f 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Session.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Session.php
@@ -229,7 +229,16 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
public function getFlashes()
{
- return $this->getBag('flashes')->all();
+ $all = $this->getBag($this->flashName)->all();
+
+ $return = array();
+ if ($all) {
+ foreach ($all as $name => $array) {
+ $return[$name] = reset($array);
+ }
+ }
+
+ return $return;
}
/**
@@ -239,7 +248,9 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
public function setFlashes($values)
{
- $this->getBag('flashes')->setAll($values);
+ foreach ($values as $name => $value) {
+ $this->getBag($this->flashName)->set($name, $value);
+ }
}
/**
@@ -252,7 +263,9 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
public function getFlash($name, $default = null)
{
- return $this->getBag('flashes')->get($name, $default);
+ $return = $this->getBag($this->flashName)->get($name);
+
+ return empty($return) ? $default : reset($return);
}
/**
@@ -263,7 +276,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
public function setFlash($name, $value)
{
- $this->getBag('flashes')->set($name, $value);
+ $this->getBag($this->flashName)->set($name, $value);
}
/**
@@ -275,7 +288,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
public function hasFlash($name)
{
- return $this->getBag('flashes')->has($name);
+ return $this->getBag($this->flashName)->has($name);
}
/**
@@ -285,7 +298,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
public function removeFlash($name)
{
- $this->getBag('flashes')->get($name);
+ $this->getBag($this->flashName)->get($name);
}
/**
@@ -295,7 +308,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
public function clearFlashes()
{
- return $this->getBag('flashes')->clear();
+ return $this->getBag($this->flashName)->clear();
}
/**
diff --git a/tests/Symfony/Tests/Component/HttpFoundation/Session/Flash/AutoExpireFlashBagTest.php b/tests/Symfony/Tests/Component/HttpFoundation/Session/Flash/AutoExpireFlashBagTest.php
index c2b34c5611..d8af886afa 100644
--- a/tests/Symfony/Tests/Component/HttpFoundation/Session/Flash/AutoExpireFlashBagTest.php
+++ b/tests/Symfony/Tests/Component/HttpFoundation/Session/Flash/AutoExpireFlashBagTest.php
@@ -34,7 +34,7 @@ class AutoExpireFlashBagTest extends \PHPUnit_Framework_TestCase
{
parent::setUp();
$this->bag = new FlashBag();
- $this->array = array('new' => array('notice' => 'A previous flash message'));
+ $this->array = array('new' => array('notice' => array('A previous flash message')));
$this->bag->initialize($this->array);
}
@@ -47,16 +47,16 @@ class AutoExpireFlashBagTest extends \PHPUnit_Framework_TestCase
public function testInitialize()
{
$bag = new FlashBag();
- $array = array('new' => array('notice' => 'A previous flash message'));
+ $array = array('new' => array('notice' => array('A previous flash message')));
$bag->initialize($array);
- $this->assertEquals('A previous flash message', $bag->peek('notice'));
+ $this->assertEquals(array('A previous flash message'), $bag->peek('notice'));
$array = array('new' => array(
- 'notice' => 'Something else',
- 'error' => 'a',
+ 'notice' => array('Something else'),
+ 'error' => array('a'),
));
$bag->initialize($array);
- $this->assertEquals('Something else', $bag->peek('notice'));
- $this->assertEquals('a', $bag->peek('error'));
+ $this->assertEquals(array('Something else'), $bag->peek('notice'));
+ $this->assertEquals(array('a'), $bag->peek('error'));
}
public function testGetStorageKey()
@@ -75,16 +75,16 @@ class AutoExpireFlashBagTest extends \PHPUnit_Framework_TestCase
public function testPeek()
{
- $this->assertNull($this->bag->peek('non_existing'));
- $this->assertEquals('default', $this->bag->peek('non_existing', 'default'));
- $this->assertEquals('A previous flash message', $this->bag->peek('notice'));
- $this->assertEquals('A previous flash message', $this->bag->peek('notice'));
+ $this->assertEquals(array(), $this->bag->peek('non_existing'));
+ $this->assertEquals(array('default'), $this->bag->peek('non_existing', array('default')));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
}
public function testSet()
{
$this->bag->set('notice', 'Foo');
- $this->assertNotEquals('Foo', $this->bag->peek('notice'));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
}
public function testHas()
@@ -123,10 +123,10 @@ class AutoExpireFlashBagTest extends \PHPUnit_Framework_TestCase
public function testGet()
{
- $this->assertNull($this->bag->get('non_existing'));
- $this->assertEquals('default', $this->bag->get('non_existing', 'default'));
- $this->assertEquals('A previous flash message', $this->bag->get('notice'));
- $this->assertNull($this->bag->get('notice'));
+ $this->assertEquals(array(), $this->bag->get('non_existing'));
+ $this->assertEquals(array('default'), $this->bag->get('non_existing', array('default')));
+ $this->assertEquals(array('A previous flash message'), $this->bag->get('notice'));
+ $this->assertEquals(array(), $this->bag->get('notice'));
}
public function testSetAll()
@@ -141,7 +141,7 @@ class AutoExpireFlashBagTest extends \PHPUnit_Framework_TestCase
$this->bag->set('notice', 'Foo');
$this->bag->set('error', 'Bar');
$this->assertEquals(array(
- 'notice' => 'A previous flash message',
+ 'notice' => array('A previous flash message'),
), $this->bag->all()
);
@@ -150,6 +150,6 @@ class AutoExpireFlashBagTest extends \PHPUnit_Framework_TestCase
public function testClear()
{
- $this->assertEquals(array('notice' => 'A previous flash message'), $this->bag->clear());
+ $this->assertEquals(array('notice' => array('A previous flash message')), $this->bag->clear());
}
}
diff --git a/tests/Symfony/Tests/Component/HttpFoundation/Session/Flash/FlashBagTest.php b/tests/Symfony/Tests/Component/HttpFoundation/Session/Flash/FlashBagTest.php
index 57fd9c4c9a..0b8dc47f61 100644
--- a/tests/Symfony/Tests/Component/HttpFoundation/Session/Flash/FlashBagTest.php
+++ b/tests/Symfony/Tests/Component/HttpFoundation/Session/Flash/FlashBagTest.php
@@ -35,7 +35,7 @@ class FlashBagTest extends \PHPUnit_Framework_TestCase
{
parent::setUp();
$this->bag = new FlashBag();
- $this->array = array('notice' => 'A previous flash message');
+ $this->array = array('notice' => array('A previous flash message'));
$this->bag->initialize($this->array);
}
@@ -71,18 +71,18 @@ class FlashBagTest extends \PHPUnit_Framework_TestCase
public function testPeek()
{
- $this->assertNull($this->bag->peek('non_existing'));
- $this->assertEquals('default', $this->bag->peek('not_existing', 'default'));
- $this->assertEquals('A previous flash message', $this->bag->peek('notice'));
- $this->assertEquals('A previous flash message', $this->bag->peek('notice'));
+ $this->assertEquals(array(), $this->bag->peek('non_existing'));
+ $this->assertEquals(array('default'), $this->bag->peek('not_existing', array('default')));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
}
public function testGet()
{
- $this->assertNull($this->bag->get('non_existing'));
- $this->assertEquals('default', $this->bag->get('not_existing', 'default'));
- $this->assertEquals('A previous flash message', $this->bag->get('notice'));
- $this->assertNull($this->bag->get('notice'));
+ $this->assertEquals(array(), $this->bag->get('non_existing'));
+ $this->assertEquals(array('default'), $this->bag->get('not_existing', array('default')));
+ $this->assertEquals(array('A previous flash message'), $this->bag->get('notice'));
+ $this->assertEquals(array(), $this->bag->get('notice'));
}
public function testAll()
@@ -90,8 +90,8 @@ class FlashBagTest extends \PHPUnit_Framework_TestCase
$this->bag->set('notice', 'Foo');
$this->bag->set('error', 'Bar');
$this->assertEquals(array(
- 'notice' => 'Foo',
- 'error' => 'Bar'), $this->bag->all()
+ 'notice' => array('Foo'),
+ 'error' => array('Bar')), $this->bag->all()
);
$this->assertEquals(array(), $this->bag->all());
@@ -101,7 +101,7 @@ class FlashBagTest extends \PHPUnit_Framework_TestCase
{
$this->bag->set('notice', 'Foo');
$this->bag->set('notice', 'Bar');
- $this->assertEquals('Bar', $this->bag->peek('notice'));
+ $this->assertEquals(array('Bar'), $this->bag->peek('notice'));
}
public function testHas()
@@ -120,15 +120,15 @@ class FlashBagTest extends \PHPUnit_Framework_TestCase
$this->bag->set('notice', 'Foo');
$this->bag->set('error', 'Bar');
$this->assertEquals(array(
- 'notice' => 'Foo',
- 'error' => 'Bar',
+ 'notice' => array('Foo'),
+ 'error' => array('Bar'),
), $this->bag->peekAll()
);
$this->assertTrue($this->bag->has('notice'));
$this->assertTrue($this->bag->has('error'));
$this->assertEquals(array(
- 'notice' => 'Foo',
- 'error' => 'Bar',
+ 'notice' => array('Foo'),
+ 'error' => array('Bar'),
), $this->bag->peekAll()
);
}
diff --git a/tests/Symfony/Tests/Component/HttpFoundation/Session/SessionTest.php b/tests/Symfony/Tests/Component/HttpFoundation/Session/SessionTest.php
index 8da6885b26..8d78df9335 100644
--- a/tests/Symfony/Tests/Component/HttpFoundation/Session/SessionTest.php
+++ b/tests/Symfony/Tests/Component/HttpFoundation/Session/SessionTest.php
@@ -175,13 +175,21 @@ class SessionTest extends \PHPUnit_Framework_TestCase
$this->session->setFlashes($array);
$this->assertEquals($array, $this->session->getFlashes());
$this->assertEquals(array(), $this->session->getFlashes());
+ $this->session->getFlashBag()->add('notice', 'foo');
+
+ // test that BC works by only retrieving the first added.
+ $this->session->getFlashBag()->add('notice', 'foo2');
+ $this->assertEquals(array('notice' => 'foo'), $this->session->getFlashes());
}
public function testGetSetFlash()
{
$this->assertNull($this->session->getFlash('notice'));
$this->assertEquals('default', $this->session->getFlash('notice', 'default'));
- $this->session->setFlash('notice', 'foo');
+ $this->session->getFlashBag()->add('notice', 'foo');
+ $this->session->getFlashBag()->add('notice', 'foo2');
+
+ // test that BC works by only retrieving the first added.
$this->assertEquals('foo', $this->session->getFlash('notice'));
$this->assertNull($this->session->getFlash('notice'));
}
diff --git a/tests/Symfony/Tests/Component/HttpFoundation/Session/Storage/MockFileSessionStorageTest.php b/tests/Symfony/Tests/Component/HttpFoundation/Session/Storage/MockFileSessionStorageTest.php
index c0453df977..3212939de8 100644
--- a/tests/Symfony/Tests/Component/HttpFoundation/Session/Storage/MockFileSessionStorageTest.php
+++ b/tests/Symfony/Tests/Component/HttpFoundation/Session/Storage/MockFileSessionStorageTest.php
@@ -81,7 +81,7 @@ class MockFileSessionStorageTest extends \PHPUnit_Framework_TestCase
$storage->start();
$this->assertEquals('108', $storage->getBag('attributes')->get('new'));
$this->assertTrue($storage->getBag('flashes')->has('newkey'));
- $this->assertEquals('test', $storage->getBag('flashes')->peek('newkey'));
+ $this->assertEquals(array('test'), $storage->getBag('flashes')->peek('newkey'));
}
public function testMultipleInstances()