Completed
Push — master ( ae96ea...875983 )
by Elf
05:06
created

XgPusher::createBatch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Support\Tencent;
4
5
use ElfSundae\XgPush\ClickAction;
6
use ElfSundae\XgPush\Message;
7
use ElfSundae\XgPush\MessageIOS;
8
use ElfSundae\XgPush\Style;
9
use ElfSundae\XgPush\XingeApp;
10
11
class XgPusher
12
{
13
    /**
14
     * The XingeApp instance.
15
     *
16
     * @var \ElfSundae\XgPush\XingeApp
17
     */
18
    protected $xinge;
19
20
    /**
21
     * The pusher environment.
22
     *
23
     * 向iOS设备推送时必填,1表示推送生产环境;2表示推送开发环境。推送Android平台不填或填0.
24
     *
25
     * @var int
26
     */
27
    protected $environment = XingeApp::IOSENV_DEV;
28
29
    /**
30
     * The key of custom payload.
31
     *
32
     * @var string
33
     */
34
    protected $customKey = 'custom';
35
36
    /**
37
     * Xinge account prefix.
38
     *
39
     * @warning 信鸽不允许使用简单的账号,例如纯数字的id。
40
     *
41
     * @var string
42
     */
43
    protected $accountPrefix = 'user';
44
45
    /**
46
     * Create a new instance.
47
     *
48
     * @param  string  $appKey
49
     * @param  string  $appSecret
50
     */
51
    public function __construct($appKey, $appSecret)
52
    {
53
        $this->xinge = new XingeApp($appKey, $appSecret);
54
    }
55
56
    /**
57
     * Get the XingeApp instance.
58
     *
59
     * @return \ElfSundae\XgPush\XingeApp
60
     */
61
    public function getXinge()
62
    {
63
        return $this->xinge;
64
    }
65
66
    /**
67
     * Get the app key.
68
     *
69
     * @return string
70
     */
71
    public function getAppKey()
72
    {
73
        return $this->xinge->accessId;
74
    }
75
76
    /**
77
     * Get the app secret.
78
     *
79
     * @return string
80
     */
81
    public function getAppSecret()
82
    {
83
        return $this->xinge->secretKey;
84
    }
85
86
    /**
87
     * Get the pusher environment.
88
     *
89
     * @return int
90
     */
91
    public function getEnvironment()
92
    {
93
        return $this->environment;
94
    }
95
96
    /**
97
     * Set the pusher environment.
98
     *
99
     * @param  mixed  $env
100
     * @return $this
101
     */
102
    public function setEnvironment($env)
103
    {
104
        if (is_string($env)) {
105
            $env = $env == 'production' ? XingeApp::IOSENV_PROD : XingeApp::IOSENV_DEV;
106
        }
107
108
        if (is_numeric($env)) {
109
            $this->environment = $env;
0 ignored issues
show
Documentation Bug introduced by
It seems like $env can also be of type double or string. However, the property $environment is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
110
        }
111
112
        return $this;
113
    }
114
115
    /**
116
     * Get the key of custom payload.
117
     *
118
     * @return string
119
     */
120
    public function getCustomKey()
121
    {
122
        return $this->customKey;
123
    }
124
125
    /**
126
     * Set the key of custom payload.
127
     *
128
     * @param  string  $key
129
     * @return $this
130
     */
131
    public function setCustomKey($key)
132
    {
133
        if ($key) {
134
            $this->customKey = $key;
135
        }
136
137
        return $this;
138
    }
139
140
    /**
141
     * Get the account prefix.
142
     *
143
     * @return string
144
     */
145
    public function getAccountPrefix()
146
    {
147
        return $this->accountPrefix;
148
    }
149
150
    /**
151
     * Set the account prefix.
152
     *
153
     * @param  string  $prefix
154
     * @return $this
155
     */
156
    public function setAccountPrefix($prefix)
157
    {
158
        $this->accountPrefix = $prefix;
159
160
        return $this;
161
    }
162
163
    /**
164
     * Determine if the Xinge response is success.
165
     *
166
     * @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
167
     *
168
     * @param  mixed  $response
169
     * @return bool
170
     */
171
    public function succeed($response)
172
    {
173
        return $this->code($response) === 0;
174
    }
175
176
    /**
177
     * Get the code of Xinge response.
178
     *
179
     * @param  mixed  $response
180
     * @return int
181
     */
182
    public function code($response)
183
    {
184
        return is_array($response) && isset($response['ret_code']) ? $response['ret_code'] : -999999;
185
    }
186
187
    /**
188
     * Get the error message of Xinge response.
189
     *
190
     * @param  mixed  $response
191
     * @return string|null
192
     */
193
    public function message($response)
194
    {
195
        if (is_array($response)) {
196
            return array_get($response, 'err_msg');
197
        }
198
    }
199
200
    /**
201
     * Get the result data of Xinge response.
202
     *
203
     * @param  mixed  $response
204
     * @return mixed
205
     */
206
    public function result($response, $key = null)
207
    {
208
        if (is_array($response)) {
209
            return array_get($response, $key ? "result.{$key}" : 'result');
210
        }
211
    }
212
213
    /**
214
     * Encode the custom data.
215
     *
216
     * @param  mixed  $data
217
     * @return array|null
218
     */
219
    public function encodeCustomData($data)
220
    {
221
        if (! empty($data)) {
222
            return [$this->customKey => $data];
223
        }
224
    }
225
226
    /**
227
     * Get Xinge account for the given user.
228
     *
229
     * @param  mixed  $user
230
     * @return string
231
     */
232
    public function accountForUser($user)
233
    {
234
        if ($this->accountPrefix && is_string($user) && starts_with($user, $this->accountPrefix)) {
235
            return $user;
236
        }
237
238 View Code Duplication
        if (is_object($user)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
239
            $user = $user->id;
240
        } elseif (is_array($user)) {
241
            $user = $user['id'];
242
        }
243
244
        return $this->accountPrefix.$user;
245
    }
246
247
    /**
248
     * Creates a new MessageIOS instance.
249
     *
250
     * @param  string  $alert
251
     * @param  mixed  $custom
252
     * @param  int  $badge
253
     * @param  string  $sound
254
     * @return \ElfSundae\XgPush\MessageIOS
255
     */
256
    public function createIOSMessage($alert = '', $custom = null, $badge = 1, $sound = 'default')
257
    {
258
        $message = new MessageIOS();
259
        $message->setAlert($alert);
260
        if ($customData = $this->encodeCustomData($custom)) {
261
            $message->setCustom($customData);
262
        }
263
        if (is_numeric($badge) && $badge >= 0) {
264
            $message->setBadge($badge);
265
        }
266
        if ($sound) {
267
            $message->setSound($sound);
268
        }
269
270
        return $message;
271
    }
272
273
    /**
274
     * Create a new Message instance.
275
     *
276
     * @param  string  $content
277
     * @param  mixed  $custom
278
     * @param  string  $title
279
     * @param  int  $type
280
     * @return \ElfSundae\XgPush\Message
281
     */
282
    public function createAndroidMessage($content = '', $custom = null, $title = null, $type = Message::TYPE_NOTIFICATION)
283
    {
284
        $message = new Message();
285
        $message->setTitle($title ?: config('app.name'));
286
        $message->setContent($content);
287
        if ($customData = $this->encodeCustomData($custom)) {
288
            $message->setCustom($customData);
289
        }
290
        $message->setType($type);
291
        $message->setStyle(new Style(0, 1, 1, 1, 0));
292
        $action = new ClickAction();
293
        $action->setActionType(ClickAction::TYPE_ACTIVITY);
294
        $message->setAction($action);
295
296
        return $message;
297
    }
298
299
    /**
300
     * Push message to a device.
301
     *
302
     * @param  string  $deviceToken
303
     * @param  \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS  $message
304
     * @return array
305
     */
306
    public function toDevice($deviceToken, $message)
307
    {
308
        return $this->xinge->PushSingleDevice($deviceToken, $message, $this->environment);
309
    }
310
311
    /**
312
     * Push message to all devices.
313
     *
314
     * @param  \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS  $message
315
     * @return array
316
     */
317
    public function toAllDevices($message)
318
    {
319
        return $this->xinge->PushAllDevices(0, $message, $this->environment);
320
    }
321
322
    /**
323
     * Push message to an user.
324
     *
325
     * @param  mixed  $user
326
     * @param  \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS  $message
327
     * @return array
328
     */
329
    public function toUser($user, $message)
330
    {
331
        return $this->xinge->PushSingleAccount(0, $this->accountForUser($user), $message, $this->environment);
332
    }
333
334
    /**
335
     * Push message to multi users.
336
     *
337
     * @warning 用户数限制 100 个。
338
     *
339
     * @param  string[]  $users
340
     * @param  \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS  $message
341
     * @return array
342
     */
343
    public function toUsersList($users, $message)
344
    {
345
        $accounts = array_map([$this, 'accountForUser'], (array) $users);
346
347
        return $this->xinge->PushAccountList(0, $accounts, $message, $this->environment);
348
    }
349
350
    /**
351
     * Push message to tagged devices.
352
     *
353
     * @param  string|string[]  $tags
354
     * @param  \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS  $message
355
     * @return array
356
     */
357
    public function toTags($tags, $message, $tagsOperation = 'OR')
358
    {
359
        return $this->xinge->PushTags(0, (array) $tags, strtoupper($tagsOperation), $message, $this->environment);
360
    }
361
362
    /**
363
     * Create a batch push.
364
     *
365
     * @param  \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS  $message
366
     * @return string|null
367
     */
368
    public function createBatch($message)
369
    {
370
        return $this->result($this->xinge->CreateMultipush($message, $this->environment), 'push_id');
371
    }
372
373
    /**
374
     * Batch pushing to a list of users.
375
     *
376
     * @warning 用户数限制 1000 个。
377
     *
378
     * @param  int|string  $pushId
379
     * @param  string|string[] $users
380
     * @return array
381
     */
382
    public function batchToUsers($pushId, $users)
383
    {
384
        $accounts = array_map([$this, 'accountForUser'], (array) $users);
385
386
        return $this->xinge->PushAccountListMultiple($pushId, $accounts);
387
    }
388
389
    /**
390
     * Batch pushing to a list of devices.
391
     *
392
     * @param  int|string  $pushId
393
     * @param  string|string[]  $devices
394
     * @return array
395
     */
396
    public function batchToDevices($pushId, $devices)
397
    {
398
        return $this->xinge->PushDeviceListMultiple($pushId, (array) $devices);
399
    }
400
401
    /**
402
     * Query all device tokens for the given user.
403
     *
404
     * @param  mixed  $user
405
     * @return string[]|null
406
     */
407
    public function queryDeviceTokensForUser($user)
408
    {
409
        return $this->result($this->xinge->QueryTokensOfAccount($this->accountForUser($user)), 'tokens');
410
    }
411
412
    /**
413
     * Query all tags for the given device token.
414
     *
415
     * @param  string  $deviceToken
416
     * @return string[]|null
417
     */
418
    public function queryTagsForDeviceToken($deviceToken)
419
    {
420
        return $this->result($this->xinge->QueryTokenTags($deviceToken), 'tags');
421
    }
422
423
    /**
424
     * Query all tags for the given user.
425
     *
426
     * @param  mixed  $user
427
     * @param  array  &$deviceTokens
428
     * @return array|null
429
     */
430
    public function queryTagsForUser($user, &$deviceTokens = null)
431
    {
432
        $deviceTokens = $this->queryDeviceTokensForUser($user);
433
434
        if (is_array($deviceTokens)) {
435
            $result = [];
436
            foreach ($deviceTokens as $token) {
437
                $result[$token] = $this->queryTagsForDeviceToken($token) ?: [];
438
            }
439
440
            return $result;
441
        }
442
    }
443
444
    /**
445
     * Dynamically handle calls to the XingeApp instance.
446
     *
447
     * @param  string  $method
448
     * @param  array   $parameters
449
     * @return mixed
450
     */
451
    public function __call($method, $parameters)
452
    {
453
        return call_user_func_array([$this->xinge, $method], $parameters);
454
    }
455
}
456