Client   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Test Coverage

Coverage 95.24%

Importance

Changes 0
Metric Value
eloc 37
dl 0
loc 198
ccs 40
cts 42
cp 0.9524
rs 10
c 0
b 0
f 0
wmc 18

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getTicket() 0 21 4
A configSignature() 0 12 4
A dictionaryOrderSignature() 0 7 1
A getAgentId() 0 3 1
A getUrl() 0 7 2
A getConfigArray() 0 3 1
A buildConfig() 0 5 2
A getTicketSignature() 0 3 1
A setUrl() 0 5 1
A getAppId() 0 3 1
1
<?php
2
3
/*
4
 * This file is part of the overtrue/wechat.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace EasyWeChat\BasicService\Jssdk;
13
14
use EasyWeChat\Kernel\BaseClient;
15
use EasyWeChat\Kernel\Exceptions\RuntimeException;
16
use EasyWeChat\Kernel\Support;
17
use EasyWeChat\Kernel\Traits\InteractsWithCache;
18
19
/**
20
 * Class Client.
21
 *
22
 * @author overtrue <[email protected]>
23
 */
24
class Client extends BaseClient
25
{
26
    use InteractsWithCache;
27
28
    /**
29
     * @var string
30
     */
31
    protected $ticketEndpoint = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket';
32
33
    /**
34
     * Current URI.
35
     *
36
     * @var string
37
     */
38
    protected $url;
39
40
    /**
41
     * Get config json for jsapi.
42
     *
43
     * @param array       $jsApiList
44
     * @param bool        $debug
45
     * @param bool        $beta
46
     * @param bool        $json
47
     * @param array       $openTagList
48
     * @param string|null $url
49
     *
50
     * @return array|string
51
     *
52
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
53
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
54
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
55
     * @throws \Psr\SimpleCache\InvalidArgumentException
56
     * @throws \GuzzleHttp\Exception\GuzzleException
57
     */
58 1
    public function buildConfig(array $jsApiList, bool $debug = false, bool $beta = false, bool $json = true, array $openTagList = [], string $url = null)
59
    {
60 1
        $config = array_merge(compact('debug', 'beta', 'jsApiList', 'openTagList'), $this->configSignature($url));
61
62 1
        return $json ? json_encode($config) : $config;
63
    }
64
65
    /**
66
     * Return jsapi config as a PHP array.
67
     *
68
     * @param array       $apis
69
     * @param bool        $debug
70
     * @param bool        $beta
71
     * @param array       $openTagList
72
     * @param string|null $url
73
     *
74
     * @return array|string
75
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
76
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
77
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
78
     * @throws \Psr\SimpleCache\InvalidArgumentException
79
     * @throws \GuzzleHttp\Exception\GuzzleException
80
     */
81 1
    public function getConfigArray(array $apis, bool $debug = false, bool $beta = false, array $openTagList = [], string $url = null)
82
    {
83 1
        return $this->buildConfig($apis, $debug, $beta, false, $openTagList, $url);
84
    }
85
86
    /**
87
     * Get js ticket.
88
     *
89
     * @param bool   $refresh
90
     * @param string $type
91
     *
92
     * @return array
93
     *
94
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
95
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
96
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
97
     * @throws \GuzzleHttp\Exception\GuzzleException
98
     * @throws \Psr\SimpleCache\InvalidArgumentException
99
     */
100 2
    public function getTicket(bool $refresh = false, string $type = 'jsapi'): array
101
    {
102 2
        $cacheKey = sprintf('easywechat.basic_service.jssdk.ticket.%s.%s', $type, $this->getAppId());
103
104 2
        if (!$refresh && $this->getCache()->has($cacheKey)) {
105 1
            return $this->getCache()->get($cacheKey);
106
        }
107
108
        /** @var array<string, mixed> $result */
109 2
        $result = $this->castResponseToType(
110 2
            $this->requestRaw($this->ticketEndpoint, 'GET', ['query' => ['type' => $type]]),
111 2
            'array'
112
        );
113
114 2
        $this->getCache()->set($cacheKey, $result, $result['expires_in'] - 500);
115
116 2
        if (!$this->getCache()->has($cacheKey)) {
117 1
            throw new RuntimeException('Failed to cache jssdk ticket.');
118
        }
119
120 2
        return $result;
121
    }
122
123
    /**
124
     * Build signature.
125
     *
126
     * @param string|null $url
127
     * @param string|null $nonce
128
     * @param null        $timestamp
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $timestamp is correct as it would always require null to be passed?
Loading history...
129
     *
130
     * @return array
131
     *
132
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
133
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
134
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
135
     * @throws \GuzzleHttp\Exception\GuzzleException
136
     * @throws \Psr\SimpleCache\InvalidArgumentException
137
     */
138 1
    protected function configSignature(string $url = null, string $nonce = null, $timestamp = null): array
139
    {
140 1
        $url = $url ?: $this->getUrl();
141 1
        $nonce = $nonce ?: Support\Str::quickRandom(10);
142 1
        $timestamp = $timestamp ?: time();
0 ignored issues
show
introduced by
$timestamp is of type null, thus it always evaluated to false.
Loading history...
143
144
        return [
145 1
            'appId' => $this->getAppId(),
146 1
            'nonceStr' => $nonce,
147 1
            'timestamp' => $timestamp,
148 1
            'url' => $url,
149 1
            'signature' => $this->getTicketSignature($this->getTicket()['ticket'], $nonce, $timestamp, $url),
150
        ];
151
    }
152
153
    /**
154
     * Sign the params.
155
     *
156
     * @param string $ticket
157
     * @param string $nonce
158
     * @param int    $timestamp
159
     * @param string $url
160
     *
161
     * @return string
162
     */
163 2
    public function getTicketSignature($ticket, $nonce, $timestamp, $url): string
164
    {
165 2
        return sha1(sprintf('jsapi_ticket=%s&noncestr=%s&timestamp=%s&url=%s', $ticket, $nonce, $timestamp, $url));
166
    }
167
168
    /**
169
     * @return string
170
     */
171 1
    public function dictionaryOrderSignature()
172
    {
173 1
        $params = func_get_args();
174
175 1
        sort($params, SORT_STRING);
176
177 1
        return sha1(implode('', $params));
178
    }
179
180
    /**
181
     * Set current url.
182
     *
183
     * @param string $url
184
     *
185
     * @return $this
186
     */
187 2
    public function setUrl(string $url)
188
    {
189 2
        $this->url = $url;
190
191 2
        return $this;
192
    }
193
194
    /**
195
     * Get current url.
196
     *
197
     * @return string
198
     */
199 2
    public function getUrl(): string
200
    {
201 2
        if ($this->url) {
202 2
            return $this->url;
203
        }
204
205 1
        return Support\current_url();
0 ignored issues
show
Bug introduced by
The function current_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

205
        return /** @scrutinizer ignore-call */ Support\current_url();
Loading history...
206
    }
207
208
    /**
209
     * @return string
210
     */
211 3
    protected function getAppId()
212
    {
213 3
        return $this->app['config']->get('app_id');
214
    }
215
216
    /**
217
     * @return string
218
     */
219
    protected function getAgentId()
220
    {
221
        return $this->app['config']->get('agent_id');
222
    }
223
}
224