Completed
Push — master ( d19868...7842ed )
by Elf
09:36
created

XgPusher::getCustomKey()   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 0
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
use Illuminate\Support\Str;
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 for custom payload.
32
     *
33
     * @var string
34
     */
35
    protected $customKey = 'custom';
36
37
    /**
38
     * Xinge account prefix.
39
     *
40
     * @warning 信鸽不允许使用简单的账号,例如纯数字的id。
41
     *
42
     * @var string
43
     */
44
    protected $accountPrefix = 'user';
45
46
    /**
47
     * Create a new instance.
48
     *
49
     * @param  string  $appKey
50
     * @param  string  $appSecret
51
     * @param  mixed  $environment
52
     * @param  string  $customKey
53
     */
54
    public function __construct($appKey, $appSecret, $environment, $customKey)
55
    {
56
        $this->xinge = new XingeApp($appKey, $appSecret);
57
        $this->setEnvironment($environment);
58
        $this->setCustomKey($customKey);
59
    }
60
61
    /**
62
     * Get the XingeApp instance.
63
     *
64
     * @return \ElfSundae\XgPush\XingeApp
65
     */
66
    public function getXinge()
67
    {
68
        return $this->xinge;
69
    }
70
71
    /**
72
     * Get the app key.
73
     *
74
     * @return string
75
     */
76
    public function getAppKey()
77
    {
78
        return $this->xinge->accessId;
79
    }
80
81
    /**
82
     * Get the app secret.
83
     *
84
     * @return string
85
     */
86
    public function getAppSecret()
87
    {
88
        return $this->xinge->secretKey;
89
    }
90
91
    /**
92
     * Get the pusher environment.
93
     *
94
     * @return int
95
     */
96
    public function getEnvironment()
97
    {
98
        return $this->environment;
99
    }
100
101
    /**
102
     * Set the pusher environment.
103
     *
104
     * @param  mixed  $env
105
     * @return $this
106
     */
107
    public function setEnvironment($env)
108
    {
109
        if (is_string($env)) {
110
            $env = $env == 'production' ? XingeApp::IOSENV_PROD : XingeApp::IOSENV_DEV;
111
        }
112
113
        if (is_numeric($env)) {
114
            $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...
115
        }
116
117
        return $this;
118
    }
119
120
    /**
121
     * Get the key for custom payload.
122
     *
123
     * @return string
124
     */
125
    public function getCustomKey()
126
    {
127
        return $this->customKey;
128
    }
129
130
    /**
131
     * Set the key for custom payload.
132
     *
133
     * @param  string  $key
134
     * @return $this
135
     */
136
    public function setCustomKey($key)
137
    {
138
        if ($key) {
139
            $this->customKey = $key;
140
        }
141
142
        return $this;
143
    }
144
145
    /**
146
     * Get account prefix.
147
     *
148
     * @return string
149
     */
150
    public function getAccountPrefix()
151
    {
152
        return $this->accountPrefix;
153
    }
154
155
    /**
156
     * Set account prefix.
157
     *
158
     * @param  string  $prefix
159
     * @return $this
160
     */
161
    public function setAccountPrefix($prefix)
162
    {
163
        $this->accountPrefix = $prefix;
164
165
        return $this;
166
    }
167
168
    /**
169
     * Determine if the Xinge result is success.
170
     *
171
     * @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
172
     *
173
     * @param  mixed  $result
174
     * @return bool
175
     */
176
    public function succeed($result)
177
    {
178
        return is_array($result) && isset($result['ret_code']) && $result['ret_code'] === 0;
179
    }
180
181
    /**
182
     * Encode the custom data.
183
     *
184
     * @param  mixed  $data
185
     * @return array|null
186
     */
187
    public function encodeCustomData($data)
188
    {
189
        if (!empty($data)) {
190
            return [$this->customKey => $data];
191
        }
192
    }
193
194
    /**
195
     * Get Xinge account for the given user.
196
     *
197
     * @param  mixed  $user
198
     * @return string
199
     */
