Skip to content

Commit bd61d62

Browse files
committed
keep previous cookies
we recently fixed that we lose previous cookies. but the fix was keeping the messages in the session and only setting the cookie on the last redirect, which means the messages are lost if the session is destroyed (e.g. redirect to page outside firewall) changed to merge the flash messages cookie from requests into the flashes. and using array_merge_recursive to keep multiple messages with the same key.
1 parent 5df759a commit bd61d62

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
Changelog
22
=========
33

4+
2.9.2
5+
-----
6+
7+
### Fixed
8+
9+
* 2.9.1 fixed overwriting flash messages on multiple redirects, but introduced
10+
a risk to lose flash messages when redirecting to a path that is outside the
11+
firewall or destroys the session.
12+
This version hopefully fixes both cases. Existing flash messages in a request
13+
cookie are merged with new flash messages from the session.
14+
415
2.9.1
516
-----
617

src/EventListener/FlashMessageListener.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,26 +87,28 @@ public function onKernelResponse(FlashMessageResponseEvent $event)
8787
return;
8888
}
8989

90-
$response = $event->getResponse();
91-
92-
// If the response is a redirect, we should wait until the final response
93-
// is reached
94-
if ($response->isRedirect()) {
95-
return;
96-
}
97-
9890
$flashBag = $this->session->getFlashBag();
9991
$flashes = $flashBag->all();
10092

10193
if (empty($flashes)) {
10294
return;
10395
}
10496

97+
$response = $event->getResponse();
98+
10599
$cookies = $response->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
106100
$host = (null === $this->options['host']) ? '' : $this->options['host'];
107101
if (isset($cookies[$host][$this->options['path']][$this->options['name']])) {
108102
$rawCookie = $cookies[$host][$this->options['path']][$this->options['name']]->getValue();
109-
$flashes = array_merge($flashes, json_decode($rawCookie));
103+
$flashes = array_merge_recursive($flashes, json_decode($rawCookie, true));
104+
}
105+
106+
// Preserve existing flash message cookie from previous redirect if there was one.
107+
// This covers multiple redirects where each redirect adds flash messages.
108+
$request = $event->getRequest();
109+
if ($request->cookies->has($this->options['name'])) {
110+
$rawCookie = $request->cookies->get($this->options['name']);
111+
$flashes = array_merge_recursive($flashes, json_decode($rawCookie, true));
110112
}
111113

112114
$cookie = new Cookie(

tests/Functional/EventListener/FlashMessageListenerTest.php

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
1515
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
16-
use Symfony\Component\HttpFoundation\Cookie;
1716

1817
class FlashMessageListenerTest extends WebTestCase
1918
{
@@ -33,7 +32,6 @@ public function testFlashMessageCookieIsSet()
3332

3433
$found = false;
3534
foreach ($cookies as $cookie) {
36-
/** @var Cookie $cookie */
3735
if ('flash_cookie_name' !== $cookie->getName()) {
3836
continue;
3937
}
@@ -45,9 +43,7 @@ public function testFlashMessageCookieIsSet()
4543
$found = true;
4644
}
4745

48-
if (!$found) {
49-
$this->fail('Cookie flash_cookie_name not found in the cookie response header: '.implode(',', $cookies));
50-
}
46+
$this->assertTrue($found, 'Cookie "flash_cookie_name" not found in response cookies');
5147
}
5248

5349
public function testFlashMessageCookieIsSetOnRedirect()
@@ -65,7 +61,6 @@ public function testFlashMessageCookieIsSetOnRedirect()
6561

6662
$found = false;
6763
foreach ($cookies as $cookie) {
68-
/** @var Cookie $cookie */
6964
if ('flash_cookie_name' !== $cookie->getName()) {
7065
continue;
7166
}
@@ -77,8 +72,6 @@ public function testFlashMessageCookieIsSetOnRedirect()
7772
$found = true;
7873
}
7974

80-
if (!$found) {
81-
$this->fail('Cookie flash_cookie_name not found in the cookie response header: '.implode(',', $cookies));
82-
}
75+
$this->assertTrue($found, 'Cookie "flash_cookie_name" not found in response cookies');
8376
}
8477
}

0 commit comments

Comments
 (0)