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
introduced
by
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 |