1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace ElfSundae\Laravel\Support\Services\XgPush; |
4
|
|
|
|
5
|
|
|
use ElfSundae\XgPush\Style; |
6
|
|
|
use ElfSundae\XgPush\Message; |
7
|
|
|
use ElfSundae\XgPush\XingeApp; |
8
|
|
|
use ElfSundae\XgPush\MessageIOS; |
9
|
|
|
use ElfSundae\XgPush\ClickAction; |
10
|
|
|
use ElfSundae\XgPush\TagTokenPair; |
11
|
|
|
|
12
|
|
|
class XgPusher |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* The XingeApp instance. |
16
|
|
|
* |
17
|
|
|
* @var \ElfSundae\XgPush\XingeApp |
18
|
|
|
*/ |
19
|
|
|
protected $xinge; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* The pusher environment. |
23
|
|
|
* |
24
|
|
|
* 向iOS设备推送时必填,1表示推送生产环境;2表示推送开发环境。推送Android平台不填或填0. |
25
|
|
|
* |
26
|
|
|
* @var int |
27
|
|
|
*/ |
28
|
|
|
protected $environment = XingeApp::IOSENV_DEV; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* The key of custom payload. |
32
|
|
|
* |
33
|
|
|
* @var string |
34
|
|
|
*/ |
35
|
|
|
protected $customKey; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Xinge account prefix. |
39
|
|
|
* |
40
|
|
|
* @warning 信鸽不允许使用简单的账号,例如纯数字的id。 |
41
|
|
|
* |
42
|
|
|
* @var string |
43
|
|
|
*/ |
44
|
|
|
protected $accountPrefix; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Create a new instance. |
48
|
|
|
* |
49
|
|
|
* @param string $appKey |
50
|
|
|
* @param string $appSecret |
51
|
|
|
*/ |
52
|
|
|
public function __construct($appKey, $appSecret) |
53
|
|
|
{ |
54
|
|
|
$this->xinge = new XingeApp($appKey, $appSecret); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Get the XingeApp instance. |
59
|
|
|
* |
60
|
|
|
* @return \ElfSundae\XgPush\XingeApp |
61
|
|
|
*/ |
62
|
|
|
public function xinge() |
63
|
|
|
{ |
64
|
|
|
return $this->xinge; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Get the app key. |
69
|
|
|
* |
70
|
|
|
* @return string |
71
|
|
|
*/ |
72
|
|
|
public function getAppKey() |
73
|
|
|
{ |
74
|
|
|
return $this->xinge->accessId; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Get the app secret. |
79
|
|
|
* |
80
|
|
|
* @return string |
81
|
|
|
*/ |
82
|
|
|
public function getAppSecret() |
83
|
|
|
{ |
84
|
|
|
return $this->xinge->secretKey; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Get the pusher environment. |
89
|
|
|
* |
90
|
|
|
* @return int |
91
|
|
|
*/ |
92
|
|
|
public function getEnvironment() |
93
|
|
|
{ |
94
|
|
|
return $this->environment; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Set the pusher environment. |
99
|
|
|
* |
100
|
|
|
* @param mixed $env |
101
|
|
|
* @return $this |
102
|
|
|
*/ |
103
|
|
|
public function setEnvironment($env) |
104
|
|
|
{ |
105
|
|
|
if (is_string($env)) { |
106
|
|
|
$env = $env == 'production' ? XingeApp::IOSENV_PROD : XingeApp::IOSENV_DEV; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
if (is_int($env)) { |
110
|
|
|
$this->environment = $env; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
return $this; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Get the key of custom payload. |
118
|
|
|
* |
119
|
|
|
* @return string|null |
120
|
|
|
*/ |
121
|
|
|
public function getCustomKey() |
122
|
|
|
{ |
123
|
|
|
return $this->customKey; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Set the key of custom payload. |
128
|
|
|
* |
129
|
|
|
* @param string|null $key |
130
|
|
|
* @return $this |
131
|
|
|
*/ |
132
|
|
|
public function setCustomKey($key) |
133
|
|
|
{ |
134
|
|
|
$this->customKey = $key; |
135
|
|
|
|
136
|
|
|
return $this; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Get the account prefix. |
141
|
|
|
* |
142
|
|
|
* @return string |
143
|
|
|
*/ |
144
|
|
|
public function getAccountPrefix() |
145
|
|
|
{ |
146
|
|
|
return $this->accountPrefix; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Set the account prefix. |
151
|
|
|
* |
152
|
|
|
* @param string $prefix |
153
|
|
|
* @return $this |
154
|
|
|
*/ |
155
|
|
|
public function setAccountPrefix($prefix) |
156
|
|
|
{ |
157
|
|
|
$this->accountPrefix = $prefix; |
158
|
|
|
|
159
|
|
|
return $this; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Determine if the Xinge response is success. |
164
|
|
|
* |
165
|
|
|
* @see http://developer.qq.com/wiki/xg/%E6%9C%8D%E5%8A%A1%E7%AB%AFAPI%E6%8E%A5%E5%85%A5/Rest%20API%20%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/Rest%20API%20%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97.html |
166
|
|
|
* |
167
|
|
|
* @param mixed $response |
168
|
|
|
* @return bool |
169
|
|
|
*/ |
170
|
|
|
public function succeed($response) |
171
|
|
|
{ |
172
|
|
|
return $this->code($response) === 0; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Get the code of Xinge response. |
177
|
|
|
* |
178
|
|
|
* @param mixed $response |
179
|
|
|
* @return int|null |
180
|
|
|
*/ |
181
|
|
|
public function code($response) |
182
|
|
|
{ |
183
|
|
|
if (is_array($response)) { |
184
|
|
|
return array_get($response, 'ret_code'); |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Get the error message of Xinge response. |
190
|
|
|
* |
191
|
|
|
* @param mixed $response |
192
|
|
|
* @return string|null |
193
|
|
|
*/ |
194
|
|
|
public function message($response) |
195
|
|
|
{ |
196
|
|
|
if (is_array($response)) { |
197
|
|
|
return array_get($response, 'err_msg'); |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Get the result data of Xinge response. |
203
|
|
|
* |
204
|
|
|
* @param mixed $response |
205
|
|
|
* @param string $key |
206
|
|
|
* @param mixed $default |
207
|
|
|
* @return mixed |
208
|
|
|
*/ |
209
|
|
|
public function result($response, $key = null, $default = null) |
210
|
|
|
{ |
211
|
|
|
if (is_array($response)) { |
212
|
|
|
return array_get($response, $key ? "result.{$key}" : 'result', $default); |
213
|
|
|
} |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
/** |
217
|
|
|
* Encode the custom data. |
218
|
|
|
* |
219
|
|
|
* @param mixed $data |
220
|
|
|
* @return array |
221
|
|
|
*/ |
222
|
|
|
public function encodeCustomData($data) |
223
|
|
|
{ |
224
|
|
|
if ($this->customKey && $data) { |
225
|
|
|
return [$this->customKey => $data]; |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
return $data ?: []; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* Get Xinge account for the given user. |
233
|
|
|
* |
234
|
|
|
* @param mixed $user |
235
|
|
|
* @return string |
236
|
|
|
*/ |
237
|
|
|
public function accountForUser($user) |
238
|
|
|
{ |
239
|
|
|
if ($this->accountPrefix && is_string($user) && starts_with($user, $this->accountPrefix)) { |
240
|
|
|
return $user; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
View Code Duplication |
if (is_object($user)) { |
|
|
|
|
244
|
|
|
$user = $user->id; |
245
|
|
|
} elseif (is_array($user)) { |
246
|
|
|
$user = $user['id']; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
return $this->accountPrefix.$user; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* Get Xinge accounts for users. |
254
|
|
|
* |
255
|
|
|
* @param array $users |
256
|
|
|
* @return array |
257
|
|
|
*/ |
258
|
|
|
public function accountsForUsers(array $users) |
259
|
|
|
{ |
260
|
|
|
return array_map([$this, 'accountForUser'], $users); |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* Creates a new MessageIOS instance. |
265
|
|
|
* |
266
|
|
|
* @param string $alert |
267
|
|
|
* @param mixed $custom |
268
|
|
|
* @param int $badge |
269
|
|
|
* @param string $sound |
270
|
|
|
* @return \ElfSundae\XgPush\MessageIOS |
271
|
|
|
*/ |
272
|
|
|
public function createIOSMessage($alert = '', $custom = null, $badge = 1, $sound = 'default') |
273
|
|
|
{ |
274
|
|
|
$message = new MessageIOS(); |
275
|
|
|
$message->setAlert($alert); |
276
|
|
|
$message->setCustom($this->encodeCustomData($custom)); |
277
|
|
|
if (is_int($badge) && $badge >= 0) { |
278
|
|
|
$message->setBadge($badge); |
279
|
|
|
} |
280
|
|
|
if ($sound) { |
281
|
|
|
$message->setSound($sound); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
return $message; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* Create a new Message instance. |
289
|
|
|
* |
290
|
|
|
* @param string $title |
291
|
|
|
* @param string $content |
292
|
|
|
* @param mixed $custom |
293
|
|
|
* @param int $type |
294
|
|
|
* @return \ElfSundae\XgPush\Message |
295
|
|
|
*/ |
296
|
|
|
public function createAndroidMessage($title = '', $content = '', $custom = null, $type = Message::TYPE_MESSAGE) |
297
|
|
|
{ |
298
|
|
|
$message = new Message(); |
299
|
|
|
$message->setTitle($title); |
300
|
|
|
$message->setContent($content); |
301
|
|
|
$message->setCustom($this->encodeCustomData($custom)); |
302
|
|
|
$message->setType($type); |
303
|
|
|
|
304
|
|
|
return $message; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* Create a new Message instance for notification. |
309
|
|
|
* The default action is opening app. |
310
|
|
|
* |
311
|
|
|
* @param string $title |
312
|
|
|
* @param string $content |
313
|
|
|
* @param mixed $custom |
314
|
|
|
* @return \ElfSundae\XgPush\Message |
315
|
|
|
*/ |
316
|
|
|
public function createAndroidNotification($title = '', $content = '', $custom = null) |
317
|
|
|
{ |
318
|
|
|
$message = $this->createAndroidMessage($title, $content, $custom, Message::TYPE_NOTIFICATION); |
319
|
|
|
|
320
|
|
|
$message->setStyle(new Style(0, 1, 1, 1, 0)); |
321
|
|
|
$action = new ClickAction(); |
322
|
|
|
$action->setActionType(ClickAction::TYPE_ACTIVITY); |
323
|
|
|
$message->setAction($action); |
324
|
|
|
|
325
|
|
|
return $message; |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
/** |
329
|
|
|
* Push message to a device. |
330
|
|
|
* |
331
|
|
|
* @param \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS $message |
332
|
|
|
* @param string $deviceToken |
333
|
|
|
* @return array |
334
|
|
|
*/ |
335
|
|
|
public function toDevice($message, $deviceToken) |
336
|
|
|
{ |
337
|
|
|
return $this->xinge->PushSingleDevice($deviceToken, $message, $this->environment); |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
/** |
341
|
|
|
* Push message to all devices. |
342
|
|
|
* |
343
|
|
|
* @param \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS $message |
344
|
|
|
* @return array |
345
|
|
|
*/ |
346
|
|
|
public function toAllDevices($message) |
347
|
|
|
{ |
348
|
|
|
return $this->xinge->PushAllDevices(0, $message, $this->environment); |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
/** |
352
|
|
|
* Push message to users. |
353
|
|
|
* |
354
|
|
|
* @warning 用户数限制 100 个。 |
355
|
|
|
* |
356
|
|
|
* @param \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS $message |
357
|
|
|
* @param mixed $users |
358
|
|
|
* @return array |
359
|
|
|
*/ |
360
|
|
|
public function toUser($message, $users) |
|
|
|
|
361
|
|
|
{ |
362
|
|
|
$users = $this->getParameterAsArray(func_get_args(), 1); |
363
|
|
|
$accounts = $this->accountsForUsers($users); |
364
|
|
|
|
365
|
|
|
if (count($accounts) == 1) { |
366
|
|
|
return $this->xinge->PushSingleAccount(0, $accounts[0], $message, $this->environment); |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
return $this->xinge->PushAccountList(0, $accounts, $message, $this->environment); |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
/** |
373
|
|
|
* Push message to tagged devices. |
374
|
|
|
* |
375
|
|
|
* @param \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS $message |
376
|
|
|
* @param string|string[] $tags |
377
|
|
|
* @param string $tagsOperation 'OR', 'AND' |
378
|
|
|
* @return array |
379
|
|
|
*/ |
380
|
|
|
public function toTags($message, $tags, $tagsOperation = 'OR') |
381
|
|
|
{ |
382
|
|
|
return $this->xinge->PushTags(0, (array) $tags, strtoupper($tagsOperation), $message, $this->environment); |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
/** |
386
|
|
|
* Create a batch push. |
387
|
|
|
* |
388
|
|
|
* @param \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS $message |
389
|
|
|
* @return string|null |
390
|
|
|
*/ |
391
|
|
|
public function createBatch($message) |
392
|
|
|
{ |
393
|
|
|
return $this->result($this->xinge->CreateMultipush($message, $this->environment), 'push_id'); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
/** |
397
|
|
|
* Batch pushing to a list of users. |
398
|
|
|
* |
399
|
|
|
* @warning 用户数限制 1000 个。 |
400
|
|
|
* |
401
|
|
|
* @param int|string $pushId |
402
|
|
|
* @param mixed $users |
403
|
|
|
* @return array |
404
|
|
|
*/ |
405
|
|
|
public function batchToUsers($pushId, $users) |
|
|
|
|
406
|
|
|
{ |
407
|
|
|
return $this->xinge->PushAccountListMultiple( |
408
|
|
|
$pushId, |
409
|
|
|
$this->accountsForUsers($this->getParameterAsArray(func_get_args(), 1)) |
410
|
|
|
); |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
/** |
414
|
|
|
* Batch pushing to a list of devices. |
415
|
|
|
* |
416
|
|
|
* @warning 设备数限制 1000 个。 |
417
|
|
|
* |
418
|
|
|
* @param int|string $pushId |
419
|
|
|
* @param mixed $deviceTokens |
420
|
|
|
* @return array |
421
|
|
|
*/ |
422
|
|
|
public function batchToDevices($pushId, $deviceTokens) |
|
|
|
|
423
|
|
|
{ |
424
|
|
|
return $this->xinge->PushDeviceListMultiple( |
425
|
|
|
$pushId, |
426
|
|
|
$this->getParameterAsArray(func_get_args(), 1) |
427
|
|
|
); |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
/** |
431
|
|
|
* Query group pushing status. |
432
|
|
|
* |
433
|
|
|
* @param mixed $pushIds |
434
|
|
|
* @return array |
435
|
|
|
*/ |
436
|
|
|
public function queryPushStatus($pushIds) |
|
|
|
|
437
|
|
|
{ |
438
|
|
|
$pushIds = $this->getParameterAsArray(func_get_args()); |
439
|
|
|
|
440
|
|
|
$list = $this->result($this->xinge->QueryPushStatus($pushIds), 'list', []); |
441
|
|
|
|
442
|
|
|
return array_combine(array_pluck($list, 'push_id'), $list); |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
/** |
446
|
|
|
* Cancel a timed pushing task that has not been pushed. |
447
|
|
|
* |
448
|
|
|
* @param string $pushId |
449
|
|
|
* @return array |
450
|
|
|
*/ |
451
|
|
|
public function cancelTimedPush($pushId) |
452
|
|
|
{ |
453
|
|
|
return $this->xinge->CancelTimingPush($pushId); |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* Query all device tokens for the given user. |
458
|
|
|
* |
459
|
|
|
* @param mixed $user |
460
|
|
|
* @return string[] |
461
|
|
|
*/ |
462
|
|
|
public function queryDeviceTokensForUser($user) |
463
|
|
|
{ |
464
|
|
|
return $this->result($this->xinge->QueryTokensOfAccount($this->accountForUser($user)), 'tokens', []); |
465
|
|
|
} |
466
|
|
|
|
467
|
|
|
/** |
468
|
|
|
* Delete device tokens for the given user. |
469
|
|
|
* |
470
|
|
|
* @param mixed $user |
471
|
|
|
* @param string|string[] $deviceTokens |
472
|
|
|
* @return bool |
473
|
|
|
*/ |
474
|
|
|
public function deleteDeviceTokensForUser($user, $deviceTokens = null) |
475
|
|
|
{ |
476
|
|
|
$account = $this->accountForUser($user); |
477
|
|
|
|
478
|
|
|
if (is_null($deviceTokens)) { |
479
|
|
|
return $this->succeed($this->xinge->DeleteAllTokensOfAccount($account)); |
480
|
|
|
} |
481
|
|
|
|
482
|
|
|
$deviceTokens = array_unique((array) $deviceTokens); |
483
|
|
|
|
484
|
|
|
$result = true; |
485
|
|
|
|
486
|
|
|
foreach ($deviceTokens as $token) { |
487
|
|
|
$result = $result && $this->succeed($this->xinge->DeleteTokenOfAccount($account, $token)); |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
return $result; |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
/** |
494
|
|
|
* Query count of registered devices. |
495
|
|
|
* |
496
|
|
|
* @return int |
497
|
|
|
*/ |
498
|
|
|
public function queryCountOfDevices() |
499
|
|
|
{ |
500
|
|
|
return $this->result($this->xinge->QueryDeviceCount(), 'device_num', 0); |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
/** |
504
|
|
|
* Query info for the given device token. |
505
|
|
|
* |
506
|
|
|
* @param string $deviceToken |
507
|
|
|
* @return array |
508
|
|
|
*/ |
509
|
|
|
public function queryDeviceTokenInfo($deviceToken) |
510
|
|
|
{ |
511
|
|
|
return $this->xinge->QueryInfoOfToken($deviceToken); |
512
|
|
|
} |
513
|
|
|
|
514
|
|
|
/** |
515
|
|
|
* Query count of registered tokens for the given tag. |
516
|
|
|
* |
517
|
|
|
* @param string $tag |
518
|
|
|
* @return int |
519
|
|
|
*/ |
520
|
|
|
public function queryCountOfDeviceTokensForTag($tag) |
521
|
|
|
{ |
522
|
|
|
return $this->result($this->xinge->QueryTagTokenNum($tag), 'device_num', 0); |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
/** |
526
|
|
|
* Query tags. |
527
|
|
|
* |
528
|
|
|
* @return array |
529
|
|
|
*/ |
530
|
|
|
public function queryTags($start = 0, $limit = 100) |
531
|
|
|
{ |
532
|
|
|
return $this->xinge->QueryTags($start, $limit); |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
/** |
536
|
|
|
* Query all tags for the given device token. |
537
|
|
|
* |
538
|
|
|
* @param string $deviceToken |
539
|
|
|
* @return string[] |
540
|
|
|
*/ |
541
|
|
|
public function queryTagsForDeviceToken($deviceToken) |
542
|
|
|
{ |
543
|
|
|
return $this->result($this->xinge->QueryTokenTags($deviceToken), 'tags', []); |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
/** |
547
|
|
|
* Query all tags for the given user. |
548
|
|
|
* |
549
|
|
|
* @param mixed $user |
550
|
|
|
* @param array &$deviceTokens |
551
|
|
|
* @return array |
552
|
|
|
*/ |
553
|
|
|
public function queryTagsForUser($user, &$deviceTokens = null) |
554
|
|
|
{ |
555
|
|
|
$deviceTokens = $this->queryDeviceTokensForUser($user); |
556
|
|
|
|
557
|
|
|
$result = []; |
558
|
|
|
foreach ($deviceTokens as $token) { |
559
|
|
|
$result[$token] = $this->queryTagsForDeviceToken($token); |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
return $result; |
563
|
|
|
} |
564
|
|
|
|
565
|
|
|
/** |
566
|
|
|
* Add tags for device tokens. |
567
|
|
|
* |
568
|
|
|
* @warning 每次最多设置 20 对。 |
569
|
|
|
* |
570
|
|
|
* @param \ElfSundae\XgPush\TagTokenPair[] $tagTokenPairs |
571
|
|
|
* @return bool |
572
|
|
|
*/ |
573
|
|
|
public function addTags($tagTokenPairs) |
574
|
|
|
{ |
575
|
|
|
return $this->succeed($this->xinge->BatchSetTag($tagTokenPairs)); |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
/** |
579
|
|
|
* Add tags for the given device token. |
580
|
|
|
* |
581
|
|
|
* @param string $deviceToken |
582
|
|
|
* @param mixed $tags |
583
|
|
|
* @return bool |
584
|
|
|
*/ |
585
|
|
|
public function addTagsForDeviceToken($deviceToken, $tags) |
|
|
|
|
586
|
|
|
{ |
587
|
|
|
return $this->addTags( |
588
|
|
|
$this->createTagTokenPairs($this->getParameterAsArray(func_get_args(), 1), $deviceToken) |
589
|
|
|
); |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
/** |
593
|
|
|
* Add tags for the given user. |
594
|
|
|
* |
595
|
|
|
* @param mixed $user |
596
|
|
|
* @param mixed $tags |
597
|
|
|
* @return bool |
598
|
|
|
*/ |
599
|
|
|
public function addTagsForUser($user, $tags) |
|
|
|
|
600
|
|
|
{ |
601
|
|
|
return $this->addTags( |
602
|
|
|
$this->createTagTokenPairs( |
603
|
|
|
$this->getParameterAsArray(func_get_args(), 1), |
604
|
|
|
$this->queryDeviceTokensForUser($user) |
605
|
|
|
) |
606
|
|
|
); |
607
|
|
|
} |
608
|
|
|
|
609
|
|
|
/** |
610
|
|
|
* Remove tags for device tokens. |
611
|
|
|
* |
612
|
|
|
* @warning 每次最多删除 20 对。 |
613
|
|
|
* |
614
|
|
|
* @param \ElfSundae\XgPush\TagTokenPair[] $tagTokenPairs |
615
|
|
|
* @return bool |
616
|
|
|
*/ |
617
|
|
|
public function removeTags($tagTokenPairs) |
618
|
|
|
{ |
619
|
|
|
return $this->succeed($this->xinge->BatchDelTag($tagTokenPairs)); |
620
|
|
|
} |
621
|
|
|
|
622
|
|
|
/** |
623
|
|
|
* Remove tags for the given device token. |
624
|
|
|
* |
625
|
|
|
* @param string $deviceToken |
626
|
|
|
* @param mixed $tags |
627
|
|
|
* @return bool |
628
|
|
|
*/ |
629
|
|
|
public function removeTagsForDeviceToken($deviceToken, $tags) |
|
|
|
|
630
|
|
|
{ |
631
|
|
|
return $this->removeTags( |
632
|
|
|
$this->createTagTokenPairs($this->getParameterAsArray(func_get_args(), 1), $deviceToken) |
633
|
|
|
); |
634
|
|
|
} |
635
|
|
|
|
636
|
|
|
/** |
637
|
|
|
* Remove tags for the given user. |
638
|
|
|
* |
639
|
|
|
* @param mixed $user |
640
|
|
|
* @param mixed $tags |
641
|
|
|
* @return bool |
642
|
|
|
*/ |
643
|
|
|
public function removeTagsForUser($user, $tags) |
|
|
|
|
644
|
|
|
{ |
645
|
|
|
return $this->removeTags( |
646
|
|
|
$this->createTagTokenPairs( |
647
|
|
|
$this->getParameterAsArray(func_get_args(), 1), |
648
|
|
|
$this->queryDeviceTokensForUser($user) |
649
|
|
|
) |
650
|
|
|
); |
651
|
|
|
} |
652
|
|
|
|
653
|
|
|
/** |
654
|
|
|
* Set tags for the given device token. |
655
|
|
|
* |
656
|
|
|
* @param string $deviceToken |
657
|
|
|
* @param mixed $tags |
658
|
|
|
* @return bool |
659
|
|
|
*/ |
660
|
|
|
public function setTagsForDeviceToken($deviceToken, $tags) |
|
|
|
|
661
|
|
|
{ |
662
|
|
|
$tags = $this->getParameterAsArray(func_get_args(), 1); |
663
|
|
|
$oldTags = $this->queryTagsForDeviceToken($deviceToken); |
664
|
|
|
|
665
|
|
|
$result = true; |
666
|
|
|
|
667
|
|
|
if ($addTags = array_diff($tags, $oldTags)) { |
668
|
|
|
$result = $result && $this->addTagsForDeviceToken($deviceToken, $addTags); |
669
|
|
|
} |
670
|
|
|
|
671
|
|
|
if ($removeTags = array_diff($oldTags, $tags)) { |
672
|
|
|
$result = $result && $this->removeTagsForDeviceToken($deviceToken, $removeTags); |
673
|
|
|
} |
674
|
|
|
|
675
|
|
|
return $result; |
676
|
|
|
} |
677
|
|
|
|
678
|
|
|
/** |
679
|
|
|
* Set tags for the given user. |
680
|
|
|
* |
681
|
|
|
* @param mixed $user |
682
|
|
|
* @param mixed $tags |
683
|
|
|
* @return bool |
684
|
|
|
*/ |
685
|
|
|
public function setTagsForUser($user, $tags) |
|
|
|
|
686
|
|
|
{ |
687
|
|
|
$tags = $this->getParameterAsArray(func_get_args(), 1); |
688
|
|
|
$oldTags = $this->queryTagsForUser($user, $tokens); |
689
|
|
|
|
690
|
|
|
$addTagTokenPairs = []; |
691
|
|
|
$removeTagTokenPairs = []; |
692
|
|
|
|
693
|
|
|
foreach ($oldTags as $token => $tokenTags) { |
694
|
|
|
$addTagTokenPairs = array_merge($addTagTokenPairs, |
695
|
|
|
$this->createTagTokenPairs(array_diff($tags, $tokenTags), $token) |
696
|
|
|
); |
697
|
|
|
|
698
|
|
|
$removeTagTokenPairs = array_merge($removeTagTokenPairs, |
699
|
|
|
$this->createTagTokenPairs(array_diff($tokenTags, $tags), $token) |
700
|
|
|
); |
701
|
|
|
} |
702
|
|
|
|
703
|
|
|
$result = true; |
704
|
|
|
|
705
|
|
|
if (count($addTagTokenPairs) > 0) { |
706
|
|
|
$result = $result && $this->addTags($addTagTokenPairs); |
707
|
|
|
} |
708
|
|
|
|
709
|
|
|
if (count($removeTagTokenPairs) > 0) { |
710
|
|
|
$result = $result && $this->removeTags($removeTagTokenPairs); |
711
|
|
|
} |
712
|
|
|
|
713
|
|
|
return $result; |
714
|
|
|
} |
715
|
|
|
|
716
|
|
|
/** |
717
|
|
|
* Get parameter as array. |
718
|
|
|
* |
719
|
|
|
* @param array $args |
720
|
|
|
* @param int $offset |
721
|
|
|
* @return array |
722
|
|
|
*/ |
723
|
|
|
protected function getParameterAsArray(array $args, $offset = 0) |
724
|
|
|
{ |
725
|
|
|
return is_array($args[$offset]) ? $args[$offset] : array_slice($args, $offset); |
726
|
|
|
} |
727
|
|
|
|
728
|
|
|
/** |
729
|
|
|
* Create array of TagTokenPair. |
730
|
|
|
* |
731
|
|
|
* @warning $tags 和 $tokens 一个是数组,另一个是字符串 |
732
|
|
|
* |
733
|
|
|
* @param string|string[] $tags |
734
|
|
|
* @param string|string[] $tokens |
735
|
|
|
* @return \ElfSundae\XgPush\TagTokenPair[] |
736
|
|
|
*/ |
737
|
|
|
protected function createTagTokenPairs($tags, $tokens) |
738
|
|
|
{ |
739
|
|
|
$tagTokenPairs = []; |
740
|
|
|
|
741
|
|
|
$tokens = (array) $tokens; |
742
|
|
|
foreach ((array) $tags as $tag) { |
743
|
|
|
foreach ($tokens as $token) { |
744
|
|
|
$tagTokenPairs[] = new TagTokenPair($tag, $token); |
745
|
|
|
} |
746
|
|
|
} |
747
|
|
|
|
748
|
|
|
return $tagTokenPairs; |
749
|
|
|
} |
750
|
|
|
|
751
|
|
|
/** |
752
|
|
|
* Dynamically handle calls to the XingeApp instance. |
753
|
|
|
* |
754
|
|
|
* @param string $method |
755
|
|
|
* @param array $parameters |
756
|
|
|
* @return mixed |
757
|
|
|
*/ |
758
|
|
|
public function __call($method, $parameters) |
759
|
|
|
{ |
760
|
|
|
return call_user_func_array([$this->xinge, $method], $parameters); |
761
|
|
|
} |
762
|
|
|
} |
763
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.