Skip to content

Commit fd0c9ae

Browse files
committed
new API with flush
1 parent 99e0297 commit fd0c9ae

File tree

3 files changed

+113
-73
lines changed

3 files changed

+113
-73
lines changed

src/Notification.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the WebPush library.
5+
*
6+
* (c) Louis Lagrange <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Minishlink\WebPush;
13+
14+
class Notification
15+
{
16+
/** @var string */
17+
private $endpoint;
18+
19+
/** @var string|null */
20+
private $payload;
21+
22+
/** @var string|null Base64 encoded */
23+
private $userPublicKey;
24+
25+
public function __construct($endpoint, $payload, $userPublicKey)
26+
{
27+
$this->endpoint = $endpoint;
28+
$this->payload = $payload;
29+
$this->userPublicKey = $payload;
30+
}
31+
32+
/**
33+
* @return string
34+
*/
35+
public function getEndpoint()
36+
{
37+
return $this->endpoint;
38+
}
39+
}

src/WebPush.php

Lines changed: 61 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ class WebPush
2525
/** @var array Key is push server type and value is the API key */
2626
protected $apiKeys;
2727

28+
/** @var array Array of array of Notifications by server type */
29+
private $notificationsByServerType;
30+
31+
/** @var array Array of not standard endpoint sources */
32+
private $urlByServerType = array(
33+
'GCM' => 'https://android.googleapis.com/gcm/send',
34+
);
35+
2836
/**
2937
* WebPush constructor.
3038
*
@@ -45,57 +53,56 @@ public function __construct(array $apiKeys = array(), $TTL = null, $timeout = nu
4553
}
4654

4755
/**
48-
* Send one notification.
56+
* Send a notification.
4957
*
5058
* @param string $endpoint
51-
* @param string|null $payload If you want to send an array, json_encode it.
59+
* @param string|null $payload If you want to send an array, json_encode it.
5260
* @param string|null $userPublicKey
61+
* @param bool $flush If you want to flush directly (usually when you send only one notification)
5362
*
54-
* @return array
55-
*
63+
* @return bool|array Return an array of information if $flush is set to true and the request has failed. Else return true.
5664
* @throws \ErrorException
5765
*/
58-
public function sendNotification($endpoint, $payload = null, $userPublicKey = null)
66+
public function sendNotification($endpoint, $payload = null, $userPublicKey = null, $flush = false)
5967
{
60-
$endpoints = array($endpoint);
61-
$payloads = isset($payload) ? array($payload) : null;
62-
$userPublicKeys = isset($userPublicKey) ? array($userPublicKey) : null;
68+
// sort notification by server type
69+
$type = $this->sortEndpoint($endpoint);
70+
$this->notificationsByServerType[$type][] = new Notification($endpoint, $payload, $userPublicKey);
6371

64-
return $this->sendNotifications($endpoints, $payloads, $userPublicKeys);
72+
if ($flush) {
73+
$res = $this->flush();
74+
return is_array($res) ? $res[0] : true;
75+
}
76+
77+
return true;
6578
}
6679

