8000 feature #45047 [Notifier] Use Importance level to set flash message t… · symfony/symfony@28ab68e · GitHub
[go: up one dir, main page]

Skip to content

Commit 28ab68e

Browse files
committed
feature #45047 [Notifier] Use Importance level to set flash message type (benr77, fabpot)
This PR was merged into the 6.1 branch. Discussion ---------- [Notifier] Use Importance level to set flash message type | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #43187 | License | MIT Instead of hard-coding the flash message type, set the flash message type based on the "importance" level of the notification. Commits ------- 1904fed Add missing dep 7ce1b9c [Notifier] Add Importance level to flash message type
2 parents 50ca517 + 1904fed commit 28ab68e

File tree

10 files changed

+240
-3
lines changed

10 files changed

+240
-3
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Notifier\ChatterInterface;
2323
use Symfony\Component\Notifier\EventListener\NotificationLoggerListener;
2424
use Symfony\Component\Notifier\EventListener\SendFailedMessageToNotifierListener;
25+
use Symfony\Component\Notifier\FlashMessage\DefaultFlashMessageImportanceMapper;
2526
use Symfony\Component\Notifier\Message\ChatMessage;
2627
use Symfony\Component\Notifier\Message\PushMessage;
2728
use Symfony\Component\Notifier\Message\SmsMessage;
@@ -43,8 +44,11 @@
4344
->set('notifier.channel_policy', ChannelPolicy::class)
4445
->args([[]])
4546

47+
->set('notifier.flash_message_importance_mapper', DefaultFlashMessageImportanceMapper::class)
48+
->args([[]])
49+
4650
->set('notifier.channel.browser', BrowserChannel::class)
47-
->args([service('request_stack')])
51+
->args([service('request_stack'), service('notifier.flash_message_importance_mapper')])
4852
->tag('notifier.channel', ['channel' => 'browser'])
4953

5054
->set('notifier.channel.chat', ChatChannel::class)

src/Symfony/Component/Notifier/CHANGELOG.md

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

4+
6.1
5+
---
6+
7+
* Use importance level to set flash message type
8+
49
5.4
510
---
611

src/Symfony/Component/Notifier/Channel/BrowserChannel.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Notifier\Channel;
1313

1414
use Symfony\Component\HttpFoundation\RequestStack;
15+
use Symfony\Component\Notifier\FlashMessage\DefaultFlashMessageImportanceMapper;
16+
use Symfony\Component\Notifier\FlashMessage\FlashMessageImportanceMapperInterface;
1517
use Symfony\Component\Notifier\Notification\Notification;
1618
use Symfony\Component\Notifier\Recipient\RecipientInterface;
1719

