Completed
Pull Request — master (#174)
by
unknown
21:47
created

ResumeUploader   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 85.92%

Importance

Changes 10
Bugs 2 Features 1
Metric Value
wmc 25
c 10
b 2
f 1
lcom 1
cbo 3
dl 0
loc 144
ccs 61
cts 71
cp 0.8592
rs 10

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 19 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 6
     */
41
    public function __construct(
42
        $upToken,
43
        $key,
44
        $inputStream,
45
        $size,
46
        $params,
47
        $mime,
48
        $config,
49 6
        $filePath
50 6
    ) {
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
        $this->host = $config->getUpHost();
60
        $this->fname=basename($filePath);
61
    }
62
63 6
    /**
64
     * 上传操作
65 6
     */
66 6
    public function upload()
67 6
    {
68 6
        $uploaded = 0;
69 6
        while ($uploaded < $this->size) {
70
            $blockSize = $this->blockSize($uploaded);
71
            $data = fread($this->inputStream, $blockSize);
72 6
            if ($data === false) {
73 6
                throw new \Exception("file read failed", 1);
74 6
            }
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 3
                $ret = $response->json();
80 3
            }
81 6
            if ($response->statusCode < 0) {
82 3
                $this->host = $this->config->getUpHostBackup();
83 3
            }
84 3
            if ($response->needRetry() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
85
                $response = $this->makeBlock($data, $blockSize);
86 6
                $ret = $response->json();
87
            }
88
89 6
            if (! $response->ok() || !isset($ret['crc32'])|| $crc != $ret['crc32']) {
90 6
                return array(null, new Error($this->currentUrl, $response));
91 6
            }
92 6
            array_push($this->contexts, $ret['ctx']);
93
            $uploaded += $blockSize;
94
        }
95
        return $this->makeFile();
96
    }
97
98 6
    /**
99
     * 创建块
100 6
     */
101 6
    private function makeBlock($block, $blockSize)
102
    {
103
        $url = $this->host . '/mkblk/' . $blockSize;
104 6
        return $this->post($url, $block);
105
    }
106 6
107 6
    private function fileUrl()
108 6
    {
109 6
        $url = $this->host . '/mkfile/' . $this->size;
110 6
        $url .= '/mimeType/' . \Qiniu\base64_urlSafeEncode($this->mime);
111 6
        if ($this->key != null) {
112
            $url .= '/key/' . \Qiniu\base64_urlSafeEncode($this->key);
113
        }
114
         if ($this->fname !=null) {
115
            $url .= '/fname/' . \Qiniu\base64_urlSafeEncode($this->fname);
116
117 6
        }
118
        if (!empty($this->params)) {
119
            foreach ($this->params as $key => $value) {
120
                $val =  \Qiniu\base64_urlSafeEncode($value);
121
                $url .= "/$key/$val";
122
            }
123 6
        }
124
        return $url;
125 6
    }
126 6
127 6
    /**
128 6
     * 创建文件
129
     */
130
    private function makeFile()
131 6
    {
132
        $url = $this->fileUrl();
133
        $body = implode(',', $this->contexts);
134 6
        $response = $this->post($url, $body);
135
        if ($response->needRetry()) {
136
            $response = $this->post($url, $body);
137 6
        }
138
        if (! $response->ok()) {
139 6
            return array(null, new Error($this->currentUrl, $response));
140 6
        }
141 6
        return array($response->json(), null);
142
    }
143
144 6
    private function post($url, $data)
145
    {
146 6
        $this->currentUrl = $url;
147 6
        $headers = array('Authorization' => 'UpToken ' . $this->upToken);
148
        return Client::post($url, $data, $headers);
149 6
    }
150
151
    private function blockSize($uploaded)
152
    {
153
        if ($this->size < $uploaded + Config::BLOCK_SIZE) {
154
            return $this->size - $uploaded;
155
        }
156
        return  Config::BLOCK_SIZE;
157
    }
158
}
159