Completed
Pull Request — master (#23)
by
unknown
09:20
created

ChannelManager::shouldSendNotification()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 6
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 3
crap 2
1
<?php
2
3
namespace Illuminate\Notifications;
4
5
use Ramsey\Uuid\Uuid;
6
use InvalidArgumentException;
7
use Illuminate\Support\Manager;
8
use Nexmo\Client as NexmoClient;
9
use Illuminate\Support\Collection;
10
use GuzzleHttp\Client as HttpClient;
11
use Illuminate\Contracts\Queue\ShouldQueue;
12
use Illuminate\Contracts\Bus\Dispatcher as Bus;
13
use Nexmo\Client\Credentials\Basic as NexmoCredentials;
14
use Illuminate\Contracts\Notifications\Factory as FactoryContract;
15
use Illuminate\Contracts\Notifications\Dispatcher as DispatcherContract;
16
17
class ChannelManager extends Manager implements DispatcherContract, FactoryContract
18
{
19
    /**
20
     * The default channels used to deliver messages.
21
     *
22
     * @var array
23
     */
24
    protected $defaultChannels = ['mail', 'database'];
25
26
    /**
27
     * Send the given notification to the given notifiable entities.
28
     *
29
     * @param  \Illuminate\Support\Collection|array|mixed  $notifiables
30
     * @param  mixed  $notification
31
     * @return void
32
     */
33
    public function send($notifiables, $notification)
34
    {
35
        if (! $notifiables instanceof Collection && ! is_array($notifiables)) {
36
            $notifiables = [$notifiables];
37
        }
38
39
        if ($notification instanceof ShouldQueue) {
40
            return $this->queueNotification($notifiables, $notification);
41
        }
42
43
        return $this->sendNow($notifiables, $notification);
44
    }
45
46
    /**
47
     * Send the given notification immediately.
48
     *
49
     * @param  \Illuminate\Support\Collection|array|mixed  $notifiables
50
     * @param  mixed  $notification
51
     * @return void
52
     */
53
    public function sendNow($notifiables, $notification, array $channels = null)
54
    {
55
        if (! $notifiables instanceof Collection && ! is_array($notifiables)) {
56
            $notifiables = [$notifiables];
57
        }
58
59
        $original = clone $notification;
60
61
        foreach ($notifiables as $notifiable) {
62
            $notification = clone $original;
63
64
            $notification->id = (string) Uuid::uuid4();
65
66
            $channels = $channels ?: $notification->via($notifiable);
67
68
            if (empty($channels)) {
69
                continue;
70
            }
71
72
            foreach ($channels as $channel) {
73
                if (! $this->shouldSendNotification($notifiable, $notification, $channel)) {
74
                    continue;
75
                }
76
77
                $response = $this->driver($channel)->send($notifiable, $notification);
78
79
                $this->app->make('events')->fire(
80
                    new Events\NotificationSent($notifiable, $notification, $channel, $response)
81
                );
82
            }
83
        }
84
    }
85
86
    /**
87
     * Determines if the notification can be sent.
88
     *
89
     * @param  mixed  $notifiable
90
     * @param  mixed  $notification
91
     * @param  string  $channel
92
     * @return bool
93
     */
94
    protected function shouldSendNotification($notifiable, $notification, $channel)
95
    {
96
        return $this->app->make('events')->until(
97
            new Events\NotificationSending($notifiable, $notification, $channel)
98
        ) !== false;
99
    }
100
101
    /**
102
     * Queue the given notification instances.
103
     *
104
     * @param  mixed  $notifiables
105
     * @param  array[\Illuminate\Notifcations\Channels\Notification]  $notification
0 ignored issues
show
Documentation introduced by
The doc-type array[\Illuminate\Notifc...\Channels\Notification] could not be parsed: Expected "]" at position 2, but found "\Illuminate\Notifcations\Channels\Notification". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
106
     * @return void
107
     */
108
    protected function queueNotification($notifiables, $notification)
109
    {
110
        if (version_compare($this->app->version(), '5.2', '<')) {
111
            $this->app->make(Bus::class)->dispatch(
112
                (new SendQueuedNotifications($notifiables, $notification))
113
                    ->onQueue($notification->queue)
114
                    ->delay($notification->delay)
115
            );
116
        } else {
117
            if (! $notifiables instanceof Collection && ! is_array($notifiables)) {
118
                $notifiables = [$notifiables];
119
            }
120
121
            $bus = $this->app->make(Bus::class);
122
123
            foreach ($notifiables as $notifiable) {
124
                foreach ($notification->via($notifiable) as $channel) {
125
                    $bus->dispatch(
126
                        (new SendQueuedNotifications($notifiables, $notification, [$channel]))
0 ignored issues
show
Bug introduced by
It seems like $notifiables can also be of type array; however, Illuminate\Notifications...ications::__construct() does only seem to accept object<Illuminate\Support\Collection>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
127
                            ->onConnection($notification->connection)
128
                            ->onQueue($notification->queue)
129
                            ->delay($notification->delay)
130
                    );
131
                }
132
            }
133
        }
134
    }
135
136
    /**
137
     * Get a channel instance.
138
     *
139
     * @param  string|null  $name
140
     * @return mixed
141
     */
142
    public function channel($name = null)
143
    {
144
        return $this->driver($name);
145
    }
146
147
    /**
148
     * Create an instance of the database driver.
149
     *
150
     * @return \Illuminate\Notifications\Channels\DatabaseChannel
151
     */
152
    protected function createDatabaseDriver()
153
    {
154
        return $this->app->make(Channels\DatabaseChannel::class);
155
    }
156
157
    /**
158
     * Create an instance of the broadcast driver.
159
     *
160
     * @return \Illuminate\Notifications\Channels\BroadcastChannel
161
     */
162
    protected function createBroadcastDriver()
163
    {
164
        return $this->app->make(Channels\BroadcastChannel::class);
165
    }
166
167
    /**
168
     * Create an instance of the mail driver.
169
     *
170
     * @return \Illuminate\Notifications\Channels\MailChannel
171
     */
172
    protected function createMailDriver()
173
    {
174
        return $this->app->make(Channels\MailChannel::class);
175
    }
176
177
    /**
178
     * Create an instance of the Nexmo driver.
179
     *
180
     * @return \Illuminate\Notifications\Channels\NexmoSmsChannel
181
     */
182
    protected function createNexmoDriver()
183
    {
184
        return new Channels\NexmoSmsChannel(
185
            new NexmoClient(new NexmoCredentials(
186
                $this->app['config']['services.nexmo.key'],
187
                $this->app['config']['services.nexmo.secret']
188
            )),
189
            $this->app['config']['services.nexmo.sms_from']
190
        );
191
    }
192
193
    /**
194
     * Create an instance of the Slack driver.
195
     *
196
     * @return \Illuminate\Notifications\Channels\SlackWebhookChannel
197
     */
198
    protected function createSlackDriver()
199
    {
200
        return new Channels\SlackWebhookChannel(new HttpClient);
201
    }
202
203
    /**
204
     * Create a new driver instance.
205
     *
206
     * @param  string  $driver
207
     * @return mixed
208
     *
209
     * @throws \InvalidArgumentException
210
     */
211
    protected function createDriver($driver)
212
    {
213
        try {
214
            return parent::createDriver($driver);
215
        } catch (InvalidArgumentException $e) {
216
            if (class_exists($driver)) {
217
                return $this->app->make($driver);
218
            }
219
220
            throw $e;
221
        }
222
    }
223
224
    /**
225
     * Get the default channel driver names.
226
     *
227
     * @return array
228
     */
229
    public function getDefaultDriver()
230
    {
231
        return $this->defaultChannels;
232
    }
233
234
    /**
235
     * Get the default channel driver names.
236
     *
237
     * @return array
238
     */
239
    public function deliversVia()
240
    {
241
        return $this->getDefaultDriver();
242
    }
243
244
    /**
245
     * Set the default channel driver names.
246
     *
247
     * @param  array|string  $channels
248
     * @return void
249
     */
250
    public function deliverVia($channels)
251
    {
252
        $this->defaultChannels = (array) $channels;
253
    }
254
}
255