6780
/**
68-
* Send multiple notifications.
69-
*
70-
* @param array $endpoints
71-
* @param array|null $payloads
72-
* @param array|null $userPublicKeys
81+
* Flush notifications. Triggers the requests.
7382
*
74-
* @return array
83+
* @return array|bool If there are no errors, return true.
84+
* Else return an array of information for each notification sent (success, statusCode, headers).
7585
*
7686
* @throws \ErrorException
7787
*/
78-
public function sendNotifications(array $endpoints, array $payloads = null, array $userPublicKeys = null)
88+
public function flush()
7989
{
80-
// sort endpoints by server type
81-
$endpointsByServerType = $this->sortEndpoints($endpoints);
82-
83-
// if GCM we should check for the API key
84-
if (array_key_exists('GCM', $endpointsByServerType)) {
90+
// if GCM is present, we should check for the API key
91+
if (array_key_exists('GCM', $this->notificationsByServerType)) {
8592
if (empty($this->apiKeys['GCM'])) {
8693
throw new \ErrorException('No GCM API Key specified.');
8794
}
8895
}
8996

9097
// for each endpoint server type
9198
$responses = array();
92-
foreach ($endpointsByServerType as $serverType => $endpoints) {
99+
foreach ($this->notificationsByServerType as $serverType => $notifications) {
93100
switch ($serverType) {
94101
case 'GCM':
95-
$responses += $this->sendToGCMEndpoints($endpoints);
102+
$responses += $this->sendToGCMEndpoints($notifications);
96103
break;
97104
case 'standard':
98-
$responses += $this->sendToStandardEndpoints($endpoints, $payloads, $userPublicKeys);
105+
$responses += $this->sendToStandardEndpoints($notifications);
99106
break;
100107
}
101108
}
@@ -108,25 +115,34 @@ public function sendNotifications(array $endpoints, array $payloads = null, arra
108115
}
109116

110117
/** @var Response|null $response */
118+
$return = array();
119+
$completeSuccess = true;
111120
foreach ($responses as $response) {
112121
if (!isset($response)) {
113-
return array(
122+
$return[] = array(
114123
'success' => false,
115124
);
125+
126+
$completeSuccess = false;
116127
} elseif (!$response->isSuccessful()) {
117-
return array(
128+
$return[] = array(
118129
'success' => false,
119130
'statusCode' => $response->getStatusCode(),
120131
'headers' => $response->getHeaders(),
121132
);
133+
134+
$completeSuccess = false;
135+
} else {
136+
$return[] = array(
137+
'success' => true,
138+
);
122139
}
123140
}
124141

125-
return array(
126-
'success' => true,
127-
);
142+
return $completeSuccess ? true : $return;
128143
}
129-
private function sendToStandardEndpoints(array $endpoints, array $payloads = null, array $userPublicKeys = null)
144+
145+
private function sendToStandardEndpoints(array $notifications)
130146
{
131147
$headers = array(
132148
'Content-Length' => 0,
@@ -139,30 +155,27 @@ private function sendToStandardEndpoints(array $endpoints, array $payloads = nul
139155
}
140156

141157
$responses = array();
142-
foreach ($endpoints as $i => $endpoint) {
143-
$responses[] = $this->sendRequest($endpoint, $headers, $content);
158+
/** @var Notification $notification */
159+
foreach ($notifications as $notification) {
160+
$responses[] = $this->sendRequest($notification->getEndpoint(), $headers, $content);
144161
}
145162

146163
return $responses;
147164
}
148165

149-
/**
150-
* @param array $endpoints
151-
*
152-
* @return array
153-
*/
154-
private function sendToGCMEndpoints(array $endpoints)
166+
private function sendToGCMEndpoints(array $notifications)
155167
{
156168
$maxBatchSubscriptionIds = 1000;
157-
$url = 'https://android.googleapis.com/gcm/send';
169+
$url = $this->urlByServerType['GCM'];
158170

159171
$headers['Authorization'] = 'key='.$this->apiKeys['GCM'];
160172
$headers['Content-Type'] = 'application/json';
161173

162174
$subscriptionIds = array();
163-
foreach ($endpoints as $endpoint) {
175+
/** @var Notification $notification */
176+
foreach ($notifications as $notification) {
164177
// get all subscriptions ids
165-
$endpointsSections = explode('/', $endpoint);
178+
$endpointsSections = explode('/', $notification->getEndpoint());
166179
$subscriptionIds[] = $endpointsSections[count($endpointsSections) - 1];
167180
}
168181

@@ -202,35 +215,19 @@ private function sendRequest($url, array $headers, $content)
202215
}
203216

204217
/**
205-
* @param array $endpoints
218+
* @param string $endpoint
206219
*
207-
* @return array
220+
* @return string
208221
*/
209-
private function sortEndpoints(array $endpoints)
222+
private function sortEndpoint($endpoint)
210223
{
211-
$sortedEndpoints = array();
212-
213-
$serverTypesByUrl = array(
214-
'GCM' => 'https://android.googleapis.com/gcm/send',
215-
);
216-
217-
foreach ($endpoints as $endpoint) {
218-
$standard = true;
219-
220-
foreach ($serverTypesByUrl as $type => $url) {
221-
if (substr($endpoint, 0, strlen($url)) === $url) {
222-
$sortedEndpoints[$type][] = $endpoint;
223-
$standard = false;
224-
break;
225-
}
226-
}
227-
228-
if ($standard) {
229-
$sortedEndpoints['standard'][] = $endpoint;
224+
foreach ($this->urlByServerType as $type => $url) {
225+
if (substr($endpoint, 0, strlen($url)) === $url) {
226+
return $type;
230227
}
231228
}
232229

233-
return $sortedEndpoints;
230+
return 'standard';
234231
}
235232

236233
/**

tests/WebPushTest.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,33 +36,37 @@ public function setUp()
3636

3737
public function testSendNotification()
3838
{
39-
$res = $this->webPush->sendNotification($this->endpoints['standard']);
39+
$res = $this->webPush->sendNotification($this->endpoints['standard'], null, null, true);
4040

41-
$this->assertArrayHasKey('success', $res);
42-
$this->assertEquals(true, $res['success']);
41+
$this->assertTrue($res);
4342
}
4443

45-
public function testSendGCMNotification()
44+
public function testSendNotifications()
4645
{
47-
$res = $this->webPush->sendNotification($this->endpoints['GCM']);
46+
foreach($this->endpoints as $endpoint) {
47+
$this->webPush->sendNotification($endpoint);
48+
}
4849

49-
$this->assertArrayHasKey('success', $res);
50-
$this->assertEquals(true, $res['success']);
50+
$res = $this->webPush->flush();
51+
52+
$this->assertTrue($res);
5153
}
5254

5355
public function testSendGCMNotificationWithoutGCMApiKey()
5456
{
5557
$webPush = new WebPush();
5658

5759
$this->setExpectedException('ErrorException', 'No GCM API Key specified.');
58-
$webPush->sendNotification($this->endpoints['GCM']);
60+
$webPush->sendNotification($this->endpoints['GCM'], null, null, true);
5961
}
6062

6163
public function testSendGCMNotificationWithWrongGCMApiKey()
6264
{
6365
$webPush = new WebPush(array('GCM' => 'bar'));
6466

65-
$res = $webPush->sendNotification($this->endpoints['GCM']);
67+
$res = $webPush->sendNotification($this->endpoints['GCM'], null, null, true);
68+
69+
$this->assertTrue(is_array($res)); // there has been an error
6670
$this->assertArrayHasKey('success', $res);
6771
$this->assertEquals(false, $res['success']);
6872

0 commit comments

Comments
 (0)