Passed
Branch master (c73d10)
by Stefan
02:51 queued 55s
created

PNPayload::setVibration()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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