• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

valkyrjaio / valkyrja / 21372746244

26 Jan 2026 08:25PM UTC coverage: 84.077% (+0.4%) from 83.691%
21372746244

push

github

web-flow
[Broadcast] Add tests and update Message class to be immutable (#396)

# Description

Add tests and update Message class to be immutable.

## Types of changes

- [X] Bug fix _(non-breaking change which fixes an issue)_
    <!-- Target the lowest major affected branch -->
- [ ] New feature _(non-breaking change which adds functionality)_
    <!-- Target master -->
- [X] Deprecation _(breaking change which removes functionality)_
    <!-- Target master -->
- [X] Breaking change _(fix or feature that would cause existing
functionality
  to change)_
<!-- Target master, unless this is a bug fix in which case let's chat
-->
- [ ] Documentation improvement
    <!-- Target appropriate branch -->

22 of 35 new or added lines in 4 files covered. (62.86%)

2 existing lines in 1 file now uncovered.

9816 of 11675 relevant lines covered (84.08%)

9.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.72
/src/Valkyrja/Notification/Notifier/Notifier.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <melechmizrachi@gmail.com>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13

14
namespace Valkyrja\Notification\Notifier;
15

16
use Override;
17
use Valkyrja\Broadcast\Broadcaster\Contract\BroadcasterContract;
18
use Valkyrja\Broadcast\Data\Message as BroadcastMessage;
19
use Valkyrja\Mail\Data\Message as MailMessage;
20
use Valkyrja\Mail\Mailer\Contract\MailerContract;
21
use Valkyrja\Notification\Data\Contract\NotifyContract;
22
use Valkyrja\Notification\Entity\Contract\NotifiableUserContract;
23
use Valkyrja\Notification\Factory\Contract\FactoryContract;
24
use Valkyrja\Notification\Notifier\Contract\NotifierContract;
25
use Valkyrja\Sms\Data\Message as SmsMessage;
26
use Valkyrja\Sms\Messenger\Contract\MessengerContract;
27
use Valkyrja\Throwable\Exception\InvalidArgumentException;
28

29
use function is_string;
30

31
class Notifier implements NotifierContract
32
{
33
    /**
34
     * The mail recipients.
35
     *
36
     * @var array<int, array{email: non-empty-string, name: string, body: non-empty-string, subject: non-empty-string, user?: NotifiableUserContract}>
37
     */
38
    protected array $mailRecipients = [];
39

40
    /**
41
     * The SMS recipients.
42
     *
43
     * @var array<int, array{to: non-empty-string, from: non-empty-string, text: non-empty-string, user?: NotifiableUserContract}>
44
     */
45
    protected array $smsRecipients = [];
46

47
    /**
48
     * The broadcast events.
49
     *
50
     * @var array<int, array{event: non-empty-string, channel: non-empty-string, message: non-empty-string, user?: NotifiableUserContract}>
51
     */
52
    protected array $broadcastEvents = [];
53

54
    public function __construct(
1✔
55
        protected FactoryContract $factory,
56
        protected BroadcasterContract $broadcaster,
57
        protected MailerContract $mailer,
58
        protected MessengerContract $sms,
59
    ) {
60
    }
1✔
61

62
    /**
63
     * @inheritDoc
64
     */
65
    #[Override]
×
66
    public function createNotification(string $name, array $data = []): NotifyContract
67
    {
68
        return $this->factory->createNotification($name, $data);
×
69
    }
70

71
    /**
72
     * @inheritDoc
73
     */
74
    #[Override]
×
75
    public function addMailRecipient(string $email, string $name = ''): static
76
    {
77
        $this->mailRecipients[] = [
×
78
            'email'   => $email,
×
79
            'name'    => $name,
×
80
            'subject' => 'Subject',
×
81
            'body'    => 'Body',
×
82
        ];
×
83

84
        return $this;
×
85
    }
86

87
    /**
88
     * @inheritDoc
89
     */
90
    #[Override]
×
91
    public function addSmsRecipient(string $phoneNumber): static
92
    {
93
        // TODO: Figure this out
94
        $this->smsRecipients[] = [
×
95
            'to'   => $phoneNumber,
×
96
            'from' => 'us',
×
97
            'text' => 'text',
×
98
        ];
×
99

100
        return $this;
×
101
    }
102

103
    /**
104
     * @inheritDoc
105
     */
106
    #[Override]
×
107
    public function addBroadcastEvent(string $event): static
108
    {
109
        $this->broadcastEvents[] = [
×
NEW
110
            'event'   => $event,
×
NEW
111
            'message' => 'message',
×
NEW
112
            'channel' => 'channel',
×
UNCOV
113
        ];
×
114

115
        return $this;
×
116
    }
117

118
    /**
119
     * @inheritDoc
120
     */
121
    #[Override]
×
122
    public function addUserRecipient(NotifiableUserContract $user): static
123
    {
124
        $this->addSmsUserRecipient($user);
×
125
        $this->addMailUserRecipient($user);
×
126
        $this->addBroadcastUserRecipient($user);
×
127

128
        return $this;
×
129
    }
130

131
    /**
132
     * @inheritDoc
133
     */
134
    #[Override]
×
135
    public function notify(NotifyContract $notify): void
136
    {
137
        // $notification = $this->getNotification($notificationName, $data);
138

139
        if ($notify->shouldSendBroadcastMessage()) {
×
140
            $this->notifyByBroadcast($notify);
×
141
        }
142

143
        if ($notify->shouldSendMailMessage()) {
×
144
            $this->notifyByMail($notify);
×
145
        }
146

147
        if ($notify->shouldSendSmsMessage()) {
×
148
            $this->notifyBySms($notify);
×
149
        }
150

151
        $this->resetRecipients();
×
152
    }
153

154
    /**
155
     * @inheritDoc
156
     */
157
    #[Override]
×
158
    public function notifyUser(NotifyContract $notify, NotifiableUserContract $user): void
159
    {
160
        $this->addUserRecipient($user);
×
161
        $this->notify($notify);
×
162
    }
163

164
    /**
165
     * @inheritDoc
166
     */
167
    #[Override]
×
168
    public function notifyUsers(NotifyContract $notify, NotifiableUserContract ...$users): void
169
    {
170
        foreach ($users as $user) {
×
171
            $this->addUserRecipient($user);
×
172
        }
173

174
        $this->notify($notify);
×
175
    }
176

177
    /**
178
     * Reset all the recipient arrays.
179
     */
180
    protected function resetRecipients(): void
×
181
    {
182
        $this->broadcastEvents = [];
×
183
        $this->mailRecipients  = [];
×
184
        $this->smsRecipients   = [];
×
185
    }
186

187
    /**
188
     * Add a user as an broadcast recipient.
189
     *
190
     * @param NotifiableUserContract $user The user
191
     */
192
    protected function addBroadcastUserRecipient(NotifiableUserContract $user): void
×
193
    {
194
        /** @var mixed $secretId */
195
        $secretId = $user::hasSecretIdField()
×
196
            ? $user->__get($user::getSecretIdField())
×
197
            : null;
×
198

NEW
199
        if (is_string($secretId) && $secretId !== '') {
×
200
            $this->broadcastEvents[] = [
×
NEW
201
                'event'   => $secretId,
×
NEW
202
                'message' => 'message',
×
NEW
203
                'channel' => 'channel',
×
NEW
204
                'user'    => $user,
×
UNCOV
205
            ];
×
206
        }
207
    }
208

209
    /**
210
     * Add a user as a mail recipient.
211
     *
212
     * @param NotifiableUserContract $user The user
213
     */
214
    protected function addMailUserRecipient(NotifiableUserContract $user): void
×
215
    {
216
        /** @var mixed $email */
217
        $email = $user->__get($user::getEmailField());
×
218
        /** @var mixed $name */
219
        $name = $user::hasNameField()
×
220
            ? $user->__get($user::getNameField())
×
221
            : '';
×
222

223
        if (! is_string($email) || $email === '') {
×
224
            throw new InvalidArgumentException('Invalid email provided');
×
225
        }
226

227
        if (! is_string($name)) {
×
228
            throw new InvalidArgumentException('Invalid name provided');
×
229
        }
230

231
        $this->mailRecipients[] = [
×
232
            'email'   => $email,
×
233
            'name'    => $name,
×
234
            'subject' => 'Subject',
×
235
            'body'    => 'Body',
×
236
            'user'    => $user,
×
237
        ];
×
238
    }
239

240
    /**
241
     * Add a user as an SMS recipient.
242
     *
243
     * @param NotifiableUserContract $user The user
244
     */
245
    protected function addSmsUserRecipient(NotifiableUserContract $user): void
×
246
    {
247
        /** @var mixed $phoneNumber */
248
        $phoneNumber = $user::hasPhoneNumberField()
×
249
            ? $user->__get($user::getPhoneNumberField())
×
250
            : null;
×
251

252
        if (is_string($phoneNumber) && $phoneNumber !== '') {
×
253
            $this->smsRecipients[] = [
×
254
                'to'   => $phoneNumber,
×
255
                'from' => 'us',
×
256
                'text' => 'test',
×
257
                'user' => $user,
×
258
            ];
×
259
        }
260
    }
261

262
    /**
263
     * Send a notification by broadcast.
264
     *
265
     * @param NotifyContract $notify The notification
266
     */
267
    protected function notifyByBroadcast(NotifyContract $notify): void
×
268
    {
269
        foreach ($this->broadcastEvents as $broadcastEvent) {
×
NEW
270
            $message = new BroadcastMessage(
×
NEW
271
                channel: $broadcastEvent['channel'],
×
NEW
272
                event: $broadcastEvent['event'],
×
NEW
273
                message: $broadcastEvent['message'],
×
NEW
274
            );
×
275

276
            $notify->broadcast($message);
×
277

278
            $this->broadcaster->send($message);
×
279
        }
280
    }
281

282
    /**
283
     * Send a notification by mail.
284
     *
285
     * @param NotifyContract $notify The notification
286
     */
287
    protected function notifyByMail(NotifyContract $notify): void
×
288
    {
289
        foreach ($this->mailRecipients as $mailRecipient) {
×
290
            $message = new MailMessage(
×
291
                $mailRecipient['email'],
×
292
                $mailRecipient['name'],
×
293
                $mailRecipient['subject'],
×
294
                $mailRecipient['body'],
×
295
            );
×
296

297
            $notify->mail($message);
×
298

299
            $this->mailer->send($message);
×
300
        }
301
    }
302

303
    /**
304
     * Send a notification by SMS.
305
     *
306
     * @param NotifyContract $notify The notification
307
     */
308
    protected function notifyBySms(NotifyContract $notify): void
×
309
    {
310
        foreach ($this->smsRecipients as $smsRecipient) {
×
311
            $message = new SmsMessage(
×
312
                $smsRecipient['to'],
×
313
                $smsRecipient['from'],
×
314
                $smsRecipient['text']
×
315
            );
×
316

317
            $notify->sms($message);
×
318

319
            $this->sms->send($message);
×
320
        }
321
    }
322
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc