Completed
Pull Request — master (#184)
by
unknown
06:34
created

ResumeUploader   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 85.53%

Importance

Changes 9
Bugs 2 Features 2
Metric Value
dl 0
loc 145
ccs 65
cts 76
cp 0.8553
rs 10
c 9
b 2
f 2
wmc 25
lcom 1
cbo 3

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 21 1
C upload() 0 31 12
A makeBlock() 0 5 1
B fileUrl() 0 20 5
A makeFile() 0 13 3
A post() 0 6 1
A blockSize() 0 7 2
1
<?php
2
namespace Qiniu\Storage;
3
4
use Qiniu\Config;
5
use Qiniu\Http\Client;
6
use Qiniu\Http\Error;
7
8
/**
9
 * 断点续上传类, 该类主要实现了断点续上传中的分块上传,
10
 * 以及相应地创建块和创建文件过程.
11
 *
12
 * @link http://developer.qiniu.com/docs/v6/api/reference/up/mkblk.html
13
 * @link http://developer.qiniu.com/docs/v6/api/reference/up/mkfile.html
14
 */
15
final class ResumeUploader
16
{
17
    private $upToken;
18
    private $key;
19
    private $inputStream;
20
    private $size;
21
    private $params;
22
    private $mime;
23
    private $contexts;
24
    private $host;
25
    private $currentUrl;
26
    private $config;
27
    private $fname;
28
29
    /**
30
     * 上传二进制流到七牛
31
     *
32
     * @param $upToken    上传凭证
33
     * @param $key        上传文件名
34
     * @param $inputStream 上传二进制流
35
     * @param $size       上传流的大小
36
     * @param $params     自定义变量
37
     * @param $mime       上传数据的mimeType
38
     *
39
     * @link http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
40
     */
41 6
    public function __construct(
42
        $upToken,
43
        $key,
44
        $inputStream,
45
        $size,
46
        $params,
47
        $mime,
48
        $config,
49
        $filePath=null
50
    ) {
51 6
        $this->upToken = $upToken;
52 6
        $this->key = $key;
53 6
        $this->inputStream = $inputStream;
54 6
        $this->size = $size;
55 6
        $this->params = $params;
56 6
        $this->mime = $mime;
57 6
        $this->contexts = array();
58 6
        $this->config = $config;
59 6
        $this->host = $config->getUpHost();
60 6
        $this->fname=basename($filePath);
61 6
    }
62
63
    /**
64
     * 上传操作
65
     */
66 6
    public function upload()
67
    {
68 6
        $uploaded = 0;
69 6
        while ($uploaded < $this->size) {
70 6
            $blockSize = $this->blockSize($uploaded);
71 6
            $data = fread($this->inputStream, $blockSize);
72 6
            if ($data === false) {
73
                throw new \Exception("file read failed", 1);
74
            }
75 6
            $crc = \Qiniu\crc32_data($data);
76 6
            $response = $this->makeBlock($data, $blockSize);
77 6
            $ret = null;
78 6
            if ($response->ok() && $response->json() != null) {
79 6
                $ret = $response->json();
80 4
            }
81 6
            if ($response->statusCode < 0) {
82 3
                $this->host = $this->config->getUpHostBackup();
83 2
            }
84 6
            if ($response->needRetry() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
85 3
                $response = $this->makeBlock($data, $blockSize);
86 3
                $ret = $response->json();
87 2
            }
88
89 6
            if (! $response->ok() || !isset($ret['crc32'])|| $crc != $ret['crc32']) {
90
                return array(null, new Error($this->currentUrl, $response));
91
            }
92 6
            array_push($this->contexts, $ret['ctx']);
93 6
            $uploaded += $blockSize;
94 4
        }
95 6
        return $this->makeFile();
96
    }
97
98
    /**
99
     * 创建块
100
     */
101 6
    private function makeBlock($block, $blockSize)
102
    {
103 6
        $url = $this->host . '/mkblk/' . $blockSize;
104 6
        return $this->post($url, $block);
105
    }
106
107 6
    private function fileUrl()
108
    {
109 6
        $url = $this->host . '/mkfile/' . $this->size;
110 6
        $url .= '/mimeType/' . \Qiniu\base64_urlSafeEncode($this->mime);
111 6
        if ($this->key != null) {
112 6
            $url .= '/key/' . \Qiniu\base64_urlSafeEncode($this->key);
113 4
        }
114 6
        if($this->fname!=null){
115 6
            $url.='/fname/'.  \Qiniu\base64_urlSafeEncode($this->fname);
116 4
        }else{
117
            $url.='/fname/'.  \Qiniu\base64_urlSafeEncode($this->key);
118
        }
119 6
        if (!empty($this->params)) {
120
            foreach ($this->params as $key => $value) {
121
                $val =  \Qiniu\base64_urlSafeEncode($value);
122
                $url .= "/$key/$val";
123
            }
124
        }
125 6
        return $url;
126
    }
127
128
    /**
129
     * 创建文件
130
     */
131 6
    private function makeFile()
132
    {
133 6
        $url = $this->fileUrl();
134 6
        $body = implode(',', $this->contexts);
135 6
        $response = $this->post($url, $body);
136 6
        if ($response->needRetry()) {
137
            $response = $this->post($url, $body);
138
        }
139 6
        if (! $response->ok()) {
140
            return array(null, new Error($this->currentUrl, $response));
141
        }
142 6
        return array($response->json(), null);
143
    }
144
145 6
    private function post($url, $data)
146
    {
147 6
        $this->currentUrl = $url;
148 6
        $headers = array('Authorization' => 'UpToken ' . $this->upToken);
149 6
        return Client::post($url, $data, $headers);
150
    }
151
152 6
    private function blockSize($uploaded)
153
    {
154 6
        if ($this->size < $uploaded + Config::BLOCK_SIZE) {
155 6
            return $this->size - $uploaded;
156
        }
157 6
        return  Config::BLOCK_SIZE;
158
    }
159
}
160