200
    public function accountForUser($user)
201
    {
202
        if ($this->accountPrefix && is_string($user) && Str::startsWith($user, $this->accountPrefix)) {
203
            return $user;
204
        }
205
206
        return $this->accountPrefix.get_id($user);
207
    }
208
209
    /**
210
     * Creates a MessageIOS instance.
211
     *
212
     * @param  string  $alert
213
     * @param  mixed  $custom
214
     * @param  int  $badge
215
     * @param  string  $sound
216
     * @return \ElfSundae\XgPush\MessageIOS
217
     */
218
    public function createIOSMessage($alert = '', $custom = null, $badge = 1, $sound = 'default')
219
    {
220
        $message = new MessageIOS();
221
        $message->setAlert($alert);
222
        if ($customData = $this->encodeCustomData($custom)) {
223
            $message->setCustom($customData);
224
        }
225
        if (is_numeric($badge) && $badge >= 0) {
226
            $message->setBadge($badge);
227
        }
228
        if (! empty($sound)) {
229
            $message->setSound($sound);
230
        }
231
232
        return $message;
233
    }
234
235
    /**
236
     * Create a Message instance.
237
     *
238
     * @param  string  $content
239
     * @param  mixed  $custom
240
     * @param  string  $title
241
     * @param  int  $type
242
     * @return \ElfSundae\XgPush\Message
243
     */
244
    public function createAndroidMessage($content = '', $custom = null, $title = null, $type = Message::TYPE_NOTIFICATION)
245
    {
246
        $message = new Message();
247
        $message->setTitle($title ?: config('app.name'));
248
        $message->setContent($content);
249
        if ($customData = $this->encodeCustomData($custom)) {
250
            $message->setCustom($customData);
251
        }
252
        $message->setType($type);
253
        //含义:样式编号0,响铃,震动,不可从通知栏清除,不影响先前通知
254
        $message->setStyle(new Style(0, 1, 1, 1, 0));
255
        $action = new ClickAction();
256
        $action->setActionType(ClickAction::TYPE_ACTIVITY);
257
        $message->setAction($action);
258
259
        return $message;
260
    }
261
262
    /**
263
     * Query all device tokens for the given user.
264
     *
265
     * @param  mixed  $user
266
     * @return string[]|null
267
     */
268
    public function queryDeviceTokensForUser($user)
269
    {
270
        $result = $this->xinge->QueryTokensOfAccount($this->accountForUser($user));
271
272
        if ($this->succeed($result)) {
273
            return array_get($result, 'result.tokens', []);
274
        }
275
    }
276
277
    /**
278
     * Query all tags for the given device token.
279
     *
280
     * @param  string  $deviceToken
281
     * @return string[]|null
282
     */
283
    public function queryTagsForDeviceToken($deviceToken)
284
    {
285
        $result = $this->xinge->QueryTokenTags($deviceToken);
286
287
        if ($this->succeed($result)) {
288
            return array_get($result, 'result.tags', []);
289
        }
290
    }
291
292
    /**
293
     * Query all tags for the given user.
294
     *
295
     * @param  mixed  $user
296
     * @param  array  &$deviceTokens
297
     * @return array
298
     */
299
    public function queryTagsForUser($user, &$deviceTokens = null)
300
    {
301
        $deviceTokens = $this->queryDeviceTokensForUser($user);
302
303
        $result = [];
304
        foreach ($deviceTokens as $token) {
0 ignored issues
show
Bug introduced by
The expression $deviceTokens of type array<integer,string>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
305
            if ($tags = $this->queryTagsForDeviceToken($token)) {
306
                $result[$token] = $tags;
307
            }
308
        }
309
310
        return $result;
311
    }
312
313
    /**
314
     * Dynamically handle calls to the XingeApp instance.
315
     *
316
     * @param  string  $method
317
     * @param  array   $parameters
318
     * @return mixed
319
     */
320
    public function __call($method, $parameters)
321
    {
322
        return call_user_func_array([$this->xinge, $method], $parameters);
323
    }
324
}
325