1
|
|
|
<?php |
|
|
|
|
2
|
|
|
App::uses('Component', 'Controller'); |
3
|
|
|
App::uses('HttpSocket', 'Network/Http'); |
4
|
|
|
App::uses('Hash', 'Utility'); |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Gcm Exception classes |
8
|
|
|
*/ |
9
|
|
|
class GcmException extends CakeException { |
|
|
|
|
10
|
|
|
} |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Gcm Component |
14
|
|
|
* |
15
|
|
|
*/ |
16
|
|
|
class GcmComponent extends Component { |
|
|
|
|
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Default options |
20
|
|
|
* |
21
|
|
|
* @var array |
22
|
|
|
*/ |
23
|
|
|
protected $_defaults = array( |
24
|
|
|
'api' => array( |
25
|
|
|
'key' => '', |
26
|
|
|
'url' => 'https://gcm-http.googleapis.com/gcm/send' |
27
|
|
|
), |
28
|
|
|
'parameters' => array( |
29
|
|
|
'collapse_key' => null, |
30
|
|
|
'priority' => 'normal', |
31
|
|
|
'delay_while_idle' => false, |
32
|
|
|
'dry_run' => false, |
33
|
|
|
'time_to_live' => 2419200, |
34
|
|
|
'restricted_package_name' => null |
35
|
|
|
) |
36
|
|
|
); |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Error code and message. |
40
|
|
|
* |
41
|
|
|
* @var array |
42
|
|
|
*/ |
43
|
|
|
protected $_errorMessages = array(); |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Response of the request |
47
|
|
|
* |
48
|
|
|
* @var object |
49
|
|
|
*/ |
50
|
|
|
protected $_response = null; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Controller reference |
54
|
|
|
*/ |
55
|
|
|
protected $Controller = null; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* A Component collection, used to get more components. |
59
|
|
|
* |
60
|
|
|
* @var ComponentCollection |
61
|
|
|
*/ |
62
|
|
|
protected $Collection; |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Constructor |
66
|
|
|
* |
67
|
|
|
* @param ComponentCollection $collection |
68
|
|
|
* @param array $settings |
69
|
|
|
*/ |
70
|
|
|
public function __construct(ComponentCollection $collection, $settings = array()) { |
71
|
|
|
$this->Collection = $collection; |
72
|
|
|
$this->_defaults = Hash::merge($this->_defaults, $settings); |
73
|
|
|
|
74
|
|
|
$this->_errorMessages = array( |
75
|
|
|
'400' => __('Error 400. The request could not be parsed as JSON or contained invalid fields.'), |
76
|
|
|
'401' => __('Error 401. Unable to authenticating the sender account.'), |
77
|
|
|
'500' => __('Error 500. Internal Server Error.'), |
78
|
|
|
'503' => __('Error 503. Service Unavailable.') |
79
|
|
|
); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Called before the Controller::beforeFilter(). |
84
|
|
|
* |
85
|
|
|
* @param Controller $controller Controller with components to initialize |
86
|
|
|
* @return void |
87
|
|
|
*/ |
88
|
|
|
public function initialize(Controller $controller) { |
89
|
|
|
$this->Controller = $controller; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* send method |
94
|
|
|
* |
95
|
|
|
* @param string|array $ids |
96
|
|
|
* @param array $payload |
97
|
|
|
* @param array $parameters |
98
|
|
|
* @return boolean |
99
|
|
|
*/ |
100
|
|
|
public function send($ids = false, $payload = array(), $parameters = array()) { |
101
|
|
|
|
102
|
|
|
if (is_string($ids)) { |
103
|
|
|
$ids = (array)$ids; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
if ($ids === false || !is_array($ids) || empty($ids)) { |
107
|
|
|
throw new GcmException(__("Ids must be a string or an array.")); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
if (!is_array($payload)) { |
111
|
|
|
throw new GcmException(__("Payload must be an array.")); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
if (!is_array($parameters)) { |
115
|
|
|
throw new GcmException(__("Parameters must be an array.")); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
if (isset($payload['notification'])) { |
|
|
|
|
119
|
|
|
$payload['notification'] = $this->_checkNotification($payload['notification']); |
120
|
|
|
if (!$payload['notification']) { |
121
|
|
|
throw new GcmException(__("Unable to check notification.")); |
122
|
|
|
} |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
if (isset($payload['data'])) { |
|
|
|
|
126
|
|
|
$payload['data'] = $this->_checkData($payload['data']); |
127
|
|
|
if (!$payload['data']) { |
128
|
|
|
throw new GcmException(__("Unable to check data.")); |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
$parameters = $this->_checkParameters($parameters); |
133
|
|
|
if (!$parameters) { |
134
|
|
|
throw new GcmException(__("Unable to check parameters.")); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
$notification = $this->_buildMessage($ids, $payload, $parameters); |
138
|
|
|
if ($notification === false) { |
139
|
|
|
throw new GcmException(__("Unable to build the message.")); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
return $this->_executePush($notification); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* sendNotification method |
147
|
|
|
* |
148
|
|
|
* @param string|array $ids |
149
|
|
|
* @param array $notification |
150
|
|
|
* @param array $parameters |
151
|
|
|
* @return boolean |
152
|
|
|
*/ |
153
|
|
|
public function sendNotification($ids = false, $notification = array(), $parameters = array()) { |
154
|
|
|
return $this->send($ids, array('notification' => $notification), $parameters); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* sendData method |
159
|
|
|
* |
160
|
|
|
* @param string|array $ids |
161
|
|
|
* @param array $data |
162
|
|
|
* @param array $parameters |
163
|
|
|
* @return boolean |
164
|
|
|
*/ |
165
|
|
|
public function sendData($ids = false, $data = array(), $parameters = array()) { |
166
|
|
|
return $this->send($ids, array('data' => $data), $parameters); |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* response method |
171
|
|
|
* |
172
|
|
|
* @return string |
173
|
|
|
*/ |
174
|
|
|
public function response() { |
175
|
|
|
if (array_key_exists($this->_response->code, $this->_errorMessages)) { |
176
|
|
|
return $this->_errorMessages[$this->_response->code]; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
return json_decode($this->_response->body, true); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* _executePush method |
184
|
|
|
* |
185
|
|
|
* @param json $notification |
186
|
|
|
* @return bool |
187
|
|
|
*/ |
188
|
|
|
protected function _executePush($notification = false) { |
189
|
|
|
if ($notification === false) { |
190
|
|
|
return false; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
if ($this->_defaults['api']['key'] === null) { |
194
|
|
|
throw new GcmException(__("No API key set. Push not triggered")); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
$httpSocket = new HttpSocket(); |
198
|
|
|
$this->_response = $httpSocket->post($this->_defaults['api']['url'], $notification, array( |
199
|
|
|
'header' => array( |
200
|
|
|
'Authorization' => 'key=' . $this->_defaults['api']['key'], |
201
|
|
|
'Content-Type' => 'application/json' |
202
|
|
|
) |
203
|
|
|
)); |
204
|
|
|
|
205
|
|
|
if ($this->_response->code === '200') { |
206
|
|
|
return true; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
return false; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* _buildMessage method |
214
|
|
|
* |
215
|
|
|
* @param array $ids |
216
|
|
|
* @param array $payload |
217
|
|
|
* @param array $parameters |
218
|
|
|
* @return false|string |
219
|
|
|
*/ |
220
|
|
|
protected function _buildMessage($ids = false, $payload = false, $parameters = false) { |
221
|
|
|
if ($ids === false) { |
222
|
|
|
return false; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
$message = array('registration_ids' => $ids); |
226
|
|
|
|
227
|
|
|
if (!empty($payload)) { |
228
|
|
|
$message += $payload; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
if (!empty($parameters)) { |
232
|
|
|
$message += $parameters; |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
return json_encode($message); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* _checkNotification method |
240
|
|
|
* |
241
|
|
|
* @param array $notification |
242
|
|
|
* @return array $notification |
243
|
|
|
*/ |
244
|
|
|
protected function _checkNotification($notification = false) { |
245
|
|
|
if ($notification === false) { |
246
|
|
|
return false; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
if (!is_array($notification)) { |
250
|
|
|
throw new GcmException("Notification must be an array."); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
if (empty($notification) || !isset($notification['title'])) { |
254
|
|
|
throw new GcmException("Notification's array must contain at least a key title."); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
if (!isset($notification['icon'])) { |
258
|
|
|
$notification['icon'] = 'myicon'; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
return $notification; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* _checkData method |
266
|
|
|
* |
267
|
|
|
* @param array $data |
268
|
|
|
* @return array $data |
269
|
|
|
*/ |
270
|
|
|
public function _checkData($data = false) { |
271
|
|
|
if ($data === false) { |
272
|
|
|
return false; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
if (!is_array($data)) { |
276
|
|
|
throw new GcmException("Data must ba an array."); |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
if (empty($data)) { |
280
|
|
|
throw new GcmException("Data's array can't be empty."); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
// Convert all data into string |
284
|
|
|
foreach ($data as $key => $value) { |
285
|
|
|
$data[$key] = strval($value); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
return $data; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
/** |
292
|
|
|
* _checkParameters method |
293
|
|
|
* |
294
|
|
|
* @param array $parameters |
295
|
|
|
* @return array $parameters |
296
|
|
|
*/ |
297
|
|
|
protected function _checkParameters($parameters = false) { |
298
|
|
|
if ($parameters === false) { |
299
|
|
|
return false; |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
$parameters = Hash::merge($this->_defaults['parameters'], $parameters); |
303
|
|
|
$parameters = array_filter($parameters); |
304
|
|
|
|
305
|
|
|
if (isset($parameters['time_to_live']) && !is_int($parameters['time_to_live'])) { |
306
|
|
|
$parameters['time_to_live'] = (int)$parameters['time_to_live']; |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
if (isset($parameters['delay_while_idle']) && !is_bool($parameters['delay_while_idle'])) { |
310
|
|
|
$parameters['delay_while_idle'] = (bool)$parameters['delay_while_idle']; |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
if (isset($parameters['dry_run']) && !is_bool($parameters['dry_run'])) { |
314
|
|
|
$parameters['dry_run'] = (bool)$parameters['dry_run']; |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
return $parameters; |
318
|
|
|
} |
319
|
|
|
} |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.