PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 1.5.3
JetBackup – Backup, Restore & Migrate v1.5.3
3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / com / core / storage / SGDropboxStorage.php
backup / com / core / storage Last commit date
BackupGuardStorage.php 5 years ago SGDropbox.php 5 years ago SGDropboxStorage.php 5 years ago SGStorage.php 5 years ago
SGDropboxStorage.php
381 lines
1 <?php
2 require_once(SG_STORAGE_PATH.'SGStorage.php');
3
4 use \Dropbox as dbx;
5
6 class SGDropboxStorage extends SGStorage
7 {
8 private $client = null;
9
10 public function init()
11 {
12 //check if curl extension is loaded
13 SGBoot::checkRequirement('curl');
14
15 // Dropbox api 2
16 $this->setActiveDirectory('');
17
18 @set_exception_handler(array('SGDropboxStorage', 'exceptionHandler'));
19 require_once(SG_STORAGE_PATH.'SGDropbox.php');
20 }
21
22 public static function exceptionHandler($exception)
23 {
24 if(SG_ENV_ADAPTER == SG_ENV_WORDPRESS) {
25 wp_die($exception->getMessage());
26 }
27 elseif (SG_ENV_ADAPTER == SG_ENV_MAGENTO) {
28 die($exception->getMessage());
29 }
30 }
31
32 public function connect()
33 {
34 if ($this->isConnected()) {
35 return;
36 }
37
38 $authCode = $this->getAuthCodeFromURL($cancel);
39
40 if ($cancel) {
41 throw new SGExceptionMethodNotAllowed('User did not allow access');
42 }
43
44 $this->auth($authCode);
45 }
46
47 private function auth($authCode = '')
48 {
49 if ($authCode) {
50 try {
51 //exchange authorization code for access token
52 parse_str($_SERVER['QUERY_STRING'], $arr);
53 list($accessToken, $userId, $urlState) = $this->getWebAuth()->finish($arr);
54
55 $this->setAccessToken($accessToken);
56 $accountInfo = $this->getClient()->getAccountInfo();
57 SGConfig::set('SG_DROPBOX_CONNECTION_STRING', $accountInfo['email']);
58
59 $this->connected = true;
60 return;
61 }
62 catch (Exception $ex) {
63 }
64 }
65
66 $refUrl = base64_encode($this->getRefURL());
67 $authorizeUrl = $this->getWebAuth()->start($refUrl);
68 header("Location: $authorizeUrl");
69 exit;
70 }
71
72 public function connectOffline()
73 {
74 if ($this->isConnected()) {
75 return;
76 }
77
78 if (!$this->getClient()) {
79 throw new SGExceptionNotFound('Access token not found');
80 }
81
82 $this->connected = true;
83 }
84
85 public function checkConnected()
86 {
87 $accessToken = $this->getAccessToken();
88 $this->connected = $accessToken?true:false;
89 }
90
91 public function getListOfFiles()
92 {
93 if (!$this->isConnected()) {
94 throw new SGExceptionForbidden('Permission denied. Authentication required.');
95 }
96
97 $listOfFiles = array();
98 $activeDirectory = rtrim($this->getActiveDirectory()).'/';
99 $metaData = $this->getClient()->getMetadataWithChildren($activeDirectory.SGConfig::get('SG_STORAGE_BACKUPS_FOLDER_NAME'));
100
101 foreach($metaData['entries'] as $file) {
102 $size = $file['size'];
103 $date = $this->standardizeFileCreationDate($file['client_modified']);
104 $name = basename($file['path_display']);
105
106 $listOfFiles[$name] = array(
107 'name' => $name,
108 'size' => $size,
109 'date' => $date,
110 'path' => $file['path_display'],
111 );
112 }
113
114 krsort($listOfFiles);
115 return $listOfFiles;
116 }
117
118 public function createFolder($folderName)
119 {
120 if (!$this->isConnected()) {
121 throw new SGExceptionForbidden('Permission denied. Authentication required.');
122 }
123
124 $path = rtrim($this->getActiveDirectory(), '/').'/'.$folderName;
125 $this->getClient()->createFolder($path);
126
127 return $path;
128 }
129
130 private $fd = null;
131 private $filePath = '';
132
133 public function downloadFile($file, $size, $backupId = null)
134 {
135 if (!$file) {
136 return false;
137 }
138
139 $this->filePath = SG_BACKUP_DIRECTORY.basename($file);
140 $this->fd = fopen(SG_BACKUP_DIRECTORY.basename($file), "wb");
141
142 $client = $this->getClient();
143
144 $url = "https://content.dropboxapi.com/2/files/download";
145 $params = array (
146 "path" => $file
147 );
148
149 $curl = $client->mkCurl($url);
150 $curl->set(CURLOPT_CUSTOMREQUEST, "POST");
151 $curl->addHeader("Dropbox-API-Arg: ".json_encode($params));
152 $curl->set(CURLOPT_WRITEFUNCTION, array($this, 'callback'));
153
154 $response = $curl->exec();
155
156 fclose($this->fd);
157
158 if ($response->statusCode !== 200) return false;
159
160 return true;
161 }
162
163 public function callback ($ch, $data)
164 {
165 if (!file_exists($this->filePath)) {
166 return -1;
167 }
168
169 fwrite($this->fd, $data);
170 return strlen($data);
171 }
172
173 private function saveStateData($uploadId, $offset)
174 {
175 $token = $this->delegate->getToken();
176 $actionId = $this->delegate->getActionId();
177 $pendingStorageUploads = $this->delegate->getPendingStorageUploads();
178 $currentUploadChunksCount = $this->delegate->getCurrentUploadChunksCount();
179 $progress = $this->delegate->getProgress();
180
181 $this->state->setProgress($progress);
182 $this->state->setCurrentUploadChunksCount($currentUploadChunksCount);
183 $this->state->setStorageType(SG_STORAGE_DROPBOX);
184 $this->state->setPendingStorageUploads($pendingStorageUploads);
185 $this->state->setToken($token);
186 $this->state->setUploadId($uploadId);
187 $this->state->setOffset($offset);
188 $this->state->setAction(SG_STATE_ACTION_UPLOADING_BACKUP);
189 $this->state->setActiveDirectory($this->getActiveDirectory());
190 $this->state->setActionId($actionId);
191 $this->state->save();
192 }
193
194 public function uploadFile($filePath)
195 {
196 if (!$this->isConnected()) {
197 throw new SGExceptionForbidden('Permission denied. Authentication required.');
198 }
199
200 if (!file_exists($filePath) || !is_readable($filePath)) {
201 throw new SGExceptionNotFound('File does not exist or is not readable: '.$filePath);
202 }
203
204 $client = $this->getClient();
205 //$chunkSizeBytes = 2.0 * 1024 * 1024;
206 $chunkSizeBytes = (int)getCloudUploadChunkSize()* 1024 * 1024;
207
208 //Note: Because PHP's integer type is signed and many platforms use 32bit integers,
209 //some filesystem functions may return unexpected results for files which are larger than 2GB.
210 $fileSize = backupGuardRealFilesize($filePath);
211
212 $this->delegate->willStartUpload((int)ceil($fileSize/$chunkSizeBytes));
213
214 $handle = fopen($filePath, "rb");
215 $byteOffset = $this->state->getOffset();
216 fseek($handle, $byteOffset);
217
218 if ($this->state->getAction() == SG_STATE_ACTION_PREPARING_STATE_FILE) {
219 $data = fread($handle, $chunkSizeBytes);
220 $uploadId = $client->chunkedUploadStart($data);
221 $byteOffset += strlen($data);
222 }
223 else {
224 $uploadId = $this->state->getUploadId();
225 }
226
227 SGPing::update();
228
229 while ($byteOffset < $fileSize) {
230 $data = fread($handle, $chunkSizeBytes);
231 $client->chunkedUploadContinue($uploadId, $byteOffset, $data);
232 $byteOffset += strlen($data);
233
234 if (!$this->delegate->shouldUploadNextChunk()) {
235 fclose($handle);
236 return;
237 }
238
239 SGPing::update();
240
241 $shouldReload = $this->shouldReload();
242 if ($shouldReload && backupGuardIsReloadEnabled()) {
243 $this->saveStateData($uploadId, $byteOffset);
244 @fclose($handle);
245 $this->reload();
246 }
247 }
248
249 $activeDirectory = $this->getActiveDirectory();
250
251 $path = rtrim($activeDirectory, '/').'/'.basename($filePath);
252
253 $result = $client->chunkedUploadFinish($uploadId, $path, $byteOffset);
254 fclose($handle);
255
256 return $result;
257 }
258
259 public function fileExists($path)
260 {
261 $this->connectOffline();
262 if (!$this->isConnected()) {
263 throw new SGExceptionForbidden('Permission denied. Authentication required.');
264 }
265
266 $client = $this->getClient();
267 try {
268 $result = $client->searchFileNames(dirname($path), basename($path));
269 }
270 catch (Exception $e) {
271 return false;
272 }
273
274 return $result;
275 }
276
277 public function deleteFile($path)
278 {
279 $this->connectOffline();
280 if (!$this->isConnected()) {
281 throw new SGExceptionForbidden('Permission denied. Authentication required.');
282 }
283
284 return $this->getClient()->delete($path);
285 }
286
287 public function deleteFolder($folderName)
288 {
289 return $this->deleteFile($folderName);
290 }
291
292 private function getAppInfo()
293 {
294 $key = SG_STORAGE_DROPBOX_KEY;
295 $secret = SG_STORAGE_DROPBOX_SECRET;
296
297 $appInfo = new dbx\AppInfo($key, $secret);
298 return $appInfo;
299 }
300
301 private function getAccessToken()
302 {
303 return SGConfig::get('SG_DROPBOX_ACCESS_TOKEN');
304 }
305
306 private function setAccessToken($accessToken)
307 {
308 SGConfig::set('SG_DROPBOX_ACCESS_TOKEN', $accessToken, true);
309 }
310
311 private function getClient()
312 {
313 if (!$this->client) {
314 $accessToken = $this->getAccessToken();
315 if (!$accessToken) {
316 return false;
317 }
318
319 $appInfo = $this->getAppInfo();
320 return new dbx\Client($accessToken, SG_STORAGE_DROPBOX_CLIENT_ID, null, $appInfo->getHost());
321 }
322
323 return $this->client;
324 }
325
326 private function getWebAuth()
327 {
328 $appInfo = $this->getAppInfo();
329 $redirectUri = SG_STORAGE_DROPBOX_REDIRECT_URI;
330 $savedCSRFToken = SGConfig::get('SG_DROPBOX_CONNECTION_CSRF_TOKEN');
331 if (!empty($savedCSRFToken)) {
332 $_SESSION['dropbox-auth-csrf-token'] = $savedCSRFToken;
333 SGConfig::set('SG_DROPBOX_CONNECTION_CSRF_TOKEN', false);
334 }
335
336 $csrfTokenStore = new dbx\ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token');
337 return new dbx\WebAuth($appInfo, SG_STORAGE_DROPBOX_CLIENT_ID, $redirectUri, $csrfTokenStore, null);
338 }
339
340 private function getCurrentURL()
341 {
342 $http = backupGuardGetCurrentUrlScheme();
343 $url = $http.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
344 return $url;
345 }
346
347 private function getRefURL()
348 {
349 $refUrl = $this->getCurrentURL();
350 if (!$_SERVER['QUERY_STRING']) {
351 $refUrl .= '?';
352 }
353 else {
354 $refUrl .= '&';
355 }
356
357 return $refUrl;
358 }
359
360 private function getAuthCodeFromURL(&$cancel = false)
361 {
362 $query = $_SERVER['QUERY_STRING'];
363 if (!$query) return '';
364
365 $query = explode('&', $query);
366 $code = '';
367 foreach ($query as $q) {
368 $q = explode('=', $q);
369 if ($q[0]=='code') {
370 $code = $q[1];
371 }
372 else if ($q[0]=='cancel' && $q[1]=='1') {
373 $cancel = true;
374 break;
375 }
376 }
377
378 return $code;
379 }
380 }
381