Passed
Push — master ( 5dcae1...4e176d )
by frey
02:33
created

src/Client/Cosapi.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 7 and the first side effect is on line 5.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
namespace Freyo\Flysystem\QcloudCOSv4\Client;
4
5
date_default_timezone_set('PRC');
6
7
class Cosapi
8
{
9
    //计算sign签名的时间参数
10
    const EXPIRED_SECONDS = 180;
11
    //1M
12
    const SLICE_SIZE_1M = 1048576;
13
    //20M 大于20M的文件需要进行分片传输
14
    const MAX_UNSLICE_FILE_SIZE = 20971520;
15
    //失败尝试次数
16
    const MAX_RETRY_TIMES = 3;
17
18
    //HTTP请求超时时间
19
    private static $timeout = 60;
20
    private static $region = 'gz'; // default region is guangzou
21
22
    /**
23
     * 设置HTTP请求超时时间.
24
     *
25
     * @param int $timeout 超时时长
26
     *
27
     * @return bool
28
     */
29
    public static function setTimeout($timeout = 60)
30
    {
31
        if (!is_int($timeout) || $timeout < 0) {
32
            return false;
33
        }
34
35
        self::$timeout = $timeout;
36
37
        return true;
38
    }
39
40
    public static function setRegion($region)
41
    {
42
        self::$region = $region;
43
    }
44
45
    /**
46
     * 上传文件,自动判断文件大小,如果小于20M则使用普通文件上传,大于20M则使用分片上传.
47
     *
48
     * @param string $bucket     bucket名称
49
     * @param string $srcPath    本地文件路径
50
     * @param string $dstPath    上传的文件路径
51
     * @param string $bizAttr    文件属性
52
     * @param string $sliceSize  分片大小(512k,1m,2m,3m),默认:1m
53
     * @param string $insertOnly 同名文件是否覆盖
54
     *
55
     * @return array
56
     */
57 2
    public static function upload($bucket, $srcPath, $dstPath, $bizAttr = null, $sliceSize = null, $insertOnly = null)
58
    {
59 2 View Code Duplication
        if (!file_exists($srcPath)) {
60
            return [
61
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
62
                'message' => 'file '.$srcPath.' not exists',
63
                'data'    => [],
64
            ];
65
        }
66
67 2
        $dstPath = self::normalizerPath($dstPath, false);
68
69
        //文件大于20M则使用分片传输
70 2
        if (filesize($srcPath) < self::MAX_UNSLICE_FILE_SIZE) {
71 2
            return self::uploadFile($bucket, $srcPath, $dstPath, $bizAttr, $insertOnly);
72
        } else {
73
            $sliceSize = self::getSliceSize($sliceSize);
74
75
            return self::uploadBySlicing($bucket, $srcPath, $dstPath, $bizAttr, $sliceSize, $insertOnly);
76
        }
77
    }
78
79
    /**
80
     * 创建目录.
81
     *
82
     * @param string $bucket  bucket名称
83
     * @param string $folder  目录路径
84
     * @param string $bizAttr 目录属性
85
     *
86
     * @return array
87
     */
88 1
    public static function createFolder($bucket, $folder, $bizAttr = null)
89
    {
90 1
        if (!self::isValidPath($folder)) {
91
            return [
92
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
93
                'message' => 'folder '.$folder.' is not a valid folder name',
94
                'data'    => [],
95
            ];
96
        }
97
98 1
        $folder = self::normalizerPath($folder, true);
99 1
        $folder = self::cosUrlEncode($folder);
100 1
        $expired = time() + self::EXPIRED_SECONDS;
101 1
        $url = self::generateResUrl($bucket, $folder);
102 1
        $signature = Auth::createReusableSignature($expired, $bucket);
103
104
        $data = [
105 1
            'op'       => 'create',
106 1
            'biz_attr' => (isset($bizAttr) ? $bizAttr : ''),
107 1
        ];
108
109 1
        $data = json_encode($data);
110
111
        $req = [
112 1
            'url'     => $url,
113 1
            'method'  => 'post',
114 1
            'timeout' => self::$timeout,
115 1
            'data'    => $data,
116
            'header'  => [
117 1
                'Authorization: '.$signature,
118 1
                'Content-Type: application/json',
119 1
            ],
120 1
        ];
121
122 1
        return self::sendRequest($req);
123
    }
124
125
    /**
126
     * 目录列表.
127
     *
128
     * @param string $bucket  bucket名称
129
     * @param string $folder  目录路径,sdk会补齐末尾的 '/'
130
     * @param int    $num     拉取的总数
131
     * @param string $pattern eListBoth,ListDirOnly,eListFileOnly  默认both
132
     * @param int    $order   默认正序(=0), 填1为反序,
133
     * @param string $context 透传字段,用于翻页,前端不需理解,需要往前/往后翻页则透传回来
134
     *
135
     * @return array
136
     */
137 1
    public static function listFolder($bucket, $folder, $num = 20, $pattern = 'eListBoth', $order = 0, $context = null)
138
    {
139 1
        $folder = self::normalizerPath($folder, true);
140
141 1
        return self::listBase($bucket, $folder, $num, $pattern, $order, $context);
142
    }
143
144
    /**
145
     * 目录列表(前缀搜索).
146
     *
147
     * @param string $bucket  bucket名称
148
     * @param string $prefix  列出含此前缀的所有文件
149
     * @param int    $num     拉取的总数
150
     * @param string $pattern eListBoth(默认),ListDirOnly,eListFileOnly
151
     * @param int    $order   默认正序(=0), 填1为反序,
152
     * @param string $context 透传字段,用于翻页,前端不需理解,需要往前/往后翻页则透传回来
153
     *
154
     * @return array
155
     */
156
    public static function prefixSearch($bucket, $prefix, $num = 20, $pattern = 'eListBoth', $order = 0, $context = null)
157
    {
158
        $path = self::normalizerPath($prefix);
159
160
        return self::listBase($bucket, $path, $num, $pattern, $order, $context);
161
    }
162
163
    /**
164
     * 目录更新.
165
     *
166
     * @param string $bucket  bucket名称
167
     * @param string $folder  文件夹路径,SDK会补齐末尾的 '/'
168
     * @param string $bizAttr 目录属性
169
     *
170
     * @return array
171
     */
172
    public static function updateFolder($bucket, $folder, $bizAttr = null)
173
    {
174
        $folder = self::normalizerPath($folder, true);
175
176
        return self::updateBase($bucket, $folder, $bizAttr);
177
    }
178
179
    /**
180
     * 查询目录信息.
181
     *
182
     * @param string $bucket bucket名称
183
     * @param string $folder 目录路径
184
     *
185
     * @return array
186
     */
187
    public static function statFolder($bucket, $folder)
188
    {
189
        $folder = self::normalizerPath($folder, true);
190
191
        return self::statBase($bucket, $folder);
192
    }
193
194
    /**
195
     * 删除目录.
196
     *
197
     * @param string $bucket bucket名称
198
     * @param string $folder 目录路径
199
     *                       注意不能删除bucket下根目录/
200
     *
201
     * @return array
202
     */
203 1 View Code Duplication
    public static function delFolder($bucket, $folder)
204
    {
205 1
        if (empty($bucket) || empty($folder)) {
206
            return [
207
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
208
                'message' => 'bucket or path is empty', ];
209
        }
210
211 1
        $folder = self::normalizerPath($folder, true);
212
213 1
        return self::delBase($bucket, $folder);
214
    }
215
216
    /**
217
     * 更新文件.
218
     *
219
     * @param string $bucket                 bucket名称
220
     * @param string $path                   文件路径
221
     * @param null   $bizAttr
222
     * @param string $authority              eInvalid(继承Bucket的读写权限)/eWRPrivate(私有读写)/eWPrivateRPublic(公有读私有写)
223
     * @param array  $customer_headers_array 携带的用户自定义头域,包括
224
     *                                       'Cache-Control' => '*'
225
     *                                       'Content-Type' => '*'
226
     *                                       'Content-Disposition' => '*'
227
     *                                       'Content-Language' => '*'
228
     *                                       'x-cos-meta-自定义内容' => '*'
229
     *
230
     * @return array
231
     */
232 1
    public static function update($bucket, $path, $bizAttr = null, $authority = null, $customer_headers_array = null)
233
    {
234 1
        $path = self::normalizerPath($path);
235
236 1
        return self::updateBase($bucket, $path, $bizAttr, $authority, $customer_headers_array);
237
    }
238
239
    /**
240
     * 查询文件信息.
241
     *
242
     * @param string $bucket bucket名称
243
     * @param string $path   文件路径
244
     *
245
     * @return array
246
     */
247 6
    public static function stat($bucket, $path)
248
    {
249 6
        $path = self::normalizerPath($path);
250
251 6
        return self::statBase($bucket, $path);
252
    }
253
254
    /**
255
     * 删除文件.
256
     *
257
     * @param string $bucket
258
     * @param string $path   文件路径
259
     *
260
     * @return array
261
     */
262 1 View Code Duplication
    public static function delFile($bucket, $path)
263
    {
264 1
        if (empty($bucket) || empty($path)) {
265
            return [
266
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
267
                'message' => 'path is empty', ];
268
        }
269
270 1
        $path = self::normalizerPath($path);
271
272 1
        return self::delBase($bucket, $path);
273
    }
274
275
    /**
276
     * 内部方法, 上传文件.
277
     *
278
     * @param string $bucket     bucket名称
279
     * @param string $srcPath    本地文件路径
280
     * @param string $dstPath    上传的文件路径
281
     * @param string $bizAttr    文件属性
282
     * @param int    $insertOnly 是否覆盖同名文件:0 覆盖,1:不覆盖
283
     *
284
     * @return array
285
     */
286 2
    private static function uploadFile($bucket, $srcPath, $dstPath, $bizAttr = null, $insertOnly = null)
287
    {
288 2
        $srcPath = realpath($srcPath);
289 2
        $dstPath = self::cosUrlEncode($dstPath);
290
291 2 View Code Duplication
        if (filesize($srcPath) >= self::MAX_UNSLICE_FILE_SIZE) {
292
            return [
293
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
294
                'message' => 'file '.$srcPath.' larger then 20M, please use uploadBySlicing interface',
295
                'data'    => [],
296
            ];
297
        }
298
299 2
        $expired = time() + self::EXPIRED_SECONDS;
300 2
        $url = self::generateResUrl($bucket, $dstPath);
301 2
        $signature = Auth::createReusableSignature($expired, $bucket);
302 2
        $fileSha = hash_file('sha1', $srcPath);
303
304
        $data = [
305 2
            'op'       => 'upload',
306 2
            'sha'      => $fileSha,
307 2
            'biz_attr' => (isset($bizAttr) ? $bizAttr : ''),
308 2
        ];
309
310 2
        $data['filecontent'] = file_get_contents($srcPath);
311
312 2
        if (isset($insertOnly) && strlen($insertOnly) > 0) {
313 2
            $data['insertOnly'] = (($insertOnly == 0 || $insertOnly == '0') ? 0 : 1);
314 2
        }
315
316
        $req = [
317 2
            'url'     => $url,
318 2
            'method'  => 'post',
319 2
            'timeout' => self::$timeout,
320 2
            'data'    => $data,
321
            'header'  => [
322 2
                'Authorization: '.$signature,
323 2
            ],
324 2
        ];
325
326 2
        return self::sendRequest($req);
327
    }
328
329
    /**
330
     * 内部方法,上传文件.
331
     *
332
     * @param string $bucket     bucket名称
333
     * @param string $srcFpath   本地文件路径
334
     * @param string $dstFpath   上传的文件路径
335
     * @param string $bizAttr    文件属性
336
     * @param string $sliceSize  分片大小
337
     * @param int    $insertOnly 是否覆盖同名文件:0 覆盖,1:不覆盖
338
     *
339
     * @return array
340
     */
341
    private static function uploadBySlicing($bucket, $srcFpath, $dstFpath, $bizAttr = null, $sliceSize = null, $insertOnly = null)
342
    {
343
        $srcFpath = realpath($srcFpath);
344
        $fileSize = filesize($srcFpath);
345
        $dstFpath = self::cosUrlEncode($dstFpath);
346
        $url = self::generateResUrl($bucket, $dstFpath);
347
        $sliceCount = ceil($fileSize / $sliceSize);
348
        // expiration seconds for one slice mutiply by slice count
349
        // will be the expired seconds for whole file
350
        $expiration = time() + (self::EXPIRED_SECONDS * $sliceCount);
351
        if ($expiration >= (time() + 10 * 24 * 60 * 60)) {
352
            $expiration = time() + 10 * 24 * 60 * 60;
353
        }
354
        $signature = Auth::createReusableSignature($expiration, $bucket);
355
356
        $sliceUploading = new SliceUploading(self::$timeout * 1000, self::MAX_RETRY_TIMES);
357
        for ($tryCount = 0; $tryCount < self::MAX_RETRY_TIMES; ++$tryCount) {
358
            if ($sliceUploading->initUploading(
359
                $signature,
360
                $srcFpath,
361
                $url,
362
                $fileSize, $sliceSize, $bizAttr, $insertOnly)
363
            ) {
364
                break;
365
            }
366
367
            $errorCode = $sliceUploading->getLastErrorCode();
368
            if ($errorCode === -4019) {
369
                // Delete broken file and retry again on _ERROR_FILE_NOT_FINISH_UPLOAD error.
370
                self::delFile($bucket, $dstFpath);
371
                continue;
372
            }
373
374 View Code Duplication
            if ($tryCount === self::MAX_RETRY_TIMES - 1) {
375
                return [
376
                    'code'       => $sliceUploading->getLastErrorCode(),
377
                    'message'    => $sliceUploading->getLastErrorMessage(),
378
                    'request_id' => $sliceUploading->getRequestId(),
379
                ];
380
            }
381
        }
382
383 View Code Duplication
        if (!$sliceUploading->performUploading()) {
384
            return [
385
                'code'       => $sliceUploading->getLastErrorCode(),
386
                'message'    => $sliceUploading->getLastErrorMessage(),
387
                'request_id' => $sliceUploading->getRequestId(),
388
            ];
389
        }
390
391 View Code Duplication
        if (!$sliceUploading->finishUploading()) {
392
            return [
393
                'code'       => $sliceUploading->getLastErrorCode(),
394
                'message'    => $sliceUploading->getLastErrorMessage(),
395
                'request_id' => $sliceUploading->getRequestId(),
396
            ];
397
        }
398
399
        return [
400
            'code'       => 0,
401
            'message'    => 'success',
402
            'request_id' => $sliceUploading->getRequestId(),
403
            'data'       => [
404
                'access_url'    => $sliceUploading->getAccessUrl(),
405
                'resource_path' => $sliceUploading->getResourcePath(),
406
                'source_url'    => $sliceUploading->getSourceUrl(),
407
            ],
408
        ];
409
    }
410
411
    /**
412
     * 内部公共函数.
413
     *
414
     * @param string $bucket  bucket名称
415
     * @param string $path    文件夹路径
416
     * @param int    $num     拉取的总数
417
     * @param string $pattern eListBoth(默认),ListDirOnly,eListFileOnly
418
     * @param int    $order   默认正序(=0), 填1为反序,
419
     * @param string $context 在翻页查询时候用到
420
     *
421
     * @return array
422
     */
423 1
    private static function listBase($bucket, $path, $num = 20, $pattern = 'eListBoth', $order = 0, $context = null)
424
    {
425 1
        $path = self::cosUrlEncode($path);
426 1
        $expired = time() + self::EXPIRED_SECONDS;
427 1
        $url = self::generateResUrl($bucket, $path);
428 1
        $signature = Auth::createReusableSignature($expired, $bucket);
429
430
        $data = [
431 1
            'op' => 'list',
432 1
        ];
433
434 1
        if (self::isPatternValid($pattern) == false) {
435
            return [
436
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
437
                'message' => 'parameter pattern invalid',
438
            ];
439
        }
440 1
        $data['pattern'] = $pattern;
441
442 1 View Code Duplication
        if ($order != 0 && $order != 1) {
443
            return [
444
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
445
                'message' => 'parameter order invalid',
446
            ];
447
        }
448 1
        $data['order'] = $order;
449
450 1 View Code Duplication
        if ($num < 0 || $num > 199) {
451
            return [
452
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
453
                'message' => 'parameter num invalid, num need less then 200',
454
            ];
455
        }
456 1
        $data['num'] = $num;
457
458 1
        if (isset($context)) {
459
            $data['context'] = $context;
460
        }
461
462 1
        $url = $url.'?'.http_build_query($data);
463
464
        $req = [
465 1
            'url'     => $url,
466 1
            'method'  => 'get',
467 1
            'timeout' => self::$timeout,
468
            'header'  => [
469 1
                'Authorization: '.$signature,
470 1
            ],
471 1
        ];
472
473 1
        return self::sendRequest($req);
474
    }
475
476
    /**
477
     * 内部公共方法(更新文件和更新文件夹).
478
     *
479
     * @param string $bucket               bucket名称
480
     * @param string $path                 路径
481
     * @param string $bizAttr              文件/目录属性
482
     * @param string $authority            eInvalid/eWRPrivate(私有)/eWPrivateRPublic(公有读写)
483
     * @param array  $custom_headers_array 携带的用户自定义头域,包括
484
     *                                     'Cache-Control' => '*'
485
     *                                     'Content-Type' => '*'
486
     *                                     'Content-Disposition' => '*'
487
     *                                     'Content-Language' => '*'
488
     *                                     'x-cos-meta-自定义内容' => '*'
489
     *
490
     * @return array
491
     */
492 1
    private static function updateBase(
493
        $bucket, $path, $bizAttr = null, $authority = null, $custom_headers_array = null)
494
    {
495 1
        $path = self::cosUrlEncode($path);
496
497 1
        $url = self::generateResUrl($bucket, $path);
498 1
        $signature = Auth::createNonreusableSignature($bucket, $path);
499
500 1
        $data = ['op' => 'update'];
501
502 1
        if (isset($bizAttr)) {
503
            $data['biz_attr'] = $bizAttr;
504
        }
505
506 1
        if (isset($authority) && strlen($authority) > 0) {
507 1
            if (self::isAuthorityValid($authority) == false) {
508
                return [
509
                    'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
510
                    'message' => 'parameter authority invalid', ];
511
            }
512
513 1
            $data['authority'] = $authority;
514 1
        }
515
516 1
        if (isset($custom_headers_array)) {
517
            $data['custom_headers'] = [];
518
            self::add_customer_header($data['custom_headers'], $custom_headers_array);
519
        }
520
521 1
        $data = json_encode($data);
522
523
        $req = [
524 1
            'url'     => $url,
525 1
            'method'  => 'post',
526 1
            'timeout' => self::$timeout,
527 1
            'data'    => $data,
528
            'header'  => [
529 1
                'Authorization: '.$signature,
530 1
                'Content-Type: application/json',
531 1
            ],
532 1
        ];
533
534 1
        return self::sendRequest($req);
535
    }
536
537
    /**
538
     * 内部方法.
539
     *
540
     * @param string $bucket bucket名称
541
     * @param string $path   文件/目录路径
542
     *
543
     * @return array
544
     */
545 6
    private static function statBase($bucket, $path)
546
    {
547 6
        $path = self::cosUrlEncode($path);
548 6
        $expired = time() + self::EXPIRED_SECONDS;
549 6
        $url = self::generateResUrl($bucket, $path);
550 6
        $signature = Auth::createReusableSignature($expired, $bucket);
551
552 6
        $data = ['op' => 'stat'];
553
554 6
        $url = $url.'?'.http_build_query($data);
555
556
        $req = [
557 6
            'url'     => $url,
558 6
            'method'  => 'get',
559 6
            'timeout' => self::$timeout,
560
            'header'  => [
561 6
                'Authorization: '.$signature,
562 6
            ],
563 6
        ];
564
565 6
        return self::sendRequest($req);
566
    }
567
568
    /**
569
     * 内部私有方法.
570
     *
571
     * @param string $bucket bucket名称
572
     * @param string $path   文件/目录路径路径
573
     *
574
     * @return array
575
     */
576 2
    private static function delBase($bucket, $path)
577
    {
578 2
        if ($path == '/') {
579
            return [
580
                'code'    => ErrorCode::COSAPI_PARAMS_ERROR,
581
                'message' => 'can not delete bucket using api! go to '.
582
                    'http://console.qcloud.com/cos to operate bucket', ];
583
        }
584
585 2
        $path = self::cosUrlEncode($path);
586
587 2
        $url = self::generateResUrl($bucket, $path);
588 2
        $signature = Auth::createNonreusableSignature($bucket, $path);
589
590 2
        $data = ['op' => 'delete'];
591
592 2
        $data = json_encode($data);
593
594
        $req = [
595 2
            'url'     => $url,
596 2
            'method'  => 'post',
597 2
            'timeout' => self::$timeout,
598 2
            'data'    => $data,
599
            'header'  => [
600 2
                'Authorization: '.$signature,
601 2
                'Content-Type: application/json',
602 2
            ],
603 2
        ];
604
605 2
        return self::sendRequest($req);
606
    }
607
608
    /**
609
     * 内部公共方法, 路径编码
610
     *
611
     * @param string $path 待编码路径
612
     *
613
     * @return string
614
     */
615 13
    private static function cosUrlEncode($path)
616
    {
617 13
        return str_replace('%2F', '/', rawurlencode($path));
618
    }
619
620
    /**
621
     * 内部公共方法, 构造URL.
622
     *
623
     * @param string $bucket
624
     * @param string $dstPath
625
     *
626
     * @return string
627
     */
628 15
    private static function generateResUrl($bucket, $dstPath)
629
    {
630 15
        $endPoint = Conf::API_COSAPI_END_POINT;
631 15
        $endPoint = str_replace('region', self::$region, $endPoint);
632
633 15
        return $endPoint.Conf::getAppId().'/'.$bucket.$dstPath;
634
    }
635
636
    /**
637
     * 内部公共方法, 发送消息.
638
     *
639
     * @param array $req
640
     *
641
     * @return array
642
     */
643 15
    private static function sendRequest($req)
644
    {
645 15
        $rsp = HttpClient::sendRequest($req);
646 15
        if ($rsp === false) {
647
            return [
648
                'code'    => ErrorCode::COSAPI_NETWORK_ERROR,
649
                'message' => 'network error',
650
            ];
651
        }
652
653 15
        $ret = json_decode($rsp, true);
654
655 15
        if ($ret === null) {
656
            return [
657 15
                'code'    => ErrorCode::COSAPI_NETWORK_ERROR,
658 15
                'message' => $rsp,
659 15
                'data'    => [],
660 15
            ];
661
        }
662
663
        return $ret;
664
    }
665
666
    /**
667
     * Get slice size.
668
     *
669
     * @param string $sliceSize
670
     *
671
     * @return int
672
     */
673
    private static function getSliceSize($sliceSize)
674
    {
675
        $sliceSize = (int) $sliceSize;
676
677
        switch ($sliceSize) {
678
            case 512:
679
                $sliceSize = 0.5 * self::SLICE_SIZE_1M;
680
                break;
681
            case 1:
682
                $sliceSize = 1 * self::SLICE_SIZE_1M;
683
                break;
684
            case 2:
685
                $sliceSize = 2 * self::SLICE_SIZE_1M;
686
                break;
687
            case 3:
688
                $sliceSize = 3 * self::SLICE_SIZE_1M;
689
                break;
690
            default:
691
                // Fix slice size to 1MB.
692
                $sliceSize = self::SLICE_SIZE_1M;
693
        }
694
695
        return $sliceSize;
696
    }
697
698
    /**
699
     * 内部方法, 规整文件路径.
700
     *
701
     * @param string $path     文件路径
702
     * @param bool   $isfolder 是否为文件夹
703
     *
704
     * @return string
705
     */
706 15
    private static function normalizerPath($path, $isfolder = false)
707
    {
708 15
        if (preg_match('/^\//', $path) == 0) {
709 15
            $path = '/'.$path;
710 15
        }
711
712 15
        if ($isfolder === true) {
713 3
            if (preg_match('/\/$/', $path) == 0) {
714 3
                $path = $path.'/';
715 3
            }
716 3
        }
717
718
        // Remove unnecessary slashes.
719 15
        $path = preg_replace('#/+#', '/', $path);
720
721 15
        return $path;
722
    }
723
724
    /**
725
     * 判断authority值是否正确.
726
     *
727
     * @param string $authority
728
     *
729
     * @return bool
730
     */
731 1
    private static function isAuthorityValid($authority)
732
    {
733 1
        if ($authority == 'eInvalid' || $authority == 'eWRPrivate' || $authority == 'eWPrivateRPublic') {
734 1
            return true;
735
        }
736
737
        return false;
738
    }
739
740
    /**
741
     * 判断pattern值是否正确.
742
     *
743
     * @param string $pattern
744
     *
745
     * @return bool
746
     */
747 1
    private static function isPatternValid($pattern)
748
    {
749 1
        if ($pattern == 'eListBoth' || $pattern == 'eListDirOnly' || $pattern == 'eListFileOnly') {
750 1
            return true;
751
        }
752
753
        return false;
754
    }
755
756
    /**
757
     * 判断是否符合自定义属性.
758
     *
759
     * @param string $key
760
     *
761
     * @return bool
762
     */
763
    private static function isCustomer_header($key)
764
    {
765
        if ($key == 'Cache-Control' || $key == 'Content-Type' ||
766
            $key == 'Content-Disposition' || $key == 'Content-Language' ||
767
            $key == 'Content-Encoding' ||
768
            substr($key, 0, strlen('x-cos-meta-')) == 'x-cos-meta-'
769
        ) {
770
            return true;
771
        }
772
773
        return false;
774
    }
775
776
    /**
777
     * 增加自定义属性到data中.
778
     *
779
     * @param array $data
780
     * @param array $customer_headers_array
781
     */
782
    private static function add_customer_header(&$data, &$customer_headers_array)
783
    {
784
        if (count($customer_headers_array) < 1) {
785
            return;
786
        }
787
        foreach ($customer_headers_array as $key => $value) {
788
            if (self::isCustomer_header($key)) {
789
                $data[$key] = $value;
790
            }
791
        }
792
    }
793
794
    // Check |$path| is a valid file path.
795
    // Return true on success, otherwise return false.
796
797
    /**
798
     * @param string $path
799
     */
800 1
    private static function isValidPath($path)
801
    {
802 1
        if (strpos($path, '?') !== false) {
803
            return false;
804
        }
805 1
        if (strpos($path, '*') !== false) {
806
            return false;
807
        }
808 1
        if (strpos($path, ':') !== false) {
809
            return false;
810
        }
811 1
        if (strpos($path, '|') !== false) {
812
            return false;
813
        }
814 1
        if (strpos($path, '\\') !== false) {
815
            return false;
816
        }
817 1
        if (strpos($path, '<') !== false) {
818
            return false;
819
        }
820 1
        if (strpos($path, '>') !== false) {
821
            return false;
822
        }
823 1
        if (strpos($path, '"') !== false) {
824
            return false;
825
        }
826
827 1
        return true;
828
    }
829
830
    /**
831
     * Copy a file.
832
     *
833
     * @param string $bucket    bucket name.
834
     * @param string $srcFpath  source file path.
835
     * @param string $dstFpath  destination file path.
836
     * @param bool   $overwrite if the destination location is occupied, overwrite it or not?
837
     *
838
     * @return array|mixed.
839
     */
840 1 View Code Duplication
    public static function copyFile($bucket, $srcFpath, $dstFpath, $overwrite = false)
841
    {
842 1
        $srcFpath = self::normalizerPath($srcFpath);
843 1
        $dstFpath = self::normalizerPath($dstFpath);
844
845 1
        $url = self::generateResUrl($bucket, $srcFpath);
846 1
        $sign = Auth::createNonreusableSignature($bucket, $srcFpath);
847
        $data = [
848 1
            'op'            => 'copy',
849 1
            'dest_fileid'   => $dstFpath,
850 1
            'to_over_write' => $overwrite ? 1 : 0,
851 1
        ];
852
        $req = [
853 1
            'url'     => $url,
854 1
            'method'  => 'post',
855 1
            'timeout' => self::$timeout,
856 1
            'data'    => $data,
857
            'header'  => [
858 1
                'Authorization: '.$sign,
859 1
            ],
860 1
        ];
861
862 1
        return self::sendRequest($req);
863
    }
864
865
    /**
866
     * Move a file.
867
     *
868
     * @param string $bucket    bucket name.
869
     * @param string $srcFpath  source file path.
870
     * @param string $dstFpath  destination file path.
871
     * @param bool   $overwrite if the destination location is occupied, overwrite it or not?
872
     *
873
     * @return array
874
     */
875 1 View Code Duplication
    public static function moveFile($bucket, $srcFpath, $dstFpath, $overwrite = false)
876
    {
877 1
        $srcFpath = self::normalizerPath($srcFpath);
878 1
        $dstFpath = self::normalizerPath($dstFpath);
879
880 1
        $url = self::generateResUrl($bucket, $srcFpath);
881 1
        $sign = Auth::createNonreusableSignature($bucket, $srcFpath);
882
        $data = [
883 1
            'op'            => 'move',
884 1
            'dest_fileid'   => $dstFpath,
885 1
            'to_over_write' => $overwrite ? 1 : 0,
886 1
        ];
887
        $req = [
888 1
            'url'     => $url,
889 1
            'method'  => 'post',
890 1
            'timeout' => self::$timeout,
891 1
            'data'    => $data,
892
            'header'  => [
893 1
                'Authorization: '.$sign,
894 1
            ],
895 1
        ];
896
897 1
        return self::sendRequest($req);
898
    }
899
}
900