Passed
Pull Request — master (#40)
by frey
03:09
created

CDN   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 332
Duplicated Lines 0 %

Test Coverage

Coverage 46.3%

Importance

Changes 5
Bugs 0 Features 2
Metric Value
eloc 83
c 5
b 0
f 2
dl 0
loc 332
ccs 50
cts 108
cp 0.463
rs 9.1199
wmc 41

23 Methods

Rating   Name   Duplication   Size   Complexity  
A signatureA() 0 13 5
A getMethod() 0 3 1
A handle() 0 3 1
A signature() 0 3 1
A signatureD() 0 11 4
A buildFormParams() 0 11 1
A getHttpClient() 0 4 1
A request() 0 11 1
A refreshUrl() 0 5 2
A normalize() 0 3 1
A addCommonParams() 0 8 1
A addSignature() 0 5 1
A signatureB() 0 15 3
A pushOverseaUrl() 0 5 2
A getConfig() 0 3 1
A getSignature() 0 7 1
A getCredentials() 0 3 1
A pushUrl() 0 5 2
A signatureC() 0 15 3
A pushUrlV2() 0 5 2
A refreshDir() 0 5 2
A refreshOverseaUrl() 0 5 2
A refreshOverseaDir() 0 5 2

How to fix   Complexity   

Complex Class

Complex classes like CDN often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CDN, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Freyo\Flysystem\QcloudCOSv5\Plugins;
4
5
use League\Flysystem\Plugin\AbstractPlugin;
6
7
class CDN extends AbstractPlugin
8
{
9
    /**
10
     * Get the method name.
11
     *
12
     * @return string
13
     */
14
    public function getMethod()
15
    {
16
        return 'cdn';
17
    }
18
19
    /**
20
     * @return $this
21
     */
22 5
    public function handle()
23
    {
24 5
        return $this;
25
    }
26
27
    /**
28
     * @param string $url
29
     * @param string $key
30
     * @param int    $timestamp
31
     * @param string $signName
32
     * @param string $timeName
33
     *
34
     * @return string
35
     */
36 1
    public function signature($url, $key = null, $timestamp = null, $signName = 'sign', $timeName = 't')
37
    {
38 1
        return $this->signatureD($url, $key, $timestamp, $signName, $timeName);
39
    }
40
41
    /**
42
     * @param string $url
43
     * @param string $key
44
     * @param int    $timestamp
45
     * @param string $random
46
     * @param string $signName
47
     *
48
     * @return string
49
     */
50 1
    public function signatureA($url, $key = null, $timestamp = null, $random = null, $signName = 'sign')
51
    {
52 1
        $key = $key ?: $this->getConfig()->get('cdn_key');
53 1
        $timestamp = $timestamp ?: time();
54 1
        $random = $random ?: sha1(uniqid('', true));
55
56 1
        $parsed = parse_url($url);
57 1
        $hash = md5(sprintf('%s-%s-%s-%s-%s', $parsed['path'], $timestamp, $random, 0, $key));
58 1
        $signature = sprintf('%s-%s-%s-%s', $timestamp, $random, 0, $hash);
59 1
        $query = http_build_query([$signName => $signature]);
60 1
        $separator = empty($parsed['query']) ? '?' : '&';
61
62 1
        return $url.$separator.$query;
63
    }
64
65
    /**
66
     * @param string $url
67
     * @param string $key
68
     * @param int    $timestamp
69
     *
70
     * @return string
71
     */
72 1
    public function signatureB($url, $key = null, $timestamp = null)
73
    {
74 1
        $key = $key ?: $this->getConfig()->get('cdn_key');
75 1
        $timestamp = date('YmdHi', $timestamp ?: time());
76
77 1
        $parsed = parse_url($url);
78 1
        $hash = md5($key.$timestamp.$parsed['path']);
79
80 1
        return sprintf(
81 1
            '%s://%s/%s/%s%s',
82 1
            $parsed['scheme'],
83 1
            $parsed['host'],
84 1
            $timestamp,
85 1
            $hash,
86 1
            $parsed['path']
87 1
        );
88
    }
89
90
    /**
91
     * @param string $url
92
     * @param string $key
93
     * @param int    $timestamp
94
     *
95
     * @return string
96
     */
97 1
    public function signatureC($url, $key = null, $timestamp = null)
98
    {
99 1
        $key = $key ?: $this->getConfig()->get('cdn_key');
100 1
        $timestamp = dechex($timestamp ?: time());
101
102 1
        $parsed = parse_url($url);
103 1
        $hash = md5($key.$parsed['path'].$timestamp);
104
105 1
        return sprintf(
106 1
            '%s://%s/%s/%s%s',
107 1
            $parsed['scheme'],
108 1
            $parsed['host'],
109 1
            $hash,
110 1
            $timestamp,
111 1
            $parsed['path']
112 1
        );
113
    }
114
115
    /**
116
     * @param string $url
117
     * @param string $key
118
     * @param int    $timestamp
119
     * @param string $signName
120
     * @param string $timeName
121
     *
122
     * @return string
123
     */
124 2
    public function signatureD($url, $key = null, $timestamp = null, $signName = 'sign', $timeName = 't')
125
    {
126 2
        $key = $key ?: $this->getConfig()->get('cdn_key');
127 2
        $timestamp = dechex($timestamp ?: time());
128
129 2
        $parsed = parse_url($url);
130 2
        $signature = md5($key.$parsed['path'].$timestamp);
131 2
        $query = http_build_query([$signName => $signature, $timeName => $timestamp]);
132 2
        $separator = empty($parsed['query']) ? '?' : '&';
133
134 2
        return $url.$separator.$query;
135
    }
136
137
    /**
138
     * @param $url
139
     *
140
     * @return array
141
     */
142
    public function pushUrl($url)
143
    {
144
        $urls = is_array($url) ? $url : func_get_args();
145
146
        return $this->request($urls, 'urls', 'CdnUrlPusher');
147
    }
148
149
    /**
150
     * @param $url
151
     *
152
     * @return array
153
     */
154
    public function pushOverseaUrl($url)
155
    {
156
        $urls = is_array($url) ? $url : func_get_args();
157
158
        return $this->request($urls, 'urls', 'CdnOverseaPushser');
159
    }
160
161
    /**
162
     * @param $url
163
     *
164
     * @return array
165
     */
166
    public function pushUrlV2($url)
167
    {
168
        $urls = is_array($url) ? $url : func_get_args();
169
170
        return $this->request($urls, 'urls', 'CdnPusherV2');
171
    }
172
173
    /**
174
     * @param $url
175
     *
176
     * @return array
177
     */
178
    public function refreshUrl($url)
179
    {
180
        $urls = is_array($url) ? $url : func_get_args();
181
182
        return $this->request($urls, 'urls', 'RefreshCdnUrl');
183
    }
184
185
    /**
186
     * @param $url
187
     *
188
     * @return array
189
     */
190
    public function refreshOverseaUrl($url)
191
    {
192
        $urls = is_array($url) ? $url : func_get_args();
193
194
        return $this->request($urls, 'urls', 'RefreshCdnOverSeaUrl');
195
    }
196
197
    /**
198
     * @param $dir
199
     *
200
     * @return array
201
     */
202
    public function refreshDir($dir)
203
    {
204
        $dirs = is_array($dir) ? $dir : func_get_args();
205
206
        return $this->request($dirs, 'dirs', 'RefreshCdnDir');
207
    }
208
209
    /**
210
     * @param $dir
211
     *
212
     * @return array
213
     */
214
    public function refreshOverseaDir($dir)
215
    {
216
        $dirs = is_array($dir) ? $dir : func_get_args();
217
218
        return $this->request($dirs, 'dirs', 'RefreshCdnOverSeaDir');
219
    }
220
221
    /**
222
     * @param array  $args
223
     * @param string $key
224
     * @param string $action
225
     *
226
     * @return array
227
     */
228
    protected function request(array $args, $key, $action)
229
    {
230
        $client = $this->getHttpClient();
231
232
        $response = $client->post('/v2/index.php', [
233
            'form_params' => $this->buildFormParams($args, $key, $action),
234
        ]);
235
236
        $contents = $response->getBody()->getContents();
237
238
        return $this->normalize($contents);
239
    }
240
241
    /**
242
     * @return \GuzzleHttp\Client
243
     */
244
    protected function getHttpClient()
245
    {
246
        return new \GuzzleHttp\Client([
247
            'base_uri' => 'https://cdn.api.qcloud.com',
248
        ]);
249
    }
250
251
    /**
252
     * @param array  $values
253
     * @param string $key
254
     * @param string $action
255
     *
256
     * @return array
257
     */
258
    protected function buildFormParams(array $values, $key, $action)
259
    {
260
        $keys = array_map(function ($n) use ($key) {
261
            return sprintf("{$key}.%d", $n);
262
        }, range(0, count($values) - 1));
263
264
        $params = array_combine($keys, $values);
265
266
        $params = $this->addCommonParams($params, $action);
0 ignored issues
show
Bug introduced by
It seems like $params can also be of type false; however, parameter $params of Freyo\Flysystem\QcloudCO...\CDN::addCommonParams() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

266
        $params = $this->addCommonParams(/** @scrutinizer ignore-type */ $params, $action);
Loading history...
267
268
        return $this->addSignature($params);
269
    }
270
271
    /**
272
     * @param array  $params
273
     * @param string $action
274
     *
275
     * @return array
276
     */
277
    protected function addCommonParams(array $params, $action)
278
    {
279
        return array_merge([
280
            'Action'    => $action,
281
            'SecretId'  => $this->getCredentials()['secretId'],
282
            'Timestamp' => time(),
283
            'Nonce'     => rand(1, 65535),
284
        ], $params);
285
    }
286
287
    /**
288
     * @return array
289
     */
290
    protected function getCredentials()
291
    {
292
        return $this->getConfig()->get('credentials');
293
    }
294
295
    /**
296
     * @param array $params
297
     *
298
     * @return array
299
     */
300
    protected function addSignature(array $params)
301
    {
302
        $params['Signature'] = $this->getSignature($params);
303
304
        return $params;
305
    }
306
307
    /**
308
     * @param array $params
309
     *
310
     * @return string
311
     */
312
    protected function getSignature(array $params)
313
    {
314
        ksort($params);
315
316
        $srcStr = 'POSTcdn.api.qcloud.com/v2/index.php?'.urldecode(http_build_query($params));
317
318
        return base64_encode(hash_hmac('sha1', $srcStr, $this->getCredentials()['secretKey'], true));
319
    }
320
321
    /**
322
     * @param string $contents
323
     *
324
     * @throws \InvalidArgumentException if the JSON cannot be decoded.
325
     *
326
     * @return array
327
     */
328
    protected function normalize($contents)
329
    {
330
        return \GuzzleHttp\json_decode($contents, true);
331
    }
332
333
    /**
334
     * @return \League\Flysystem\Config
335
     */
336 5
    protected function getConfig()
337
    {
338 5
        return $this->filesystem->getConfig();
339
    }
340
}
341