-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathChannelManager.php
More file actions
158 lines (136 loc) · 5.36 KB
/
ChannelManager.php
File metadata and controls
158 lines (136 loc) · 5.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php
namespace IrishDan\NotificationBundle;
use IrishDan\NotificationBundle\Channel\ChannelInterface;
use IrishDan\NotificationBundle\Event\NotificationFailedEvent;
use IrishDan\NotificationBundle\Event\NotificationSentEvent;
use IrishDan\NotificationBundle\Notification\NotifiableInterface;
use IrishDan\NotificationBundle\Notification\NotificationInterface;
use IrishDan\NotificationBundle\Event\NotificationSendingEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Class ChannelManager
*
* @package NotificationBundle\Utils
*/
class ChannelManager
{
protected $channels = [];
protected $eventDispatcher;
protected $configuredChannels;
public function __construct(EventDispatcherInterface $eventDispatcher, array $configuredChannels)
{
$this->eventDispatcher = $eventDispatcher;
$this->configuredChannels = $configuredChannels;
}
/**
* @param array $recipients
* @return array
*/
protected function formatRecipients(array $recipients)
{
foreach ($recipients as $key => $recipient) {
if (!$recipient instanceof NotifiableInterface) {
unset($recipients[$key]);
}
}
return $recipients;
}
/**
* @param array $notifiables
* @param NotificationInterface $notification
*/
public function send(array $notifiables, NotificationInterface $notification)
{
$notifiables = $this->formatRecipients($notifiables);
$this->sendNow($notifiables, $notification);
}
public function sendNow(array $recipients, NotificationInterface $notification)
{
// Clone the original notification as will need a copy for each recipient;
$original = clone $notification;
// Set a uuid so notifications from different channels can be grouped.
// Needed when marking as read across all channels.
$uuid = uniqid();
foreach ($recipients as $notifiable) {
// Get all of the channels the notification would like to be send on.
// Then check each channel against what is configured in the system,
// and which channels the notifiable is subscribed to.
$viaChannels = $notification->getChannels();
foreach ($viaChannels as $channel) {
if (!$this->shouldSendNotification($notifiable, $notification, $channel)) {
continue;
}
$currentNotification = clone $original;
$this->formatNotification($notifiable, $currentNotification, $channel, $uuid);
try {
// Dispatch sending event.
$sendingEvent = new NotificationSendingEvent($currentNotification);
$this->eventDispatcher->dispatch(NotificationSendingEvent::NAME, $sendingEvent);
$response = $this->channels[$channel]->formatAndDispatch($currentNotification);
if ($response) {
// Dispatch sent event.
$successEvent = new NotificationSentEvent($currentNotification);
$this->eventDispatcher->dispatch(NotificationSentEvent::NAME, $successEvent);
}
} catch (\Exception $exception) {
// Dispatch sending failed event.
$successEvent = new NotificationFailedEvent($currentNotification);
$this->eventDispatcher->dispatch(NotificationFailedEvent::NAME, $successEvent);
throw $exception;
}
}
}
}
/**
* Based on the available channels (configured in system) the notifiable's subscribed channels,
* and the nofications determines if the notification can be sent.
*
* @param mixed $notifiable
* @param mixed $notification
* @param string $channel
* @return bool
*/
protected function shouldSendNotification(NotifiableInterface $notifiable, NotificationInterface $notification, $channel)
{
$notifiableChannels = $notifiable->getSubscribedChannels();
$configuredChannels = $notification->getChannels();
if (
in_array($channel, $configuredChannels)
&& in_array($channel, $notifiableChannels)
&& in_array($channel, $this->configuredChannels)
&& in_array($channel, array_keys($this->channels))
) {
return true;
}
return false;
}
/**
* @param NotifiableInterface $notifiable
* @param NotificationInterface $notification
* @param $channel
*/
protected function formatNotification(NotifiableInterface $notifiable, NotificationInterface $notification, $channel, $uuid)
{
$notification->setNotifiable($notifiable);
$notification->setChannel($channel);
$notification->setUuid($uuid);
}
/**
* Get a channel service
*
* @param string|null $name
* @return mixed
*/
public function getChannel($name = null)
{
return empty($this->channels[$name]) ? null : $this->channels[$name];
}
/**
* @param $channelName
* @param ChannelInterface $channel
*/
public function setChannel($channelName, ChannelInterface $channel)
{
$this->channels[$channelName] = $channel;
}
}