|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace App\Support\Tencent; |
|
4
|
|
|
|
|
5
|
|
|
use ElfSundae\XgPush\XingeApp; |
|
6
|
|
|
|
|
7
|
|
|
class XgPusher |
|
8
|
|
|
{ |
|
9
|
|
|
/** |
|
10
|
|
|
* The XingeApp instance. |
|
11
|
|
|
* |
|
12
|
|
|
* @var \ElfSundae\XgPush\XingeApp |
|
13
|
|
|
*/ |
|
14
|
|
|
protected $service; |
|
15
|
|
|
|
|
16
|
|
|
/** |
|
17
|
|
|
* Create a new instance. |
|
18
|
|
|
*/ |
|
19
|
|
|
public function __construct() |
|
20
|
|
|
{ |
|
21
|
|
|
$this->service = static::createService(); |
|
22
|
|
|
} |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* Get the XingeApp instance. |
|
26
|
|
|
* |
|
27
|
|
|
* @return \ElfSundae\XgPush\XingeApp |
|
28
|
|
|
*/ |
|
29
|
|
|
public function getService() |
|
30
|
|
|
{ |
|
31
|
|
|
return $this->service; |
|
32
|
|
|
} |
|
33
|
|
|
|
|
34
|
|
|
/** |
|
35
|
|
|
* Create a XingeApp instance. |
|
36
|
|
|
* |
|
37
|
|
|
* @return \ElfSundae\XgPush\XingeApp |
|
38
|
|
|
*/ |
|
39
|
|
|
public static function createService() |
|
40
|
|
|
{ |
|
41
|
|
|
return new XingeApp(static::appKey(), static::appSecret()); |
|
42
|
|
|
} |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* Get the app key. |
|
46
|
|
|
* |
|
47
|
|
|
* @return string |
|
48
|
|
|
*/ |
|
49
|
|
|
public static function appKey() |
|
50
|
|
|
{ |
|
51
|
|
|
return config('services.xgpush.key'); |
|
52
|
|
|
} |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* Get the app secret. |
|
56
|
|
|
* |
|
57
|
|
|
* @return string |
|
58
|
|
|
*/ |
|
59
|
|
|
public static function appSecret() |
|
60
|
|
|
{ |
|
61
|
|
|
return config('services.xgpush.secret'); |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
/** |
|
65
|
|
|
* Get the custom key. |
|
66
|
|
|
* |
|
67
|
|
|
* @return string |
|
68
|
|
|
*/ |
|
69
|
|
|
public static function customKey() |
|
70
|
|
|
{ |
|
71
|
|
|
return config('services.xgpush.custom_key', 'custom'); |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
/** |
|
75
|
|
|
* Get the environment. |
|
76
|
|
|
* |
|
77
|
|
|
* environment: 向iOS设备推送时必填,1表示推送生产环境;2表示推送开发环境。推送Android平台不填或填0. |
|
78
|
|
|
* |
|
79
|
|
|
* @return int |
|
80
|
|
|
*/ |
|
81
|
|
|
public static function environment() |
|
82
|
|
|
{ |
|
83
|
|
|
return config('services.xgpush.environment') == 'production' ? |
|
84
|
|
|
XingeApp::IOSENV_PROD : |
|
85
|
|
|
XingeApp::IOSENV_DEV; |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* 解析信鸽返回的结果。 |
|
90
|
|
|
* |
|
91
|
|
|
* @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 |
|
92
|
|
|
* |
|
93
|
|
|
* @param mixed $xgResult 信鸽的请求结果 |
|
94
|
|
|
* @param int &$code 返回码,0 为成功 |
|
95
|
|
|
* @param string &$message 请求出错时的错误信息 |
|
96
|
|
|
* @param mixed &$result 请求正确时的额外数据 |
|
97
|
|
|
* @return bool |
|
98
|
|
|
*/ |
|
99
|
|
|
public static function parseResult($xgResult = null, &$code = null, &$message = null, &$result = null) |
|
100
|
|
|
{ |
|
101
|
|
|
if (is_array($xgResult) && isset($xgResult['ret_code'])) { |
|
102
|
|
|
$code = (int) $xgResult['ret_code']; |
|
103
|
|
|
$message = isset($xgResult['err_msg']) ? (string) $xgResult['err_msg'] : ''; |
|
104
|
|
|
if (isset($xgResult['result'])) { |
|
105
|
|
|
$result = $xgResult['result']; |
|
106
|
|
|
} |
|
107
|
|
|
} else { |
|
108
|
|
|
$code = -99999; |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
return $code === 0; |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* Encode the custom data. |
|
116
|
|
|
* |
|
117
|
|
|
* @param mixed $data |
|
118
|
|
|
* @return array|null |
|
119
|
|
|
*/ |
|
120
|
|
|
public static function encodeCustomData($data) |
|
121
|
|
|
{ |
|
122
|
|
|
return ! empty($data) ? [static::customKey() => $data] : null; |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
/** |
|
126
|
|
|
* Get Xinge account for the given user. |
|
127
|
|
|
* |
|
128
|
|
|
* @param mixed $user |
|
129
|
|
|
* @return string |
|
130
|
|
|
*/ |
|
131
|
|
|
public static function accountForUser($user) |
|
132
|
|
|
{ |
|
133
|
|
View Code Duplication |
if (is_object($user)) { |
|
|
|
|
|
|
134
|
|
|
$user = $user->id; |
|
135
|
|
|
} elseif (is_array($user)) { |
|
136
|
|
|
$user = $user['id']; |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
// 信鸽不允许使用简单的账号,例如纯数字的id。 |
|
140
|
|
|
// 所以在 userId 前面加个 'user' 字符。 |
|
141
|
|
|
if (starts_with($user, 'user')) { |
|
142
|
|
|
return $user; |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
return 'user'.$user; |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
/** |
|
149
|
|
|
* Creates a MessageIOS instance. |
|
150
|
|
|
* |
|
151
|
|
|
* @param string $alert |
|
152
|
|
|
* @param mixed $custom |
|
153
|
|
|
* @param int $badge |
|
154
|
|
|
* @param string $sound |
|
155
|
|
|
* @return MessageIOS |
|
156
|
|
|
*/ |
|
157
|
|
|
public static function createIOSMessage($alert = '', $custom = null, $badge = 1, $sound = 'default') |
|
158
|
|
|
{ |
|
159
|
|
|
$message = new MessageIOS(); |
|
160
|
|
|
$message->setAlert($alert); |
|
161
|
|
|
if ($customData = static::encodeCustomData($custom)) { |
|
162
|
|
|
$message->setCustom($customData); |
|
163
|
|
|
} |
|
164
|
|
|
if (is_numeric($badge) && $badge >= 0) { |
|
165
|
|
|
$message->setBadge($badge); |
|
166
|
|
|
} |
|
167
|
|
|
if (! empty($sound)) { |
|
168
|
|
|
$message->setSound($sound); |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
|
|
return $message; |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
/** |
|
175
|
|
|
* Create a Message instance. |
|
176
|
|
|
* |
|
177
|
|
|
* @param string $content |
|
178
|
|
|
* @param mixed $custom |
|
179
|
|
|
* @param string $title |
|
180
|
|
|
* @param int $type |
|
181
|
|
|
* @return Message |
|
182
|
|
|
*/ |
|
183
|
|
|
public static function createAndroidMessage($content = '', $custom = null, $title = null, $type = Message::TYPE_NOTIFICATION) |
|
184
|
|
|
{ |
|
185
|
|
|
$message = new Message(); |
|
186
|
|
|
$message->setTitle($title ?: config('app.name')); |
|
187
|
|
|
$message->setContent($content); |
|
188
|
|
|
if ($customData = static::encodeCustomData($custom)) { |
|
189
|
|
|
$message->setCustom($customData); |
|
190
|
|
|
} |
|
191
|
|
|
$message->setType($type); |
|
192
|
|
|
//含义:样式编号0,响铃,震动,不可从通知栏清除,不影响先前通知 |
|
193
|
|
|
$message->setStyle(new Style(0, 1, 1, 1, 0)); |
|
194
|
|
|
$action = new ClickAction(); |
|
195
|
|
|
$action->setActionType(ClickAction::TYPE_ACTIVITY); |
|
196
|
|
|
$message->setAction($action); |
|
197
|
|
|
|
|
198
|
|
|
return $message; |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
/** |
|
202
|
|
|
* Query all device tokens for the given user. |
|
203
|
|
|
* |
|
204
|
|
|
* @param mixed $user |
|
205
|
|
|
* @return string[]|null |
|
206
|
|
|
*/ |
|
207
|
|
View Code Duplication |
public static function queryDeviceTokensForUser($user) |
|
|
|
|
|
|
208
|
|
|
{ |
|
209
|
|
|
$query = static::createService()->QueryTokensOfAccount(static::accountForUser($user)); |
|
210
|
|
|
|
|
211
|
|
|
if (static::parseResult($query, null, null, $result)) { |
|
|
|
|
|
|
212
|
|
|
return is_array($result) ? array_get($result, 'tokens', []) : []; |
|
213
|
|
|
} |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
|
/** |
|
217
|
|
|
* Query all tags for the given device token. |
|
218
|
|
|
* |
|
219
|
|
|
* @param string $deviceToken |
|
220
|
|
|
* @return string[]|null |
|
221
|
|
|
*/ |
|
222
|
|
View Code Duplication |
public static function queryTagsForDeviceToken($deviceToken) |
|
|
|
|
|
|
223
|
|
|
{ |
|
224
|
|
|
$query = static::createService()->QueryTokenTags($deviceToken); |
|
225
|
|
|
|
|
226
|
|
|
if (static::parseResult($query, null, null, $result)) { |
|
|
|
|
|
|
227
|
|
|
return is_array($result) ? array_get($result, 'tags', []) : []; |
|
228
|
|
|
} |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
/** |
|
232
|
|
|
* Query all tags for the given user. |
|
233
|
|
|
* |
|
234
|
|
|
* @param mixed $user |
|
235
|
|
|
* @param array &$deviceTokens |
|
236
|
|
|
* @return array|null |
|
237
|
|
|
*/ |
|
238
|
|
|
public static function queryTagsForUser($user, &$deviceTokens = null) |
|
239
|
|
|
{ |
|
240
|
|
|
$deviceTokens = static::queryDeviceTokensForUser($user); |
|
241
|
|
|
|
|
242
|
|
|
$result = []; |
|
243
|
|
|
foreach ($deviceTokens as $token) { |
|
|
|
|
|
|
244
|
|
|
if ($tags = static::queryTagsForDeviceToken($token)) { |
|
245
|
|
|
$result[$token] = $tags; |
|
246
|
|
|
} |
|
247
|
|
|
} |
|
248
|
|
|
|
|
249
|
|
|
return $result; |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
/** |
|
253
|
|
|
* Dynamically handle calls to the XingeApp class. |
|
254
|
|
|
* |
|
255
|
|
|
* @param string $method |
|
256
|
|
|
* @param array $parameters |
|
257
|
|
|
* @return mixed |
|
258
|
|
|
*/ |
|
259
|
|
|
public static function __callStatic($method, $parameters) |
|
260
|
|
|
{ |
|
261
|
|
|
array_unshift($parameters, static::appKey(), static::appSecret()); |
|
262
|
|
|
|
|
263
|
|
|
return call_user_func_array([XingeApp::class, $method], $parameters); |
|
264
|
|
|
} |
|
265
|
|
|
|
|
266
|
|
|
/** |
|
267
|
|
|
* Dynamically handle calls to the XingeApp instance. |
|
268
|
|
|
* |
|
269
|
|
|
* @param string $method |
|
270
|
|
|
* @param array $parameters |
|
271
|
|
|
* @return mixed |
|
272
|
|
|
*/ |
|
273
|
|
|
public function __call($method, $parameters) |
|
274
|
|
|
{ |
|
275
|
|
|
return call_user_func_array([$this->getService(), $method], $parameters); |
|
276
|
|
|
} |
|
277
|
|
|
} |
|
278
|
|
|
|
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.