Completed
Push — master ( eed316...671ef2 )
by Elf
06:38
created

XgPusher::createIOSMessage()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 8
nop 4
dl 0
loc 16
ccs 0
cts 10
cp 0
crap 30
rs 8.8571
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
     * Query all device tokens for the given user.
301
     *
302
     * @param  mixed  $user
303
     * @return string[]|null
304
     */
305
    public function queryDeviceTokensForUser($user)
306
    {
307
        return $this->result(
308
            $this->xinge->QueryTokensOfAccount($this->accountForUser($user)),
309
            'tokens'
310
        );
311
    }
312
313
    /**
314
     * Query all tags for the given device token.
315
     *
316
     * @param  string  $deviceToken
317
     * @return string[]|null
318
     */
319
    public function queryTagsForDeviceToken($deviceToken)
320
    {
321
        return $this->result(
322
            $this->xinge->QueryTokenTags($deviceToken),
323
            'tags'
324
        );
325
    }
326
327
    /**
328
     * Query all tags for the given user.
329
     *
330
     * @param  mixed  $user
331
     * @param  array  &$deviceTokens
332
     * @return array|null
333
     */
334
    public function queryTagsForUser($user, &$deviceTokens = null)
335
    {
336
        $deviceTokens = $this->queryDeviceTokensForUser($user);
337
338
        if (is_array($deviceTokens)) {
339
            $result = [];
340
            foreach ($deviceTokens as $token) {
341
                if ($tags = $this->queryTagsForDeviceToken($token)) {
342
                    $result[$token] = $tags;
343
                }
344
            }
345
346
            return $result;
347
        }
348
    }
349
350
    /**
351
     * Push message to a device.
352
     *
353
     * @param  string  $deviceToken
354
     * @param  \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS  $message
355
     * @return array
356
     */
357
    public function toDevice($deviceToken, $message)
358
    {
359
        return $this->xinge->PushSingleDevice($deviceToken, $message, $this->environment);
360
    }
361
362
    /**
363
     * Push message to an user.
364
     *
365
     * @param  mixed  $user
366
     * @param  \ElfSundae\XgPush\Message|\ElfSundae\XgPush\MessageIOS  $message
367
     * @return array
368
     */
369
    public function toUser($user, $message)
370
    {
371
        return $this->xinge->PushSingleAccount(0, $this->accountForUser($user), $message, $this->environment);
372
    }
373
374
    /**
375
     * Dynamically handle calls to the XingeApp instance.
376
     *
377
     * @param  string  $method
378
     * @param  array   $parameters
379
     * @return mixed
380
     */
381
    public function __call($method, $parameters)
382
    {
383
        return call_user_func_array([$this->xinge, $method], $parameters);
384
    }
385
}
386