1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
namespace SKien\PNServer; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Class representing payload for push notification. |
8
|
|
|
* |
9
|
|
|
* the class provides functions to define the properties of a push |
10
|
|
|
* notification. As result, a JSON string is generated to push to the client. |
11
|
|
|
* |
12
|
|
|
* Most properties directly map the showNotification() options and are |
13
|
|
|
* passed on directly within the service worker. |
14
|
|
|
* |
15
|
|
|
* @package PNServer |
16
|
|
|
* @author Stefanius <[email protected]> |
17
|
|
|
* @copyright MIT License - see the LICENSE file for details |
18
|
|
|
*/ |
19
|
|
|
class PNPayload |
20
|
|
|
{ |
21
|
|
|
use PNServerHelper; |
22
|
|
|
|
23
|
|
|
/** @var array<mixed> */ |
24
|
|
|
protected array $aPayload; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Create instance of payload with title, text and icon to display. |
28
|
|
|
* - title should be short and meaningfull. |
29
|
|
|
* - The text should not increase 200 characters - the different browsers and |
30
|
|
|
* platforms limit the display differently (partly according to the number of |
31
|
|
|
* lines, others according to the number of characters) |
32
|
|
|
* - icon should be square (if not, some browsers/platforms cut a square). There |
33
|
|
|
* is no exact specification for the 'optimal' size, 64dp (px * device pixel ratio) |
34
|
|
|
* should be a good decision (... 192px for highest device pixel ratio) |
35
|
|
|
* |
36
|
|
|
* @param string $strTitle Title to display |
37
|
|
|
* @param string $strText A string representing an extra content to display within the notification. |
38
|
|
|
* @param string $strIcon containing the URL of an image to be used as an icon by the notification. |
39
|
|
|
*/ |
40
|
|
|
public function __construct(string $strTitle, ?string $strText = null, ?string $strIcon = null) |
41
|
|
|
{ |
42
|
|
|
$this->aPayload = array( |
43
|
|
|
'title' => $strTitle, |
44
|
|
|
'opt' => array( |
45
|
|
|
'body' => $strText, |
46
|
|
|
'icon' => $strIcon, |
47
|
|
|
), |
48
|
|
|
); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Note: the URL is no part of the JS showNotification() - Options! |
53
|
|
|
* @param string $strURL URL to open when user click on the notification. |
54
|
|
|
*/ |
55
|
|
|
public function setURL(string $strURL) : void |
56
|
|
|
{ |
57
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
58
|
|
|
if (!isset($this->aPayload['opt']['data']) || !is_array($this->aPayload['opt']['data'])) { |
59
|
|
|
$this->aPayload['opt']['data'] = array(); |
60
|
|
|
} |
61
|
|
|
$this->aPayload['opt']['data']['url'] = $strURL; |
62
|
|
|
} |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* An ID for a given notification that allows you to find, replace, or remove the notification using |
67
|
|
|
* a script if necessary. |
68
|
|
|
* If set, multiple notifications with the same tag will only reappear if $bReNotify is set to true. |
69
|
|
|
* Usualy the last notification with same tag is displayed in this case. |
70
|
|
|
* |
71
|
|
|
* @param string $strTag |
72
|
|
|
* @param bool $bReNotify |
73
|
|
|
*/ |
74
|
|
|
public function setTag(string $strTag, bool $bReNotify = false) : void |
75
|
|
|
{ |
76
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
77
|
|
|
$this->aPayload['opt']['tag'] = $strTag; |
78
|
|
|
$this->aPayload['opt']['renotify'] = $bReNotify; |
79
|
|
|
} |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* containing the URL of an larger image to be displayed in the notification. |
84
|
|
|
* Size, position and cropping vary with the different browsers and platforms |
85
|
|
|
* @param string $strImage |
86
|
|
|
*/ |
87
|
|
|
public function setImage(string $strImage) : void |
88
|
|
|
{ |
89
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
90
|
|
|
$this->aPayload['opt']['image'] = $strImage; |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* containing the URL of an badge assigend to the notification. |
96
|
|
|
* The badge is a small monochrome icon that is used to portray a little |
97
|
|
|
* more information to the user about where the notification is from. |
98
|
|
|
* So far I have only found Chrome for Android that supports the badge... |
99
|
|
|
* ... in most cases the browsers icon is displayed. |
100
|
|
|
* |
101
|
|
|
* @param string $strBadge |
102
|
|
|
*/ |
103
|
|
|
public function setBadge(string $strBadge) : void |
104
|
|
|
{ |
105
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
106
|
|
|
$this->aPayload['opt']['badge'] = $strBadge; |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Add action to display in the notification. |
112
|
|
|
* |
113
|
|
|
* The count of action that can be displayed vary between browser/platform. On |
114
|
|
|
* the client it can be detected with javascript: Notification.maxActions |
115
|
|
|
* |
116
|
|
|
* Appropriate responses have to be implemented within the notificationclick event. |
117
|
|
|
* the event.action property contains the $strAction clicked on |
118
|
|
|
* |
119
|
|
|
* @param string $strAction identifying a user action to be displayed on the notification. |
120
|
|
|
* @param string $strTitle containing action text to be shown to the user. |
121
|
|
|
* @param string $strIcon containing the URL of an icon to display with the action. |
122
|
|
|
* @param string $strCustom custom info - not part of the showNotification()- Options! |
123
|
|
|
*/ |
124
|
|
|
public function addAction(string $strAction, string $strTitle, ?string $strIcon = null, string $strCustom = '') : void |
125
|
|
|
{ |
126
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
127
|
|
|
if (!isset($this->aPayload['opt']['actions']) || !is_array($this->aPayload['opt']['actions'])) { |
128
|
|
|
$this->aPayload['opt']['actions'] = array(); |
129
|
|
|
} |
130
|
|
|
$this->aPayload['opt']['actions'][] = array('action' => $strAction, 'title' => $strTitle, 'icon' => $strIcon, 'custom' => $strCustom); |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Set the time when the notification was created. |
136
|
|
|
* It can be used to indicate the time at which a notification is actual. For example, this could |
137
|
|
|
* be in the past when a notification is used for a message that couldn’t immediately be delivered |
138
|
|
|
* because the device was offline, or in the future for a meeting that is about to start. |
139
|
|
|
* |
140
|
|
|
* @param mixed $timestamp DateTime object, UNIX timestamp or English textual datetime description |
141
|
|
|
*/ |
142
|
|
|
public function setTimestamp($timestamp) : void |
143
|
|
|
{ |
144
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
145
|
|
|
$iTimestamp = $timestamp; |
146
|
|
|
if (self::className($timestamp) == 'DateTime') { |
147
|
|
|
// DateTime -object |
148
|
|
|
$iTimestamp = $timestamp->getTimestamp(); |
149
|
|
|
} else if (is_string($timestamp)) { |
150
|
|
|
// string |
151
|
|
|
$iTimestamp = strtotime($timestamp); |
152
|
|
|
} |
153
|
|
|
// timestamp in milliseconds! |
154
|
|
|
$this->aPayload['opt']['timestamp'] = bcmul((string) $iTimestamp, '1000'); |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Indicates that on devices with sufficiently large screens, a notification should remain active until |
160
|
|
|
* the user clicks or dismisses it. If this value is absent or false, the desktop version of Chrome |
161
|
|
|
* will auto-minimize notifications after approximately twenty seconds. Implementation depends on |
162
|
|
|
* browser and plattform. |
163
|
|
|
* |
164
|
|
|
* @param bool $bSet |
165
|
|
|
*/ |
166
|
|
|
public function requireInteraction(bool $bSet = true) : void |
167
|
|
|
{ |
168
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
169
|
|
|
$this->aPayload['opt']['requireInteraction'] = $bSet; |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Indicates that no sounds or vibrations should be made. |
175
|
|
|
* If this 'mute' function is activated, a previously set vibration is reset to prevent a TypeError exception. |
176
|
|
|
* @param bool $bSet |
177
|
|
|
*/ |
178
|
|
|
public function setSilent(bool $bSet = true) : void |
179
|
|
|
{ |
180
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
181
|
|
|
$this->aPayload['opt']['silent'] = $bSet; |
182
|
|
|
if ($bSet && isset($this->aPayload['opt']['vibrate'])) { |
183
|
|
|
// silent=true and defined vibation causes TypeError |
184
|
|
|
unset($this->aPayload['opt']['vibrate']); |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* A vibration pattern to run with the display of the notification. |
191
|
|
|
* A vibration pattern can be an array with as few as one member. The values are times in milliseconds |
192
|
|
|
* where the even indices (0, 2, 4, etc.) indicate how long to vibrate and the odd indices indicate |
193
|
|
|
* how long to pause. For example, [300, 100, 400] would vibrate 300ms, pause 100ms, then vibrate 400ms. |
194
|
|
|
* |
195
|
|
|
* @param array<int> $aPattern |
196
|
|
|
*/ |
197
|
|
|
public function setVibration(array $aPattern) : void |
198
|
|
|
{ |
199
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
200
|
|
|
$this->aPayload['opt']['vibrate'] = $aPattern; |
201
|
|
|
if (isset($this->aPayload['opt']['silent'])) { |
202
|
|
|
// silent=true and vibation pattern causes TypeError |
203
|
|
|
$this->aPayload['opt']['silent'] = false; |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* containing the URL of an sound - file (mp3 or wav). |
210
|
|
|
* currently not found any browser supports sounds |
211
|
|
|
* @param string $strSound |
212
|
|
|
*/ |
213
|
|
|
public function setSound(string $strSound) : void |
214
|
|
|
{ |
215
|
|
|
if (is_array($this->aPayload) && isset($this->aPayload['opt']) && is_array($this->aPayload['opt'])) { |
216
|
|
|
$this->aPayload['opt']['sound'] = $strSound; |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Get the Payload data as array |
222
|
|
|
* @return array<mixed> |
223
|
|
|
*/ |
224
|
|
|
public function getPayload() : array |
225
|
|
|
{ |
226
|
|
|
return $this->aPayload; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Convert payload dasta to JSON string. |
231
|
|
|
* @return string JSON string representing payloal |
232
|
|
|
*/ |
233
|
|
|
public function toJSON() : string |
234
|
|
|
{ |
235
|
|
|
$strJson = json_encode($this->aPayload); |
236
|
|
|
return utf8_encode($strJson !== false ? $strJson : ''); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* @return string JSON string representing payloal |
241
|
|
|
*/ |
242
|
|
|
public function __toString() : string |
243
|
|
|
{ |
244
|
|
|
return $this->toJSON(); |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
} |
248
|
|
|
|