Skip to content

Commit 14f4296

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 14f4296

File tree

2 files changed

+14
-18
lines changed

2 files changed

+14
-18
lines changed

src/EventListener/FlashMessageListener.php

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

1414
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1515
use Symfony\Component\HttpFoundation\Cookie;
16+
use Symfony\Component\HttpFoundation\Request;
1617
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
1718
use Symfony\Component\HttpFoundation\Session\Session;
1819
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
@@ -87,26 +88,28 @@ public function onKernelResponse(FlashMessageResponseEvent $event)
8788
return;
8889
}
8990

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-
9891
$flashBag = $this->session->getFlashBag();
9992
$flashes = $flashBag->all();
10093

10194
if (empty($flashes)) {
10295
return;
10396
}
10497

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

112115
$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)