Completed
Pull Request — master (#182)
by
unknown
04:20
created

ResumeUploader::upload()   C

Complexity

Conditions 12
Paths 18

Size

Total Lines 31
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 14.8092

Importance

Changes 4
Bugs 1 Features 0
Metric Value
cc 12
eloc 22
c 4
b 1
f 0
nc 18
nop 0
dl 0
loc 31
ccs 19
cts 26
cp 0.7308
crap 14.8092
rs 5.1612

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
28
    /**
29
     * 上传二进制流到七牛
30
     *
31
     * @param $upToken    上传凭证
32
     * @param $key        上传文件名
33
     * @param $inputStream 上传二进制流
34
     * @param $size       上传流的大小
35
     * @param $params     自定义变量
36
     * @param $mime       上传数据的mimeType
37
     *
38
     * @link http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
39
     */
40 6
    public function __construct(
41
        $upToken,
42
        $key,
43
        $inputStream,
44
        $size,
45
        $params,
46
        $mime,
47
        $config
48
    ) {
49 6
        $this->upToken = $upToken;
50 6
        $this->key = $key;
51 6
        $this->inputStream = $inputStream;
52 6
        $this->size = $size;
53 6
        $this->params = $params;
54 6
        $this->mime = $mime;
55 6
        $this->contexts = array();
56 6
        $this->config = $config;
57 6
        $this->host = $config->getUpHost();
58 6
    }
59
60
    /**
61
     * 上传操作
62
     */
63 6
    public function upload()
64
    {
65 6
        $uploaded = 0;
66 6
        while ($uploaded < $this->size) {
67 6
            $blockSize = $this->blockSize($uploaded);
68 6
            $data = fread($this->inputStream, $blockSize);
69 6
            if ($data === false) {
70
                throw new \Exception("file read failed", 1);
71
            }
72 6
            $crc = \Qiniu\crc32_data($data);
73 6
            $response = $this->makeBlock($data, $blockSize);
74 6
            $ret = null;
75 6
            if ($response->ok() && $response->json() != null) {
76
                $ret = $response->json();
77
            }
78 6
            if ($response->statusCode < 0) {
79 6
                $this->host = $this->config->getUpHostBackup();
80 6
            }
81 6
            if ($response->needRetry() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
82 6
                $response = $this->makeBlock($data, $blockSize);
83 6
                $ret = $response->json();
84 6
            }
85
86 6
            if (! $response->ok() || !isset($ret['crc32'])|| $crc != $ret['crc32']) {
87 6
                return array(null, new Error($this->currentUrl, $response));
88
            }
89
            array_push($this->contexts, $ret['ctx']);
90
            $uploaded += $blockSize;
91
        }
92
        return $this->makeFile();
93
    }
94
95
    /**
96
     * 创建块
97
     */
98 6
    private function makeBlock($block, $blockSize)
99
    {
100 6
        $url = $this->host . '/mkblk/' . $blockSize;
101 6
        return $this->post($url, $block);
102
    }
103
104
    private function fileUrl()
105
    {
106
        $url = $this->host . '/mkfile/' . $this->size;
107
        $url .= '/mimeType/' . \Qiniu\base64_urlSafeEncode($this->mime);
108
        if ($this->key != null) {
109
            $url .= '/key/' . \Qiniu\base64_urlSafeEncode($this->key);
110
        }
111
        if (!empty($this->params)) {
112
            foreach ($this->params as $key => $value) {
113
                $val =  \Qiniu\base64_urlSafeEncode($value);
114
                $url .= "/$key/$val";
115
            }
116
        }
117
        return $url;
118
    }
119
120
    /**
121
     * 创建文件
122
     */
123
    private function makeFile()
124
    {
125
        $url = $this->fileUrl();
126
        $body = implode(',', $this->contexts);
127
        $response = $this->post($url, $body);
128
        if ($response->needRetry()) {
129
            $response = $this->post($url, $body);
130
        }
131
        if (! $response->ok()) {
132
            return array(null, new Error($this->currentUrl, $response));
133
        }
134
        return array($response->json(), null);
135
    }
136
137 6
    private function post($url, $data)
138
    {
139 6
        $this->currentUrl = $url;
140 6
        $headers = array('Authorization' => 'UpToken ' . $this->upToken);
141 6
        return Client::post($url, $data, $headers);
142
    }
143
144 6
    private function blockSize($uploaded)
145
    {
146 6
        if ($this->size < $uploaded + Config::BLOCK_SIZE) {
147
            return $this->size - $uploaded;
148
        }
149 6
        return  Config::BLOCK_SIZE;
150
    }
151
}
152