Skip to content

[2.1][HttpFoundation] Multiple session flash messages #3267

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from Mar 23, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG-2.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,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

Expand Down
21 changes: 11 additions & 10 deletions UPGRADE-2.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,30 +307,31 @@ UPGRADE FROM 2.0 to 2.1
Before:

```
{% if app.session.hasFlash('notice') %}
{% if app.session.flashbag.has('notice') %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should keep it like it was as you need to keep how it was done in Symfony 2.0, not before your patch.

<div class="flash-notice">
{{ app.session.flash('notice') }}
{{ app.session.flashbag.get('notice') }}
</div>
{% endif %}
```

After:

```
{% if app.session.flashbag.has('notice') %}
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="flash-notice">
{{ app.session.flashbag.get('notice') }}
{{ flashMessage }}
</div>
{% endif %}
{% endfor %}
```

You can process all flash messges in a single loop with:

```
{% for type, flashMessage in app.session.flashbag.all() %}
<div class="flash-{{ type }}">
{{ flashMessage }}
</div>
{% for type, flashMessages in app.session.flashbag.all() %}
{% for flashMessage in flashMessages) %}
<div class="flash-{{ type }}">
{{ flashMessage }}
</div>
{% endfor %}
{% endfor %}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ public function get($name, $default = null)
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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function showFlashAction()
$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.';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ public function testFlash()

$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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,15 @@ public function initialize(array &$flashes)
/**
* {@inheritdoc}
*/
public function peek($type, $default = null)
public function add($type, $message)
{
$this->flashes['new'][$type][] = $message;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this generate a notice is flashes['new'][$type] is not yet defined? I seem to recall it doing so for me in the past.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't. $foo['bar']['baz'] = true; is valid for example

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good. Just checking.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reading throw a notice. Writing does not

}

/**
* {@inheritdoc}
*/
public function peek($type, array $default = array())
{
return $this->has($type) ? $this->flashes['display'][$type] : $default;
}
Expand All @@ -91,7 +99,7 @@ public function peekAll()
/**
* {@inheritdoc}
*/
public function get($type, $default = null)
public function get($type, array $default = array())
{
$return = $default;

Expand Down Expand Up @@ -129,17 +137,17 @@ public function setAll(array $messages)
/**
* {@inheritdoc}
*/
public function set($type, $message)
public function set($type, $messages)
{
$this->flashes['new'][$type] = $message;
$this->flashes['new'][$type] = (array)$messages;
}

/**
* {@inheritdoc}
*/
public function has($type)
{
return array_key_exists($type, $this->flashes['display']);
return array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type];
}

/**
Expand All @@ -163,9 +171,6 @@ public function getStorageKey()
*/
public function clear()
{
$return = $this->all();
$this->flashes = array('display' => array(), 'new' => array());

return $return;
return $this->all();
}
}
18 changes: 13 additions & 5 deletions src/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,15 @@ public function initialize(array &$flashes)
/**
* {@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;
}
Expand All @@ -84,7 +92,7 @@ public function peekAll()
/**
* {@inheritdoc}
*/
public function get($type, $default = null)
public function get($type, array $default = array())
{
if (!$this->has($type)) {
return $default;
Expand All @@ -111,9 +119,9 @@ public function all()
/**
* {@inheritdoc}
*/
public function set($type, $message)
public function set($type, $messages)
{
$this->flashes[$type] = $message;
$this->flashes[$type] = (array) $messages;
}

/**
Expand All @@ -129,7 +137,7 @@ public function setAll(array $messages)
*/
public function has($type)
{
return array_key_exists($type, $this->flashes);
return array_key_exists($type, $this->flashes) && $this->flashes[$type];
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ function set($type, $message);
* 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.
Expand All @@ -49,11 +49,11 @@ function peekAll();
* 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.
Expand Down
27 changes: 20 additions & 7 deletions src/Symfony/Component/HttpFoundation/Session/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,16 @@ public function getFlashBag()
*/
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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be simplified? It's not clear why we have to manually build out the return value.

is_array($all) ? return $all : return array();

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No no, this API is designed to replicate the old functionality (no arrays). All this API is already deprecated.

}

/**
Expand All @@ -239,7 +248,9 @@ public function getFlashes()
*/
public function setFlashes($values)
{
$this->getBag('flashes')->setAll($values);
foreach ($values as $name => $value) {
$this->getBag($this->flashName)->set($name, $value);
}
}

/**
Expand All @@ -252,7 +263,9 @@ public function setFlashes($values)
*/
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);
}

/**
Expand All @@ -263,7 +276,7 @@ public function getFlash($name, $default = null)
*/
public function setFlash($name, $value)
{
$this->getBag('flashes')->set($name, $value);
$this->getBag($this->flashName)->set($name, $value);
}

/**
Expand All @@ -275,7 +288,7 @@ public function setFlash($name, $value)
*/
public function hasFlash($name)
{
return $this->getBag('flashes')->has($name);
return $this->getBag($this->flashName)->has($name);
}

/**
Expand All @@ -285,7 +298,7 @@ public function hasFlash($name)
*/
public function removeFlash($name)
{
$this->getBag('flashes')->get($name);
$this->getBag($this->flashName)->get($name);
}

/**
Expand All @@ -295,6 +308,6 @@ public function removeFlash($name)
*/
public function clearFlashes()
{
return $this->getBag('flashes')->clear();
return $this->getBag($this->flashName)->clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function setUp()
{
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);
}

Expand All @@ -47,16 +47,16 @@ public function tearDown()
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()
Expand All @@ -75,16 +75,16 @@ public function testGetSetName()

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()
Expand Down Expand Up @@ -123,10 +123,10 @@ public function testPeekAll()

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()
Expand All @@ -141,7 +141,7 @@ public function testAll()
$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()
);

Expand All @@ -150,6 +150,6 @@ public function testAll()

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());
}
}
Loading