@@ -22,9 +24,12 @@ final class BrowserChannel implements ChannelInterface
2224
{
2325
private RequestStack $stack;
2426

25-
public function __construct(RequestStack $stack)
27+
private FlashMessageImportanceMapperInterface $mapper;
28+
29+
public function __construct(RequestStack $stack, FlashMessageImportanceMapperInterface $mapper = new DefaultFlashMessageImportanceMapper())
2630
{
2731
$this->stack = $stack;
32+
$this->mapper = $mapper;
2833
}
2934

3035
public function notify(Notification $notification, RecipientInterface $recipient, string $transportName = null): void
@@ -37,7 +42,7 @@ public function notify(Notification $notification, RecipientInterface $recipient
3742
if ($notification->getEmoji()) {
3843
$message = $notification->getEmoji().' '.$message;
3944
}
40-
$request->getSession()->getFlashBag()->add('notification', $message);
45+
$request->getSession()->getFlashBag()->add($this->mapper->flashMessageTypeFromImportance($notification->getImportance()), $message);
4146
}
4247

4348
public function supports(Notification $notification, RecipientInterface $recipient): bool
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\Exception;
13+
14+
/**
15+
* @author Ben Roberts <ben@headsnet.com>
16+
*/
17+
class FlashMessageImportanceMapperException extends LogicException
18+
{
19+
public function __construct(string $importance, string $mappingClass)
20+
{
21+
$message = sprintf('The "%s" Notifier flash message mapper does not support an importance value of "%s".', $mappingClass, $importance);
22+
23+
parent::__construct($message);
24+
}
25+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\FlashMessage;
13+
14+
use Symfony\Component\Notifier\Exception\FlashMessageImportanceMapperException;
15+
16+
/**
17+
* @author Ben Roberts <ben@headsnet.com>
18+
*/
19+
abstract class AbstractFlashMessageImportanceMapper
20+
{
21+
public function flashMessageTypeFromImportance(string $importance): string
22+
{
23+
if (!\array_key_exists($importance, static::IMPORTANCE_MAP)) {
24+
throw new FlashMessageImportanceMapperException($importance, static::class);
25+
}
26+
27+
return static::IMPORTANCE_MAP[$importance];
28+
}
29+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\FlashMessage;
13+
14+
use Symfony\Component\Notifier\Notification\Notification;
15+
16+
/**
17+
* @author Ben Roberts <ben@headsnet.com>
18+
*/
19+
class BootstrapFlashMessageImportanceMapper extends AbstractFlashMessageImportanceMapper implements FlashMessageImportanceMapperInterface
20+
{
21+
protected const IMPORTANCE_MAP = [
22+
Notification::IMPORTANCE_URGENT => 'danger',
23+
Notification::IMPORTANCE_HIGH => 'warning',
24+
Notification::IMPORTANCE_MEDIUM => 'info',
25+
Notification::IMPORTANCE_LOW => 'success',
26+
];
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\FlashMessage;
13+
14+
use Symfony\Component\Notifier\Notification\Notification;
15+
16+
/**
17+
* @author Ben Roberts <ben@headsnet.com>
18+
*/
19+
class DefaultFlashMessageImportanceMapper extends AbstractFlashMessageImportanceMapper implements FlashMessageImportanceMapperInterface
20+
{
21+
protected const IMPORTANCE_MAP = [
22+
Notification::IMPORTANCE_URGENT => 'notification',
23+
Notification::IMPORTANCE_HIGH => 'notification',
24+
Notification::IMPORTANCE_MEDIUM => 'notification',
25+
Notification::IMPORTANCE_LOW => 'notification',
26+
];
27+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\FlashMessage;
13+
14+
use Symfony\Component\Notifier\Exception\FlashMessageImportanceMapperException;
15+
16+
/**
17+
* @author Ben Roberts <ben@headsnet.com>
18+
*/
19+
interface FlashMessageImportanceMapperInterface
20+
{
21+
/**
22+
* @throws FlashMessageImportanceMapperException
23+
*/
24+
public function flashMessageTypeFromImportance(string $importance): string;
25+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\Tests\Channel;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\RequestStack;
17+
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
18+
use Symfony\Component\HttpFoundation\Session\Session;
19+
use Symfony\Component\Notifier\Channel\BrowserChannel;
20+
use Symfony\Component\Notifier\Exception\FlashMessageImportanceMapperException;
21+
use Symfony\Component\Notifier\FlashMessage\BootstrapFlashMessageImportanceMapper;
22+
use Symfony\Component\Notifier\FlashMessage\DefaultFlashMessageImportanceMapper;
23+
use Symfony\Component\Notifier\FlashMessage\FlashMessageImportanceMapperInterface;
24+
use Symfony\Component\Notifier\Notification\Notification;
25+
use Symfony\Component\Notifier\Recipient\Recipient;
26+
27+
/**
28+
* @author Ben Roberts <ben@headsnet.com>
29+
*/
30+
class BrowserChannelTest extends TestCase
31+
{
32+
/**
33+
* @dataProvider defaultFlashMessageImportanceDataProvider
34+
*/
35+
public function testImportanceLevelIsReflectedInFlashMessageType(
36+
FlashMessageImportanceMapperInterface $mapper,
37+
string $importance,
38+
string $expectedFlashMessageType
39+
) {
40+
$session = $this->createMock(Session::class);
41+
$session->method('getFlashBag')->willReturn(new FlashBag());
42+
$browserChannel = $this->buildBrowserChannel($session, $mapper);
43+
$notification = new Notification();
44+
$notification->importance($importance);
45+
$recipient = new Recipient('hello@example.com');
46+
47+
$browserChannel->notify($notification, $recipient);
48+
49+
$this->assertEquals($expectedFlashMessageType, array_key_first($session->getFlashBag()->all()));
50+
}
51+
52+
public function testUnknownImportanceMappingIsReported()
53+
{
54+
$session = $this->createMock(Session::class);
55+
$session->method('getFlashBag')->willReturn(new FlashBag());
56+
$browserChannel = $this->buildBrowserChannel($session, new DefaultFlashMessageImportanceMapper());
57+
$notification = new Notification();
58+
$notification->importance('unknown-importance-string');
59+
$recipient = new Recipient('hello@example.com');
60+
61+
$this->expectException(FlashMessageImportanceMapperException::class);
62+
63+
$browserChannel->notify($notification, $recipient);
64+
}
65+
66+
public function defaultFlashMessageImportanceDataProvider(): array
67+
{
68+
return [
69+
[new DefaultFlashMessageImportanceMapper(), Notification::IMPORTANCE_URGENT, 'notification'],
70+
[new DefaultFlashMessageImportanceMapper(), Notification::IMPORTANCE_HIGH, 'notification'],
71+
[new DefaultFlashMessageImportanceMapper(), Notification::IMPORTANCE_MEDIUM, 'notification'],
72+
[new DefaultFlashMessageImportanceMapper(), Notification::IMPORTANCE_LOW, 'notification'],
73+
[new BootstrapFlashMessageImportanceMapper(), Notification::IMPORTANCE_URGENT, 'danger'],
74+
[new BootstrapFlashMessageImportanceMapper(), Notification::IMPORTANCE_HIGH, 'warning'],
75+
[new BootstrapFlashMessageImportanceMapper(), Notification::IMPORTANCE_MEDIUM, 'info'],
76+
[new BootstrapFlashMessageImportanceMapper(), Notification::IMPORTANCE_LOW, 'success'],
77+
];
78+
}
79+
80+
private function buildBrowserChannel(Session $session, FlashMessageImportanceMapperInterface $mapper): BrowserChannel
81+
{
82+
$request = $this->createMock(Request::class);
83+
$request->method('getSession')->willReturn($session);
84+
$requestStack = $this->createStub(RequestStack::class);
85+
$requestStack->method('getCurrentRequest')->willReturn($request);
86+
87+
return new BrowserChannel($requestStack, $mapper);
88+
}
89+
}

src/Symfony/Component/Notifier/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"require-dev": {
2323
"symfony/event-dispatcher-contracts": "^2|^3",
2424
"symfony/http-client-contracts": "^2|^3",
25+
"symfony/http-foundation": "^5.4|^6.0",
2526
"symfony/messenger": "^5.4|^6.0"
2627
},
2728
"conflict": {

0 commit comments

Comments
 (0)
0