@@ -28,6 +28,14 @@ class WebPush
28
28
/** @var array Key is push server type and value is the API key */
29
29
protected $ apiKeys ;
30
30
31
+ /** @var array Array of array of Notifications by server type */
32
+ private $ notificationsByServerType ;
33
+
34
+ /** @var array Array of not standard endpoint sources */
35
+ private $ urlByServerType = array (
36
+ 'GCM ' => 'https://android.googleapis.com/gcm/send ' ,
37
+ );
38
+
31
39
/**
32
40
* WebPush constructor.
33
41
*
@@ -48,57 +56,56 @@ public function __construct(array $apiKeys = array(), $TTL = null, $timeout = nu
48
56
}
49
57
50
58
/**
51
- * Send one notification.
59
+ * Send a notification.
52
60
*
53
61
* @param string $endpoint
54
- * @param string|null $payload If you want to send an array, json_encode it.
62
+ * @param string|null $payload If you want to send an array, json_encode it.
55
63
* @param string|null $userPublicKey
64
+ * @param bool $flush If you want to flush directly (usually when you send only one notification)
56
65
*
57
- * @return array
58
- *
66
+ * @return bool|array Return an array of information if $flush is set to true and the request has failed. Else return true.
59
67
* @throws \ErrorException
60
68
*/
61
- public function sendNotification ($ endpoint , $ payload = null , $ userPublicKey = null )
69
+ public function sendNotification ($ endpoint , $ payload = null , $ userPublicKey = null , $ flush = false )
62
70
{
63
- $ endpoints = array ( $ endpoint );
64
- $ payloads = isset ( $ payload ) ? array ( $ payload ) : null ;
65
- $ userPublicKeys = isset ( $ userPublicKey ) ? array ( $ userPublicKey ) : null ;
71
+ // sort notification by server type
72
+ $ type = $ this -> sortEndpoint ( $ endpoint ) ;
73
+ $ this -> notificationsByServerType [ $ type ][] = new Notification ( $ endpoint , $ payload , $ userPublicKey );
66
74
67
- return $ this ->sendNotifications ($ endpoints , $ payloads , $ userPublicKeys );
75
+ if ($ flush ) {
76
+ $ res = $ this ->flush ();
77
+ return is_array ($ res ) ? $ res [0 ] : true ;
78
+ }
79
+
80
+ return true ;
68
81
}
69
82
70
83
/**
71
- * Send multiple notifications.
72
- *
73
- * @param array $endpoints
74
- * @param array|null $payloads
75
- * @param array|null $userPublicKeys
84
+ * Flush notifications. Triggers the requests.
76
85
*
77
- * @return array
86
+ * @return array|bool If there are no errors, return true.
87
+ * Else return an array of information for each notification sent (success, statusCode, headers).
78
88
*
79
89
* @throws \ErrorException
80
90
*/
81
- public function sendNotifications ( array $ endpoints , array $ payloads = null , array $ userPublicKeys = null )
91
+ public function flush ( )
82
92
{
83
- // sort endpoints by server type
84
- $ endpointsByServerType = $ this ->sortEndpoints ($ endpoints );
85
-
86
- // if GCM we should check for the API key
87
- if (array_key_exists ('GCM ' , $ endpointsByServerType )) {
93
+ // if GCM is present, we should check for the API key
94
+ if (array_key_exists ('GCM ' , $ this ->notificationsByServerType )) {
88
95
if (empty ($ this ->apiKeys ['GCM ' ])) {
89
96
throw new \ErrorException ('No GCM API Key specified. ' );
90
97
}
91
98
}
92
99
93
100
// for each endpoint server type
94
101
$ responses = array ();
95
- foreach ($ endpointsByServerType as $ serverType => $ endpoints ) {
102
+ foreach ($ this -> notificationsByServerType as $ serverType => $ notifications ) {
96
103
switch ($ serverType ) {
97
104
case 'GCM ' :
98
- $ responses += $ this ->sendToGCMEndpoints ($ endpoints );
105
+ $ responses += $ this ->sendToGCMEndpoints ($ notifications );
99
106
break ;
100
107
case 'standard ' :
101
- $ responses += $ this ->sendToStandardEndpoints ($ endpoints , $ payloads , $ userPublicKeys );
108
+ $ responses += $ this ->sendToStandardEndpoints ($ notifications );
102
109
break ;
103
110
}
104
111
}
@@ -111,23 +118,31 @@ public function sendNotifications(array $endpoints, array $payloads = null, arra
111
118
}
112
119
113
120
/** @var Response|null $response */
121
+ $ return = array ();
122
+ $ completeSuccess = true ;
114
123
foreach ($ responses as $ response ) {
115
124
if (!isset ($ response )) {
116
- return array (
125
+ $ return[] = array (
117
126
'success ' => false ,
118
127
);
128
+
129
+ $ completeSuccess = false ;
119
130
} elseif (!$ response ->isSuccessful ()) {
120
- return array (
131
+ $ return[] = array (
121
132
'success ' => false ,
122
133
'statusCode ' => $ response ->getStatusCode (),
123
134
'headers ' => $ response ->getHeaders (),
124
135
);
136
+
137
+ $ completeSuccess = false ;
138
+ } else {
139
+ $ return [] = array (
140
+ 'success ' => true ,
141
+ );
125
142
}
126
143
}
127
144
128
- return array (
129
- 'success ' => true ,
130
- );
145
+ return $ completeSuccess ? true : $ return ;
131
146
}
132
147
133
148
/**
@@ -172,23 +187,16 @@ private function encrypt($userPublicKey, $payload)
172
187
);
173
188
}
174
189
175
- /**
176
- * @param array $endpoints
177
- * @param array|null $payloads
178
- * @param array|null $userPublicKeys
179
- *
180
- * @return array
181
- *
182
- * @throws \ErrorException
183
- */
184
- private function sendToStandardEndpoints (array $ endpoints , array $ payloads = null , array $ userPublicKeys = null )
190
+ private function sendToStandardEndpoints (array $ notifications )
185
191
{
186
192
$ responses = array ();
187
- foreach ($ endpoints as $ i => $ endpoint ) {
188
- $ payload = $ payloads [$ i ];
193
+ /** @var Notification $notification */
194
+ foreach ($ notifications as $ notification ) {
195
+ $ payload = $ notification ->getPayload ();
196
+ $ userPublicKey = $ notification ->getUserPublicKey ();
189
197
190
- if (isset ($ payload )) {
191
- $ encrypted = $ this ->encrypt ($ userPublicKeys [ $ i ] , $ payload );
198
+ if (isset ($ payload ) && isset ( $ userPublicKey ) ) {
199
+ $ encrypted = $ this ->encrypt ($ userPublicKey , $ payload );
192
200
193
201
$ headers = array (
194
202
'Content-Length ' => strlen ($ encrypted ['cipherText ' ]),
@@ -211,29 +219,25 @@ private function sendToStandardEndpoints(array $endpoints, array $payloads = nul
211
219
$ headers ['TTL ' ] = $ this ->TTL ;
212
220
}
213
221
214
- $ responses [] = $ this ->sendRequest ($ endpoint , $ headers , $ content );
222
+ $ responses [] = $ this ->sendRequest ($ notification -> getEndpoint () , $ headers , $ content );
215
223
}
216
224
217
225
return $ responses ;
218
226
}
219
227
220
- /**
221
- * @param array $endpoints
222
- *
223
- * @return array
224
- */
225
- private function sendToGCMEndpoints (array $ endpoints )
228
+ private function sendToGCMEndpoints (array $ notifications )
226
229
{
227
230
$ maxBatchSubscriptionIds = 1000 ;
228
- $ url = ' https://android.googleapis.com/gcm/send ' ;
231
+ $ url = $ this -> urlByServerType [ ' GCM ' ] ;
229
232
230
233
$ headers ['Authorization ' ] = 'key= ' .$ this ->apiKeys ['GCM ' ];
231
234
$ headers ['Content-Type ' ] = 'application/json ' ;
232
235
233
236
$ subscriptionIds = array ();
234
- foreach ($ endpoints as $ endpoint ) {
237
+ /** @var Notification $notification */
238
+ foreach ($ notifications as $ notification ) {
235
239
// get all subscriptions ids
236
- $ endpointsSections = explode ('/ ' , $ endpoint );
240
+ $ endpointsSections = explode ('/ ' , $ notification -> getEndpoint () );
237
241
$ subscriptionIds [] = $ endpointsSections [count ($ endpointsSections ) - 1 ];
238
242
}
239
243
@@ -273,35 +277,19 @@ private function sendRequest($url, array $headers, $content)
273
277
}
274
278
275
279
/**
276
- * @param array $endpoints
280
+ * @param string $endpoint
277
281
*
278
- * @return array
282
+ * @return string
279
283
*/
280
- private function sortEndpoints ( array $ endpoints )
284
+ private function sortEndpoint ( $ endpoint )
281
285
{
282
- $ sortedEndpoints = array ();
283
-
284
- $ serverTypesByUrl = array (
285
- 'GCM ' => 'https://android.googleapis.com/gcm/send ' ,
286
- );
287
-
288
- foreach ($ endpoints as $ endpoint ) {
289
- $ standard = true ;
290
-
291
- foreach ($ serverTypesByUrl as $ type => $ url ) {
292
- if (substr ($ endpoint , 0 , strlen ($ url )) === $ url ) {
293
- $ sortedEndpoints [$ type ][] = $ endpoint ;
294
- $ standard = false ;
295
- break ;
296
- }
297
- }
298
-
299
- if ($ standard ) {
300
- $ sortedEndpoints ['standard ' ][] = $ endpoint ;
286
+ foreach ($ this ->urlByServerType as $ type => $ url ) {
287
+ if (substr ($ endpoint , 0 , strlen ($ url )) === $ url ) {
288
+ return $ type ;
301
289
}
302
290
}
303
291
304
- return $ sortedEndpoints ;
292
+ return ' standard ' ;
305
293
}
306
294
307
295
/**
0 commit comments