Issues (1)

src/PushMessage.php (1 issue)

Severity
1
<?php
2
3
namespace AlexLisenkov\LaravelWebPush;
4
5
use AlexLisenkov\LaravelWebPush\Contracts\MessageActionContract;
6
use AlexLisenkov\LaravelWebPush\Contracts\PushMessageContract;
7
use AlexLisenkov\LaravelWebPush\Contracts\PushSubscriptionContract;
8
use AlexLisenkov\LaravelWebPush\Contracts\WebPushContract;
9
use GuzzleHttp\Promise\PromiseInterface;
10
use Illuminate\Support\Facades\App;
11
12
class PushMessage implements PushMessageContract
13
{
14
    /**
15
     * JSON encoding options
16
     */
17
    public const DEFAULT_ENCODING_OPTIONS = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT;
18
19
    /**
20
     * Available notification directions
21
     */
22
    public const NOTIFICATION_DIRECTIONS = ['auto', 'ltr', 'rtl'];
23
24
    /**
25
     * The title that must be shown within the notification
26
     *
27
     * @var string
28
     */
29
    protected $title = '';
30
31
    /**
32
     * An array of actions to display in the notification. The members of the array should be an object literal. It may
33
     * contain the following values:
34
     *
35
     * @var MessageActionContract[]
36
     */
37
    protected $actions;
38
39
    /**
40
     * A badge resource is an icon representing the web application, or the category of the notification if the web
41
     * application sends a wide variety of notifications. It may be used to represent the notification when there is
42
     * not enough space to display the notification itself. It may also be displayed inside the notification, but then
43
     * it should have less visual priority than the image resource and icon resource.
44
     *
45
     * @string|null
46
     */
47
    protected $badge;
48
49
    /**
50
     * A string representing an extra content to display within the notification.
51
     *
52
     * @var string
53
     */
54
    protected $body = '';
55
56
    /**
57
     * Arbitrary data that you want to be associated with the notification. This can be of any data type.
58
     */
59
    protected $data;
60
61
    /**
62
     * The direction of the notification; it can be auto, ltr or rtl
63
     *
64
     * @var string
65
     */
66
    protected $dir = 'auto';
67
68
    /**
69
     * The URL of an image to be used as an icon by the notification.
70
     *
71
     * @var null|string
72
     */
73
    protected $icon;
74
75
    /**
76
     * An image resource is a picture shown as part of the content of the notification, and should be displayed with
77
     * higher visual priority than the icon resource and badge resource, though it may be displayed in fewer
78
     * circumstances.
79
     *
80
     * @var string|null
81
     */
82
    protected $image;
83
84
    /**
85
     * Specify the lang used within the notification. This string must be a valid BCP 47 language tag.
86
     * https://tools.ietf.org/html/bcp47
87
     *
88
     * @var string|null
89
     */
90
    protected $lang;
91
92
    /**
93
     * When set indicates that the end user should be alerted after the show steps have run with a new notification
94
     * that has the same tag as an existing notification.
95
     *
96
     * @bool
97
     */
98
    protected $renotify = false;
99
100
    /**
101
     * When set, indicates that on devices with a sufficiently large screen, the notification should remain readily
102
     * available until the user activates or dismisses the notification.
103
     *
104
     * @bool
105
     */
106
    protected $require_interaction = false;
107
108
    /**
109
     * An ID for a given notification that allows you to find, replace, or remove the notification using a script if
110
     * necessary.
111
     *
112
     * @var string|null
113
     */
114
    protected $tag;
115
116
    /**
117
     * Timestamp which is a DOMTimeStamp representing the time, in milliseconds since 00:00:00 UTC on 1 January 1970,
118
     * of the event for which the notification was created.
119
     * https://heycam.github.io/webidl/#DOMTimeStamp
120
     *
121
     * @var int|null
122
     */
123
    protected $timestamp;
124
125
    /**
126
     * When set indicates that no sounds or vibrations should be made.
127
     *
128
     * @var bool|null
129
     */
130
    protected $silent;
131
132
    /**
133
     * Topics are strings that can be used to replace a pending messages with a new message if they have matching topic
134
     * names. This is useful in scenarios where multiple messages are sent while a device is offline, and you really
135
     * only want a user to see the latest message when the device is turned on.
136
     *
137
     * @var string
138
     */
139
    protected $topic;
140
141
    /**
142
     * Urgency indicates to the push service how important a message is to the user. This can be used by the push
143
     * service to help conserve the battery life of a user's device by only waking up for important messages when
144
     * battery is low. It can be: very-low, low, normal or high
145
     *
146
     * @var string|null
147
     */
148
    protected $urgency;
149
150
    /**
151
     * https://w3c.github.io/vibration/#idl-def-vibratepattern
152
     * A vibration pattern to run with the display of the notification.
153
     * A vibration pattern can be an array with as few as one member.
154
     * The values are times in milliseconds where the even indices (0, 2, 4, etc.) indicate how long to vibrate and the
155
     * odd indices indicate how long to pause.
156
     * For example, [300, 100, 400] would vibrate 300ms, pause 100ms, then vibrate 400ms.
157
     *
158
     * @var array|null
159
     */
160
    protected $vibrate = [0, 200, 1000];
161
162
    /**
163
     * @param PushSubscriptionContract $push_subscription
164
     *
165
     * @return PromiseInterface
166
     */
167 1
    public function sendTo(PushSubscriptionContract $push_subscription): PromiseInterface
168
    {
169
        /** @var WebPushContract $web_push */
170 1
        $web_push = App::make(WebPushContract::class);
171
172 1
        return $web_push->sendMessage($this, $push_subscription);
173
    }
174
175
    /**
176
     * @return string
177
     */
178 1
    public function __toString(): string
179
    {
180 1
        return (string) $this->toJson();
181
    }
182
183
    /**
184
     * @param int $options
185
     *
186
     * @return false|string
187
     */
188 3
    public function toJson($options = self::DEFAULT_ENCODING_OPTIONS)
189
    {
190 3
        return json_encode($this->toArray(), $options);
191
    }
192
193
    /**
194
     * @return array
195
     */
196 9
    public function toArray(): array
197
    {
198 9
        return array_filter([
199 9
            'title' => $this->getTitle(),
200
            'options' => array_filter([
201 9
                'actions' => $this->mapActionsToArray(),
202 9
                'badge' => $this->getBadge(),
203 9
                'body' => $this->getBody(),
204 9
                'data' => $this->getData(),
205 9
                'dir' => $this->getDir(),
206 9
                'icon' => $this->getIcon(),
207 9
                'image' => $this->getImage(),
208 9
                'lang' => $this->getLang(),
209 9
                'renotify' => $this->getRenotify(),
210 9
                'requireInteraction' => $this->getRequireInteraction(),
211 9
                'silent' => $this->isSilent(),
212 9
                'tag' => $this->getTag(),
213 9
                'timestamp' => $this->getTimestamp(),
214 9
                'vibrate' => !$this->isSilent() ? $this->getVibrate() : null,
215
            ]),
216
        ]);
217
    }
218
219
    /**
220
     * Get Title
221
     *
222
     * @return string
223
     */
224 10
    public function getTitle(): string
225
    {
226 10
        return $this->title;
227
    }
228
229
    /**
230
     * Set Title
231
     *
232
     * @param string $title
233
     *
234
     * @return PushMessageContract
235
     */
236 5
    public function setTitle(string $title): PushMessageContract
237
    {
238 5
        $this->title = $title;
239
240 5
        return $this;
241
    }
242
243
    /**
244
     * @return array|null
245
     */
246 9
    private function mapActionsToArray(): ?array
247
    {
248 9
        if ($this->getActions() === null) {
0 ignored issues
show
The condition $this->getActions() === null is always false.
Loading history...
249 7
            return null;
250
        }
251
252 2
        $actions = $this->getActions();
253
254 2
        return array_map(function (MessageActionContract $action) {
255 1
            return $action->toArray();
256 2
        }, $actions);
257
    }
258
259
    /**
260
     * Get Actions
261
     *
262
     * @return MessageActionContract[]|null
263
     */
264 10
    public function getActions(): ?array
265
    {
266 10
        return $this->actions;
267
    }
268
269
    /**
270
     * Set Actions
271
     *
272
     * @param MessageActionContract[] $actions
273
     *
274
     * @return PushMessage
275
     */
276 5
    public function setActions(?array $actions): PushMessage
277
    {
278 5
        $this->assertActionsImplementContract($actions ?? []);
279
280 4
        $this->actions = $actions;
281
282 4
        return $this;
283
    }
284
285 5
    private function assertActionsImplementContract($actions): void
286
    {
287 5
        foreach ($actions as $action) {
288 2
            if (!$action instanceof MessageActionContract) {
289 1
                throw new \InvalidArgumentException(get_class($action) . ' must implement ' . MessageActionContract::class);
290
            }
291
        }
292 4
    }
293
294
    /**
295
     * Get Badge
296
     *
297
     * @return string|null
298
     */
299 10
    public function getBadge(): ?string
300
    {
301 10
        return $this->badge;
302
    }
303
304
    /**
305
     * Set Badge
306
     *
307
     * @param string $badge
308
     *
309
     * @return PushMessage
310
     */
311 1
    public function setBadge(string $badge): PushMessage
312
    {
313 1
        $this->badge = $badge;
314
315 1
        return $this;
316
    }
317
318
    /**
319
     * Get Body
320
     *
321
     * @return string
322
     */
323 10
    public function getBody(): string
324
    {
325 10
        return $this->body;
326
    }
327
328
    /**
329
     * Set Body
330
     *
331
     * @param string $body
332
     *
333
     * @return PushMessageContract
334
     */
335 5
    public function setBody(string $body): PushMessageContract
336
    {
337 5
        $this->body = $body;
338
339 5
        return $this;
340
    }
341
342
    /**
343
     * Get Data
344
     *
345
     * @return mixed
346
     */
347 10
    public function getData()
348
    {
349 10
        return $this->data;
350
    }
351
352
    /**
353
     * Set Data
354
     *
355
     * @param mixed $data
356
     *
357
     * @return PushMessage
358
     */
359 1
    public function setData($data): PushMessage
360
    {
361 1
        $this->data = $data;
362
363 1
        return $this;
364
    }
365
366
    /**
367
     * Get Dir
368
     *
369
     * @return string
370
     */
371 13
    public function getDir(): string
372
    {
373 13
        return $this->dir;
374
    }
375
376
    /**
377
     * Set Dir
378
     *
379
     * @param string $dir
380
     *
381
     * @return PushMessage
382
     */
383 4
    public function setDir(string $dir): PushMessage
384
    {
385 4
        if (!in_array($dir, self::NOTIFICATION_DIRECTIONS, true)) {
386 1
            throw new \InvalidArgumentException('Direction must be one of ' . implode(', ',
387 1
                    self::NOTIFICATION_DIRECTIONS));
388
        }
389
390 3
        $this->dir = $dir;
391
392 3
        return $this;
393
    }
394
395
    /**
396
     * Get IconPath
397
     *
398
     * @return null|string
399
     */
400 10
    public function getIcon(): ?string
401
    {
402 10
        return $this->icon;
403
    }
404
405
    /**
406
     * Set IconPath
407
     *
408
     * @param null|string $icon
409
     *
410
     * @return PushMessageContract
411
     */
412 5
    public function setIcon(?string $icon): PushMessageContract
413
    {
414 5
        $this->icon = $icon;
415
416 5
        return $this;
417
    }
418
419
    /**
420
     * Get Image
421
     *
422
     * @return string|null
423
     */
424 10
    public function getImage(): ?string
425
    {
426 10
        return $this->image;
427
    }
428
429
    /**
430
     * Set Image
431
     *
432
     * @param string|null $image
433
     *
434
     * @return PushMessage
435
     */
436 1
    public function setImage(?string $image): PushMessage
437
    {
438 1
        $this->image = $image;
439
440 1
        return $this;
441
    }
442
443
    /**
444
     * Get Lang
445
     *
446
     * @return null|string
447
     */
448 10
    public function getLang(): ?string
449
    {
450 10
        return $this->lang;
451
    }
452
453
    /**
454
     * Set Lang
455
     *
456
     * @param null|string $lang
457
     *
458
     * @return PushMessageContract
459
     */
460 5
    public function setLang(?string $lang): PushMessageContract
461
    {
462 5
        $this->lang = $lang;
463
464 5
        return $this;
465
    }
466
467
    /**
468
     * Get Renotify
469
     *
470
     * @return mixed
471
     */
472 11
    public function getRenotify()
473
    {
474 11
        return $this->renotify;
475
    }
476
477
    /**
478
     * Set Renotify
479
     *
480
     * @param mixed $renotify
481
     *
482
     * @return PushMessage
483
     */
484 1
    public function setRenotify($renotify): PushMessage
485
    {
486 1
        $this->renotify = $renotify;
487
488 1
        return $this;
489
    }
490
491
    /**
492
     * Get RequireInteraction
493
     *
494
     * @return mixed
495
     */
496 11
    public function getRequireInteraction()
497
    {
498 11
        return $this->require_interaction;
499
    }
500
501
    /**
502
     * Set RequireInteraction
503
     *
504
     * @param mixed $require_interaction
505
     *
506
     * @return PushMessage
507
     */
508 1
    public function setRequireInteraction($require_interaction): PushMessage
509
    {
510 1
        $this->require_interaction = $require_interaction;
511
512 1
        return $this;
513
    }
514
515
    /**
516
     * Get Silent
517
     *
518
     * @return bool
519
     */
520 10
    public function isSilent(): ?bool
521
    {
522 10
        return $this->silent;
523
    }
524
525
    /**
526
     * Set Silent
527
     *
528
     * @param bool $silent
529
     *
530
     * @return PushMessageContract
531
     */
532 3
    public function setSilent(?bool $silent): PushMessageContract
533
    {
534 3
        $this->silent = $silent;
535
536 3
        return $this;
537
    }
538
539
    /**
540
     * Get Tag
541
     *
542
     * @return null|string
543
     */
544 10
    public function getTag(): ?string
545
    {
546 10
        return $this->tag;
547
    }
548
549
    /**
550
     * Set Tag
551
     *
552
     * @param null|string $tag
553
     *
554
     * @return PushMessageContract
555
     */
556 5
    public function setTag(?string $tag): PushMessageContract
557
    {
558 5
        $this->tag = $tag;
559
560 5
        return $this;
561
    }
562
563
    /**
564
     * Get Timestamp
565
     *
566
     * @return int|null
567
     */
568 10
    public function getTimestamp(): ?int
569
    {
570 10
        return $this->timestamp;
571
    }
572
573
    /**
574
     * Set Timestamp
575
     *
576
     * @param int|null $timestamp
577
     *
578
     * @return PushMessageContract
579
     */
580 5
    public function setTimestamp(?int $timestamp): PushMessageContract
581
    {
582 5
        $this->timestamp = $timestamp;
583
584 5
        return $this;
585
    }
586
587
    /**
588
     * Get VibrationPattern
589
     *
590
     * @return array|null
591
     */
592 9
    public function getVibrate(): ?array
593
    {
594 9
        return $this->vibrate;
595
    }
596
597
    /**
598
     * Set VibrationPattern
599
     *
600
     * @param array|null $vibrate
601
     *
602
     * @return PushMessageContract
603
     */
604 7
    public function setVibrate(?array $vibrate): PushMessageContract
605
    {
606 7
        $this->vibrate = $vibrate;
607
608 7
        return $this;
609
    }
610
611
    /**
612
     * @return false|mixed|string
613
     */
614 1
    public function jsonSerialize()
615
    {
616 1
        return $this->toJson();
617
    }
618
619
    /**
620
     * Get Topic
621
     *
622
     * @return string
623
     */
624 1
    public function getTopic(): ?string
625
    {
626 1
        return $this->topic;
627
    }
628
629
    /**
630
     * Set Topic
631
     *
632
     * @param string $topic
633
     *
634
     * @return PushMessage
635
     */
636 5
    public function setTopic(?string $topic): PushMessage
637
    {
638 5
        $this->topic = $topic;
639
640 5
        return $this;
641
    }
642
643
    /**
644
     * Get Urgency
645
     *
646
     * @return string
647
     */
648 1
    public function getUrgency(): ?string
649
    {
650 1
        return $this->urgency;
651
    }
652
653
    /**
654
     * Set Urgency
655
     *
656
     * @param string $urgency
657
     *
658
     * @return PushMessage
659
     */
660 5
    public function setUrgency(?string $urgency): PushMessage
661
    {
662 5
        $this->urgency = $urgency;
663
664 5
        return $this;
665
    }
666
}
667