Skip to content

Commit f9a2ab3

Browse files
committed
[Notifier] added the component
0 parents  commit f9a2ab3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2886
-0
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/Tests export-ignore
2+
/phpunit.xml.dist export-ignore

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
phpunit.xml
3+
vendor/

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CHANGELOG
2+
=========
3+
4+
5.0.0
5+
-----
6+
7+
* Introduced the component as experimental

Channel/AbstractChannel.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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\Channel;
13+
14+
use Symfony\Component\Messenger\MessageBusInterface;
15+
use Symfony\Component\Notifier\Exception\LogicException;
16+
use Symfony\Component\Notifier\Transport\TransportInterface;
17+
18+
/**
19+
* @author Fabien Potencier <fabien@symfony.com>
20+
*
21+
* @experimental in 5.0
22+
*/
23+
abstract class AbstractChannel implements ChannelInterface
24+
{
25+
protected $transport;
26+
protected $bus;
27+
28+
public function __construct(TransportInterface $transport = null, MessageBusInterface $bus = null)
29+
{
30+
if (null === $transport && null === $bus) {
31+
throw new LogicException(sprintf('"%s" needs a Transport or a Bus but both cannot be "null".', static::class));
32+
}
33+
34+
$this->transport = $transport;
35+
$this->bus = $bus;
36+
}
37+
}

Channel/BrowserChannel.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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\Channel;
13+
14+
use Symfony\Component\HttpFoundation\RequestStack;
15+
use Symfony\Component\Messenger\MessageBusInterface;
16+
use Symfony\Component\Notifier\Notification\Notification;
17+
use Symfony\Component\Notifier\Recipient\Recipient;
18+
19+
/**
20+
* @author Fabien Potencier <fabien@symfony.com>
21+
*
22+
* @experimental in 5.0
23+
*/
24+
final class BrowserChannel implements ChannelInterface
25+
{
26+
private $stack;
27+
28+
public function __construct(RequestStack $stack)
29+
{
30+
$this->stack = $stack;
31+
}
32+
33+
public function notify(Notification $notification, Recipient $recipient, string $transportName = null, MessageBusInterface $bus = null): void
34+
{
35+
if (null === $request = $this->stack->getCurrentRequest()) {
36+
return;
37+
}
38+
39+
$message = $notification->getSubject();
40+
if ($notification->getEmoji()) {
41+
$message = $notification->getEmoji().' '.$message;
42+
}
43+
$request->getSession()->getFlashBag()->add('notification', $message);
44+
}
45+
46+
public function supports(Notification $notification, Recipient $recipient): bool
47+
{
48+
return true;
49+
}
50+
}

Channel/ChannelInterface.php

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\Channel;
13+
14+
use Symfony\Component\Notifier\Notification\Notification;
15+
use Symfony\Component\Notifier\Recipient\Recipient;
16+
17+
/**
18+
* @author Fabien Potencier <fabien@symfony.com>
19+
*
20+
* @experimental in 5.0
21+
*/
22+
interface ChannelInterface
23+
{
24+
public function notify(Notification $notification, Recipient $recipient, string $transportName = null): void;
25+
26+
public function supports(Notification $notification, Recipient $recipient): bool;
27+
}

Channel/ChannelPolicy.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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\Channel;
13+
14+
use Symfony\Component\Notifier\Exception\InvalidArgumentException;
15+
16+
/**
17+
* @author Fabien Potencier <fabien@symfony.com>
18+
*
19+
* @experimental in 5.0
20+
*/
21+
final class ChannelPolicy implements ChannelPolicyInterface
22+
{
23+
private $policy;
24+
25+
public function __construct(array $policy)
26+
{
27+
$this->policy = $policy;
28+
}
29+
30+
public function getChannels(string $importance): array
31+
{
32+
if (!isset($this->policy[$importance])) {
33+
throw new InvalidArgumentException(sprintf('Importance "%s" is not defined in the Policy.', $importance));
34+
}
35+
36+
return $this->policy[$importance];
37+
}
38+
}

Channel/ChannelPolicyInterface.php

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\Channel;
13+
14+
/**
15+
* @author Fabien Potencier <fabien@symfony.com>
16+
*
17+
* @experimental in 5.0
18+
*/
19+
interface ChannelPolicyInterface
20+
{
21+
/**
22+
* @return string[]
23+
*/
24+
public function getChannels(string $importance): array;
25+
}

