This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace EntWeChat\Card; |
||
4 | |||
5 | use Doctrine\Common\Cache\Cache; |
||
6 | use Doctrine\Common\Cache\FilesystemCache; |
||
7 | use EntWeChat\Core\AbstractAPI; |
||
8 | use EntWeChat\Support\Arr; |
||
9 | use Psr\Http\Message\ResponseInterface; |
||
10 | |||
11 | class Card extends AbstractAPI |
||
12 | { |
||
13 | /** |
||
14 | * Cache. |
||
15 | * |
||
16 | * @var Cache |
||
17 | */ |
||
18 | protected $cache; |
||
19 | |||
20 | /** |
||
21 | * Ticket cache key. |
||
22 | * |
||
23 | * @var string |
||
24 | */ |
||
25 | protected $ticketCacheKey; |
||
26 | |||
27 | /** |
||
28 | * Ticket cache prefix. |
||
29 | * |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $ticketCachePrefix = 'entwechat.card_api_ticket.'; |
||
33 | |||
34 | const API_CREATE_CARD = 'https://qyapi.weixin.qq.com/cgi-bin/card/create'; |
||
35 | const API_CREATE_QRCODE = 'https://qyapi.weixin.qq.com/cgi-bin/card/qrcode/create'; |
||
36 | const API_SHOW_QRCODE = 'https://mp.weixin.qq.com/cgi-bin/showqrcode'; |
||
37 | const API_GET_CARD_TICKET = 'https://qyapi.weixin.qq.com/cgi-bin/ticket/get'; |
||
38 | const API_GET_HTML = 'https://qyapi.weixin.qq.com/cgi-bin/card/mpnews/gethtml'; |
||
39 | const API_GET_CODE = 'https://qyapi.weixin.qq.com/cgi-bin/card/code/get'; |
||
40 | const API_CONSUME_CARD = 'https://qyapi.weixin.qq.com/cgi-bin/card/code/consume'; |
||
41 | const API_GET_CARD = 'https://qyapi.weixin.qq.com/cgi-bin/card/get'; |
||
42 | const API_LIST_CARD = 'https://qyapi.weixin.qq.com/cgi-bin/card/batchget'; |
||
43 | const API_MODIFY_STOCK = 'https://qyapi.weixin.qq.com/cgi-bin/card/modifystock'; |
||
44 | const API_DELETE_CARD = 'https://qyapi.weixin.qq.com/cgi-bin/card/delete'; |
||
45 | |||
46 | // 卡券类型 |
||
47 | const TYPE_GENERAL_COUPON = 'GENERAL_COUPON'; // 通用券 |
||
48 | const TYPE_GROUPON = 'GROUPON'; // 团购券 |
||
49 | const TYPE_DISCOUNT = 'DISCOUNT'; // 折扣券 |
||
50 | const TYPE_GIFT = 'GIFT'; // 礼品券 |
||
51 | const TYPE_CASH = 'CASH'; // 代金券 |
||
52 | |||
53 | // 卡券状态 |
||
54 | const CARD_STATUS_NOT_VERIFY = 'CARD_STATUS_NOT_VERIFY'; // 待审核 |
||
55 | const CARD_STATUS_VERIFY_FAIL = 'CARD_STATUS_VERIFY_FAIL'; // 审核失败 |
||
56 | const CARD_STATUS_VERIFY_OK = 'CARD_STATUS_VERIFY_OK'; // 通过审核 |
||
57 | const CARD_STATUS_USER_DELETE = 'CARD_STATUS_USER_DELETE'; // 卡券被商户删除 |
||
58 | const CARD_STATUS_USER_DISPATCH = 'CARD_STATUS_USER_DISPATCH'; // 在公众平台投放过的卡券 |
||
59 | |||
60 | /** |
||
61 | * 创建卡券. |
||
62 | * |
||
63 | * @param string $cardType |
||
64 | * @param array $baseInfo |
||
65 | * @param array $especial |
||
66 | * @param array $advancedInfo |
||
67 | * |
||
68 | * @return \EntWeChat\Support\Collection |
||
69 | */ |
||
70 | public function create($cardType = 'member_card', array $baseInfo = [], array $especial = [], array $advancedInfo = []) |
||
71 | { |
||
72 | $params = [ |
||
73 | 'card' => [ |
||
74 | 'card_type' => strtoupper($cardType), |
||
75 | strtolower($cardType) => array_merge(['base_info' => $baseInfo], $especial, ['advanced_info' => $advancedInfo]), |
||
76 | ], |
||
77 | ]; |
||
78 | |||
79 | return $this->parseJSON('json', [self::API_CREATE_CARD, $params]); |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * 创建二维码. |
||
84 | * |
||
85 | * @param array $cards |
||
86 | * |
||
87 | * @return \EntWeChat\Support\Collection |
||
88 | */ |
||
89 | public function QRCode(array $cards = []) |
||
90 | { |
||
91 | return $this->parseJSON('json', [self::API_CREATE_QRCODE, $cards]); |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * ticket 换取二维码图片. |
||
96 | * |
||
97 | * @param string $ticket |
||
98 | * |
||
99 | * @return array |
||
100 | */ |
||
101 | public function showQRCode($ticket = null) |
||
102 | { |
||
103 | $params = [ |
||
104 | 'ticket' => $ticket, |
||
105 | ]; |
||
106 | |||
107 | $http = $this->getHttp(); |
||
108 | |||
109 | /** @var ResponseInterface $response */ |
||
110 | $response = $http->get(self::API_SHOW_QRCODE, $params); |
||
111 | |||
112 | return [ |
||
113 | 'status' => $response->getStatusCode(), |
||
114 | 'reason' => $response->getReasonPhrase(), |
||
115 | 'headers' => $response->getHeaders(), |
||
116 | 'body' => strval($response->getBody()), |
||
117 | 'url' => self::API_SHOW_QRCODE.'?'.http_build_query($params), |
||
118 | ]; |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * 通过ticket换取二维码 链接. |
||
123 | * |
||
124 | * @param string $ticket |
||
125 | * |
||
126 | * @return string |
||
127 | */ |
||
128 | public function getQRCodeUrl($ticket) |
||
129 | { |
||
130 | return self::API_SHOW_QRCODE.'?ticket='.$ticket; |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * 获取 卡券 Api_ticket. |
||
135 | * |
||
136 | * @param bool $refresh 是否强制刷新 |
||
137 | * |
||
138 | * @return string $apiTicket |
||
139 | */ |
||
140 | public function getAPITicket($refresh = false) |
||
141 | { |
||
142 | $key = $this->getTicketCacheKey(); |
||
143 | |||
144 | $ticket = $this->getCache()->fetch($key); |
||
145 | |||
146 | if (!$ticket || $refresh) { |
||
147 | $result = $this->parseJSON('get', [self::API_GET_CARD_TICKET, ['type' => 'wx_card']]); |
||
148 | |||
149 | $this->getCache()->save($key, $result['ticket'], $result['expires_in'] - 500); |
||
150 | |||
151 | return $result['ticket']; |
||
152 | } |
||
153 | |||
154 | return $ticket; |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * 微信卡券:JSAPI 卡券发放. |
||
159 | * |
||
160 | * @param array $cards |
||
161 | * |
||
162 | * @return string |
||
163 | */ |
||
164 | public function jsConfigForAssign(array $cards) |
||
165 | { |
||
166 | return json_encode(array_map(function ($card) { |
||
167 | return $this->attachExtension($card['card_id'], $card); |
||
168 | }, $cards)); |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * 生成 js添加到卡包 需要的 card_list 项. |
||
173 | * |
||
174 | * @param string $cardId |
||
175 | * @param array $extension |
||
176 | * |
||
177 | * @return string |
||
178 | */ |
||
179 | public function attachExtension($cardId, array $extension = []) |
||
180 | { |
||
181 | $timestamp = time(); |
||
182 | $ext = [ |
||
183 | 'code' => Arr::get($extension, 'code'), |
||
184 | 'openid' => Arr::get($extension, 'openid', Arr::get($extension, 'open_id')), |
||
185 | 'timestamp' => $timestamp, |
||
186 | 'outer_id' => Arr::get($extension, 'outer_id'), |
||
187 | 'balance' => Arr::get($extension, 'balance'), |
||
188 | 'fixed_begintimestamp' => Arr::get($extension, 'fixed_begintimestamp'), |
||
189 | 'outer_str' => Arr::get($extension, 'outer_str'), |
||
190 | ]; |
||
191 | $ext['signature'] = $this->getSignature( |
||
192 | $this->getAPITicket(), |
||
193 | $timestamp, |
||
194 | $cardId, |
||
195 | $ext['code'], |
||
196 | $ext['openid'], |
||
197 | $ext['balance'] |
||
198 | ); |
||
199 | |||
200 | return [ |
||
201 | 'cardId' => $cardId, |
||
202 | 'cardExt' => json_encode($ext), |
||
203 | ]; |
||
204 | } |
||
205 | |||
206 | /** |
||
207 | * 生成签名. |
||
208 | * |
||
209 | * @return string |
||
210 | */ |
||
211 | public function getSignature() |
||
212 | { |
||
213 | $params = func_get_args(); |
||
214 | sort($params, SORT_STRING); |
||
215 | |||
216 | return sha1(implode($params)); |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * 核查code接口. |
||
221 | * |
||
222 | * @param string $cardId |
||
223 | * @param array $code |
||
224 | * |
||
225 | * @return \EntWeChat\Support\Collection |
||
226 | */ |
||
227 | View Code Duplication | public function checkCode($cardId, $code) |
|
0 ignored issues
–
show
|
|||
228 | { |
||
229 | $params = [ |
||
230 | 'card_id' => $cardId, |
||
231 | 'code' => $code, |
||
232 | ]; |
||
233 | |||
234 | return $this->parseJSON('json', [self::API_CHECK_CODE, $params]); |
||
235 | } |
||
236 | |||
237 | /** |
||
238 | * 查询Code接口. |
||
239 | * |
||
240 | * @param string $code |
||
241 | * @param bool $checkConsume |
||
242 | * @param string $cardId |
||
243 | * |
||
244 | * @return \EntWeChat\Support\Collection |
||
245 | */ |
||
246 | View Code Duplication | public function getCode($code, $checkConsume, $cardId) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
247 | { |
||
248 | $params = [ |
||
249 | 'code' => $code, |
||
250 | 'check_consume' => $checkConsume, |
||
251 | 'card_id' => $cardId, |
||
252 | ]; |
||
253 | |||
254 | return $this->parseJSON('json', [self::API_GET_CODE, $params]); |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * 核销Code接口. |
||
259 | * |
||
260 | * @param string $code |
||
261 | * @param string $cardId |
||
262 | * |
||
263 | * @return \EntWeChat\Support\Collection |
||
264 | */ |
||
265 | public function consume($code, $cardId = null) |
||
266 | { |
||
267 | if (strlen($code) === 28 && $cardId && strlen($cardId) !== 28) { |
||
0 ignored issues
–
show
The expression
$cardId of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
268 | list($code, $cardId) = [$cardId, $code]; |
||
269 | } |
||
270 | |||
271 | $params = [ |
||
272 | 'code' => $code, |
||
273 | ]; |
||
274 | |||
275 | if ($cardId) { |
||
0 ignored issues
–
show
The expression
$cardId of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
276 | $params['card_id'] = $cardId; |
||
277 | } |
||
278 | |||
279 | return $this->parseJSON('json', [self::API_CONSUME_CARD, $params]); |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * 图文消息群发卡券. |
||
284 | * |
||
285 | * @param string $cardId |
||
286 | * |
||
287 | * @return \EntWeChat\Support\Collection |
||
288 | */ |
||
289 | View Code Duplication | public function getHtml($cardId) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
290 | { |
||
291 | $params = [ |
||
292 | 'card_id' => $cardId, |
||
293 | ]; |
||
294 | |||
295 | return $this->parseJSON('json', [self::API_GET_HTML, $params]); |
||
296 | } |
||
297 | |||
298 | /** |
||
299 | * 查看卡券详情. |
||
300 | * |
||
301 | * @param string $cardId |
||
302 | * |
||
303 | * @return \EntWeChat\Support\Collection |
||
304 | */ |
||
305 | View Code Duplication | public function getCard($cardId) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
306 | { |
||
307 | $params = [ |
||
308 | 'card_id' => $cardId, |
||
309 | ]; |
||
310 | |||
311 | return $this->parseJSON('json', [self::API_GET_CARD, $params]); |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * 批量查询卡列表. |
||
316 | * |
||
317 | * @param int $offset |
||
318 | * @param int $count |
||
319 | * @param string $statusList |
||
320 | * |
||
321 | * @return \EntWeChat\Support\Collection |
||
322 | */ |
||
323 | View Code Duplication | public function lists($offset = 0, $count = 10, $statusList = 'CARD_STATUS_VERIFY_OK') |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
324 | { |
||
325 | $params = [ |
||
326 | 'offset' => $offset, |
||
327 | 'count' => $count, |
||
328 | 'status_list' => $statusList, |
||
329 | ]; |
||
330 | |||
331 | return $this->parseJSON('json', [self::API_LIST_CARD, $params]); |
||
332 | } |
||
333 | |||
334 | /** |
||
335 | * 增加库存. |
||
336 | * |
||
337 | * @param string $cardId |
||
338 | * @param int $amount |
||
339 | * |
||
340 | * @return \EntWeChat\Support\Collection |
||
341 | */ |
||
342 | public function increaseStock($cardId, $amount) |
||
343 | { |
||
344 | return $this->updateStock($cardId, $amount, 'increase'); |
||
345 | } |
||
346 | |||
347 | /** |
||
348 | * 减少库存. |
||
349 | * |
||
350 | * @param string $cardId |
||
351 | * @param int $amount |
||
352 | * |
||
353 | * @return \EntWeChat\Support\Collection |
||
354 | */ |
||
355 | public function reduceStock($cardId, $amount) |
||
356 | { |
||
357 | return $this->updateStock($cardId, $amount, 'reduce'); |
||
358 | } |
||
359 | |||
360 | /** |
||
361 | * 修改库存接口. |
||
362 | * |
||
363 | * @param string $cardId |
||
364 | * @param int $amount |
||
365 | * @param string $action |
||
366 | * |
||
367 | * @return \EntWeChat\Support\Collection |
||
368 | */ |
||
369 | protected function updateStock($cardId, $amount, $action = 'increase') |
||
370 | { |
||
371 | $key = $action === 'increase' ? 'increase_stock_value' : 'reduce_stock_value'; |
||
372 | $params = [ |
||
373 | 'card_id' => $cardId, |
||
374 | $key => abs($amount), |
||
375 | ]; |
||
376 | |||
377 | return $this->parseJSON('json', [self::API_MODIFY_STOCK, $params]); |
||
378 | } |
||
379 | |||
380 | /** |
||
381 | * 删除卡券接口. |
||
382 | * |
||
383 | * @param string $cardId |
||
384 | * |
||
385 | * @return \EntWeChat\Support\Collection |
||
386 | */ |
||
387 | View Code Duplication | public function delete($cardId) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
388 | { |
||
389 | $params = [ |
||
390 | 'card_id' => $cardId, |
||
391 | ]; |
||
392 | |||
393 | return $this->parseJSON('json', [self::API_DELETE_CARD, $params]); |
||
394 | } |
||
395 | |||
396 | /** |
||
397 | * Set cache manager. |
||
398 | * |
||
399 | * @param \Doctrine\Common\Cache\Cache $cache |
||
400 | * |
||
401 | * @return $this |
||
402 | */ |
||
403 | public function setCache(Cache $cache) |
||
404 | { |
||
405 | $this->cache = $cache; |
||
406 | |||
407 | return $this; |
||
408 | } |
||
409 | |||
410 | /** |
||
411 | * Return cache manager. |
||
412 | * |
||
413 | * @return \Doctrine\Common\Cache\Cache |
||
414 | */ |
||
415 | public function getCache() |
||
416 | { |
||
417 | return $this->cache ?: $this->cache = new FilesystemCache(sys_get_temp_dir()); |
||
418 | } |
||
419 | |||
420 | /** |
||
421 | * Set Api_ticket cache prifix. |
||
422 | * |
||
423 | * @param string $prefix |
||
424 | * |
||
425 | * @return $this |
||
426 | */ |
||
427 | public function setTicketCachePrefix($prefix) |
||
428 | { |
||
429 | $this->ticketCachePrefix = $prefix; |
||
430 | |||
431 | return $this; |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * Set Api_ticket cache key. |
||
436 | * |
||
437 | * @param string $cacheKey |
||
438 | * |
||
439 | * @return $this |
||
440 | */ |
||
441 | public function setTicketCacheKey($cacheKey) |
||
442 | { |
||
443 | $this->ticketCacheKey = $cacheKey; |
||
444 | |||
445 | return $this; |
||
446 | } |
||
447 | |||
448 | /** |
||
449 | * Get ApiTicket token cache key. |
||
450 | * |
||
451 | * @return string |
||
452 | */ |
||
453 | public function getTicketCacheKey() |
||
454 | { |
||
455 | if (is_null($this->ticketCacheKey)) { |
||
456 | return $this->ticketCachePrefix.$this->getAccessToken()->getFingerprint(); |
||
457 | } |
||
458 | |||
459 | return $this->ticketCacheKey; |
||
460 | } |
||
461 | |||
462 | /** |
||
463 | * Set current url. |
||
464 | * |
||
465 | * @param string $url |
||
466 | * |
||
467 | * @return Card |
||
468 | */ |
||
469 | public function setUrl($url) |
||
470 | { |
||
471 | $this->url = $url; |
||
0 ignored issues
–
show
The property
url does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
472 | |||
473 | return $this; |
||
474 | } |
||
475 | } |
||
476 |
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.