1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace B2; |
4
|
|
|
|
5
|
|
|
use B2\Files\Files; |
6
|
|
|
use PartnerIT\Curl\Network\CurlRequest; |
7
|
|
|
|
8
|
|
|
class B2Client |
9
|
|
|
{ |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* @var string |
13
|
|
|
*/ |
14
|
|
|
protected $accountId; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @var string |
18
|
|
|
*/ |
19
|
|
|
protected $applicationKey; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* @var string |
23
|
|
|
*/ |
24
|
|
|
protected $apiUrl; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var string |
28
|
|
|
*/ |
29
|
|
|
protected $authorizationToken; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @var string |
33
|
|
|
*/ |
34
|
|
|
protected $downloadUrl; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var CurlRequest |
38
|
|
|
*/ |
39
|
|
|
protected $CurlRequest; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var Files |
43
|
|
|
*/ |
44
|
|
|
public $Files; |
45
|
|
|
|
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* B2Client constructor. |
49
|
|
|
* @param string $accountId |
50
|
|
|
* @param string $applicationKey |
51
|
|
|
*/ |
52
|
5 |
|
public function __construct($accountId, $applicationKey, CurlRequest $curlRequest = null) |
53
|
|
|
{ |
54
|
|
|
|
55
|
5 |
|
if (!$curlRequest) { |
56
|
4 |
|
$this->CurlRequest = new CurlRequest(); |
57
|
4 |
|
} else { |
58
|
1 |
|
$this->CurlRequest = $curlRequest; |
59
|
|
|
} |
60
|
|
|
|
61
|
5 |
|
$this->accountId = $accountId; |
62
|
5 |
|
$this->applicationKey = $applicationKey; |
63
|
5 |
|
$this->Files = new Files($this); |
64
|
|
|
|
65
|
5 |
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* @param array $result |
69
|
|
|
*/ |
70
|
3 |
|
public function setToken($result) |
71
|
|
|
{ |
72
|
3 |
|
$this->authorizationToken = $result['authorizationToken']; |
73
|
3 |
|
$this->apiUrl = $result['apiUrl']; |
74
|
3 |
|
$this->downloadUrl = $result['downloadUrl']; |
75
|
3 |
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* |
79
|
|
|
*/ |
80
|
1 |
|
public function requestToken() |
81
|
|
|
{ |
82
|
|
|
|
83
|
1 |
|
$results = $this->curl('https://api.backblaze.com/b2api/v1/b2_authorize_account', 'GET', [ |
84
|
1 |
|
$this->buildBasicAuthHeader() |
85
|
1 |
|
]); |
86
|
|
|
|
87
|
1 |
|
if ($results['statusCode'] === 200) { |
88
|
1 |
|
$this->setToken($results['responseBody']); |
89
|
1 |
|
return true; |
90
|
|
|
} else { |
91
|
|
|
throw new \RuntimeException('Failed to get token: ' . $results['responseBody']['message']); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @param $endpoint |
98
|
|
|
* @param $method |
99
|
|
|
* @param array $data |
100
|
|
|
* @return mixed |
101
|
|
|
* @throws \Exception |
102
|
|
|
*/ |
103
|
2 |
|
public function call($endpoint, $method, $data = []) |
104
|
|
|
{ |
105
|
|
|
|
106
|
2 |
|
if (empty($this->authorizationToken)) { |
107
|
|
|
throw new \Exception('You must set or generate a token'); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
$headers = [ |
111
|
2 |
|
$this->buildTokenAuthHeader() |
112
|
2 |
|
]; |
113
|
|
|
|
114
|
2 |
|
$headers[] = 'Content-Type: application/json'; |
115
|
2 |
|
$headers[] = "Accept: application/json"; |
116
|
2 |
|
$body = json_encode($data); |
117
|
|
|
|
118
|
2 |
|
$result = $this->curl($this->apiUrl . '/b2api/v1/' . $endpoint, $method, $headers, $body); |
119
|
|
|
|
120
|
2 |
|
if ($result['statusCode'] >= 200 && $result['statusCode'] < 300) { |
121
|
1 |
|
return $result['responseBody']; |
122
|
|
|
} |
123
|
|
|
|
124
|
1 |
|
if ($result['statusCode'] >= 400) { |
125
|
1 |
|
throw new \RuntimeException('Error ' . $result['statusCode'] . ' - ' . $result['responseBody']['message']); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* @param $uri |
132
|
|
|
* @param string $method |
133
|
|
|
* @param array $headers |
134
|
|
|
* @param mixed $body |
135
|
|
|
* @return array |
136
|
|
|
* @throws \Exception |
137
|
|
|
*/ |
138
|
|
|
public function curl($uri, $method = 'GET', $headers = [], $body = null, $raw = false) |
139
|
|
|
{ |
140
|
|
|
|
141
|
|
|
$this->CurlRequest->setOption(CURLOPT_URL, $uri); |
142
|
|
|
$this->CurlRequest->setOption(CURLOPT_CUSTOMREQUEST, $method); |
143
|
|
|
$this->CurlRequest->setOption(CURLOPT_RETURNTRANSFER, 1); |
144
|
|
|
$this->CurlRequest->setOption(CURLOPT_POST, 1); |
145
|
|
|
$this->CurlRequest->setOption(CURLOPT_POSTFIELDS, $body); |
146
|
|
|
$this->CurlRequest->setOption(CURLOPT_HTTPHEADER, $headers); |
147
|
|
|
|
148
|
|
|
$resp = $this->CurlRequest->execute(); |
149
|
|
View Code Duplication |
if ($this->CurlRequest->getErrorNo() !== 0) { |
|
|
|
|
150
|
|
|
throw new \RuntimeException('curl error ' . $this->CurlRequest->getError() . '" - Code: ' . $this->CurlRequest->getErrorNo()); |
151
|
|
|
} else { |
152
|
|
|
if ($raw) { |
153
|
|
|
return $resp; |
154
|
|
|
} else { |
155
|
|
|
return [ |
156
|
|
|
'statusCode' => $this->CurlRequest->getInfo(CURLINFO_HTTP_CODE), |
157
|
|
|
'responseBody' => json_decode($resp, true) |
158
|
|
|
]; |
159
|
|
|
} |
160
|
|
|
} |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* @return string |
165
|
|
|
*/ |
166
|
1 |
|
public function buildBasicAuthHeader() |
167
|
|
|
{ |
168
|
1 |
|
return 'Authorization: Basic ' . base64_encode($this->accountId . ':' . $this->applicationKey); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* @return string |
173
|
|
|
*/ |
174
|
2 |
|
public function buildTokenAuthHeader() |
175
|
|
|
{ |
176
|
2 |
|
return 'Authorization: ' . $this->authorizationToken; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param $data |
181
|
|
|
* @param $sha1 |
182
|
|
|
* @param $fileName |
183
|
|
|
* @param $url |
184
|
|
|
* @param $token |
185
|
|
|
*/ |
186
|
|
|
public function uploadData($fileData, $fileDataSha1, $fileName, $contentType, $uploadUrl, $uploadToken) |
187
|
|
|
{ |
188
|
|
|
$headers = []; |
189
|
|
|
$headers[] = "Authorization: " . $uploadToken; |
190
|
|
|
$headers[] = "X-Bz-File-Name: " . $fileName; |
191
|
|
|
$headers[] = "Content-Type: " . $contentType; |
192
|
|
|
$headers[] = "X-Bz-Content-Sha1: " . $fileDataSha1; |
193
|
|
|
|
194
|
|
|
$this->CurlRequest->setOption(CURLOPT_URL, $uploadUrl); |
195
|
|
|
$this->CurlRequest->setOption(CURLOPT_POST, true); |
196
|
|
|
$this->CurlRequest->setOption(CURLOPT_POSTFIELDS, $fileData); |
197
|
|
|
$this->CurlRequest->setOption(CURLOPT_HTTPHEADER, $headers); |
198
|
|
|
|
199
|
|
|
$resp = $this->CurlRequest->execute(); |
200
|
|
View Code Duplication |
if ($this->CurlRequest->getErrorNo() !== 0) { |
|
|
|
|
201
|
|
|
throw new \RuntimeException('curl error ' . $this->CurlRequest->getError() . '" - Code: ' . $this->CurlRequest->getErrorNo()); |
202
|
|
|
} else { |
203
|
|
|
return [ |
204
|
|
|
'statusCode' => $this->CurlRequest->getInfo(CURLINFO_HTTP_CODE), |
205
|
|
|
'responseBody' => json_decode($resp, true) |
206
|
|
|
]; |
207
|
|
|
} |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* @param $url |
212
|
|
|
*/ |
213
|
|
|
public function downloadFileByName($uri) |
214
|
|
|
{ |
215
|
|
|
|
216
|
|
|
$uri = $this->downloadUrl . "/file/" . $uri; |
217
|
|
|
$this->CurlRequest->setOption(CURLOPT_URL, $uri); |
218
|
|
|
$this->CurlRequest->setOption(CURLOPT_CUSTOMREQUEST, 'GET'); |
219
|
|
|
$this->CurlRequest->setOption(CURLOPT_RETURNTRANSFER, 1); |
220
|
|
|
|
221
|
|
|
$headers = [ |
222
|
|
|
$this->buildTokenAuthHeader() |
223
|
|
|
]; |
224
|
|
|
|
225
|
|
|
$this->CurlRequest->setOption(CURLOPT_HTTPHEADER, $headers); |
226
|
|
|
|
227
|
|
|
$resp = $this->CurlRequest->execute(); |
228
|
|
|
if ($this->CurlRequest->getErrorNo() !== 0) { |
229
|
|
|
throw new \RuntimeException('curl error ' . $this->CurlRequest->getError() . '" - Code: ' . $this->CurlRequest->getErrorNo()); |
230
|
|
|
} else { |
231
|
|
|
return $resp; |
232
|
|
|
} |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* @return string |
237
|
|
|
*/ |
238
|
1 |
|
public function getDownloadUrl() |
239
|
|
|
{ |
240
|
1 |
|
return $this->downloadUrl; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.