Channel/ChatChannel.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Channel;
13+
14+
use Symfony\Component\Notifier\Exception\LogicException;
15+
use Symfony\Component\Notifier\Message\ChatMessage;
16+
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
17+
use Symfony\Component\Notifier\Notification\Notification;
18+
use Symfony\Component\Notifier\Recipient\Recipient;
19+
20+
/**
21+
* @author Fabien Potencier <fabien@symfony.com>
22+
*
23+
* @experimental in 5.0
24+
*/
25+
class ChatChannel extends AbstractChannel
26+
{
27+
public function notify(Notification $notification, Recipient $recipient, string $transportName = null): void
28+
{
29+
if (null === $transportName) {
30+
throw new LogicException('A Chat notification must have a transport defined.');
31+
}
32+
33+
$message = null;
34+
if ($notification instanceof ChatNotificationInterface) {
35+
$message = $notification->asChatMessage($recipient, $transportName);
36+
}
37+
38+
if (null === $message) {
39+
$message = ChatMessage::fromNotification($notification, $recipient, $transportName);
40+
}
41+
42+
$message->transport($transportName);
43+
44+
if (null === $this->bus) {
45+
$this->transport->send($message);
46+
} else {
47+
$this->bus->dispatch($message);
48+
}
49+
}
50+
51+
public function supports(Notification $notification, Recipient $recipient): bool
52+
{
53+
return true;
54+
}
55+
}

Channel/EmailChannel.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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\Channel;
13+
14+
use Symfony\Component\Mailer\Envelope;
15+
use Symfony\Component\Mailer\Messenger\SendEmailMessage;
16+
use Symfony\Component\Mailer\Transport\TransportInterface;
17+
use Symfony\Component\Messenger\MessageBusInterface;
18+
use Symfony\Component\Mime\Email;
19+
use Symfony\Component\Notifier\Exception\LogicException;
20+
use Symfony\Component\Notifier\Message\EmailMessage;
21+
use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
22+
use Symfony\Component\Notifier\Notification\Notification;
23+
use Symfony\Component\Notifier\Recipient\Recipient;
24+
25+
/**
26+
* @author Fabien Potencier <fabien@symfony.com>
27+
*
28+
* @experimental in 5.0
29+
*/
30+
class EmailChannel implements ChannelInterface
31+
{
32+
private $transport;
33+
private $bus;
34+
private $from;
35+
private $envelope;
36+
37+
public function __construct(TransportInterface $transport = null, MessageBusInterface $bus = null, string $from = null, Envelope $envelope = null)
38+
{
39+
if (null === $transport && null === $bus) {
40+
throw new LogicException(sprintf('"%s" needs a Transport or a Bus but both cannot be "null".', static::class));
41+
}
42+
43+
$this->transport = $transport;
44+
$this->bus = $bus;
45+
$this->from = $from ?: ($envelope ? $envelope->getSender() : null);
46+
$this->envelope = $envelope;
47+
}
48+
49+
public function notify(Notification $notification, Recipient $recipient, string $transportName = null): void
50+
{
51+
$message = null;
52+
if ($notification instanceof EmailNotificationInterface) {
53+
$message = $notification->asEmailMessage($recipient, $transportName);
54+
}
55+
56+
$message = $message ?: EmailMessage::fromNotification($notification, $recipient, $transportName);
57+
$email = $message->getMessage();
58+
if ($email instanceof Email) {
59+
if (!$email->getFrom()) {
60+
if (null === $this->from) {
61+
throw new LogicException(sprintf('To send the "%s" notification by email, you should either configure a global "from" or set it in the "asEmailMessage()" method.', \get_class($notification)));
62+
}
63+
64+
$email->from($this->from);
65+
}
66+
67+
if (!$email->getTo()) {
68+
$email->to($recipient->getEmail());
69+
}
70+
}
71+
72+
if (null !== $this->envelope) {
73+
$message->envelope($this->envelope);
74+
}
75+
76+
if (null !== $transportName) {
77+
$message->transport($transportName);
78+
}
79+
80+
if (null === $this->bus) {
81+
$this->transport->send($message->getMessage(), $message->getEnvelope());
82+
} else {
83+
$this->bus->dispatch(new SendEmailMessage($message->getMessage(), $message->getEnvelope()));
84+
}
85+
}
86+
87+
public function supports(Notification $notification, Recipient $recipient): bool
88+
{
89+
return '' !== $recipient->getEmail();
90+
}
91+
}

0 commit comments

Comments
 (0)