PluginProbe
WP Database Backup – Unlimited Database & Files Backup by Backup for WP / 6.3
WP Database Backup – Unlimited Database & Files Backup by Backup for WP v6.3
7.13 7.12 trunk 1.1 2.1.1 5.9 6.0 6.1 6.10 6.11 6.12 6.12.1 6.2 6.3 6.4 6.5 6.5.1 6.6 6.7 6.8 6.9 7.0 7.0.1 7.1 7.10 All 34 releases
wp-database-backup / includes / admin / Destination / Dropbox / DropboxClient.php

DropboxClient.php in WP Database Backup – Unlimited Database & Files Backup by Backup for WP 6.3, at includes/admin/Destination/Dropbox/DropboxClient.php

934 lines 26.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php // phpcs:ignore
2 /**
3 * Class for communicating with Dropbox API V2.
4 *
5 * @package wpdbbkp
6 */
7
8 if ( ! class_exists( 'WPDBBackup_Destination_Dropbox_API' ) ) {
9 /**
10 * Destination backup.
11 *
12 * @class WPDBBackup_Destination_Dropbox_API
13 */
14 final class WPDBBackup_Destination_Dropbox_API {
15
16
17 /**
18 * URL to Dropbox API endpoint.
19 */
20 const API_URL = 'https://api.dropboxapi.com/';
21
22 /**
23 * URL to Dropbox content endpoint.
24 */
25 const API_CONTENT_URL = 'https://content.dropboxapi.com/';
26
27 /**
28 * URL to Dropbox for authentication.
29 */
30 const API_WWW_URL = 'https://www.dropbox.com/';
31
32 /**
33 * API version.
34 */
35 const API_VERSION_URL = '2/';
36
37 /**
38 * oAuth vars
39 *
40 * @var string
41 */
42 private $oauth_app_key = '';
43
44 /**
45 * @var string
46 */
47 private $oauth_app_secret = '';
48
49 /**
50 * @var string
51 */
52 private $oauth_token = '';
53
54 /**
55 * Job object for logging.
56 *
57 * @var WPDBBackup_Job
58 */
59 private $job_object;
60
61 /**
62 * Constructor function.
63 *
64 * @param string $boxtype - destination type.
65 * @param WPDBBackup_Job $job_object - Job details.
66 *
67 * @throws WPDBBackup_Destination_Dropbox_API_Exception - Exception handling.
68 */
69 public function __construct( $boxtype = 'dropbox', WPDBBackup_Job $job_object = null ) {
70 if ( 'dropbox' === $boxtype ) {
71 $this->oauth_app_key = 'cv3o964lig1qrga';
72 $this->oauth_app_secret = '7g05tjesk5fgqjk';
73 } else {
74 $this->oauth_app_key = 'cv3o964lig1qrga';
75 $this->oauth_app_secret = '7g05tjesk5fgqjk';
76 }
77
78 if ( empty( $this->oauth_app_key ) || empty( $this->oauth_app_secret ) ) {
79 throw new WPDBBackup_Destination_Dropbox_API_Exception( 'No App key or App Secret specified.' );
80 }
81
82 $this->job_object = $job_object;
83 }
84
85 // Helper methods.
86
87 /**
88 * List a folder
89 *
90 * This is a helper method to use filesListFolder and
91 * filesListFolderContinue to construct an array of files within a given
92 * folder path.
93 *
94 * @param string $path - Path.
95 *
96 * @return array
97 */
98 public function list_Folder( $path ) {
99 $files = array();
100 $result = $this->filesListFolder( array( 'path' => $path ) );
101 if ( ! $result ) {
102 return array();
103 }
104
105 $files = array_merge( $files, $result['entries'] );
106
107 $args = array( 'cursor' => $result['cursor'] );
108
109 while ( $result['has_more'] == true ) {
110 $result = $this->filesListFolderContinue( $args );
111 $files = array_merge( $files, $result['entries'] );
112 }
113
114 return $files;
115 }
116
117 /**
118 * Uploads a file to Dropbox.
119 *
120 * @param $file
121 * @param string $path
122 * @param bool $overwrite
123 *
124 * @return array
125 * @throws WPDBBackup_Destination_Dropbox_API_Exception
126 */
127 public function upload( $file, $path = '', $overwrite = true ) {
128 $file = str_replace( '\\', '/', $file );
129
130 if ( ! is_readable( $file ) ) {
131 throw new WPDBBackup_Destination_Dropbox_API_Exception( "Error: File \"$file\" is not readable or doesn't exist." );
132 }
133
134 if ( filesize( $file ) < 5242880 ) { // chunk transfer on bigger uploads
135 $output = $this->filesUpload(
136 array(
137 'contents' => file_get_contents( $file ),
138 'path' => $path,
139 'mode' => ( $overwrite ) ? 'overwrite' : 'add',
140 )
141 );
142 } else {
143 $output = $this->multipartUpload( $file, $path, $overwrite );
144 }
145
146 return $output;
147 }
148
149 /**
150 * @param $file
151 * @param string $path
152 * @param bool $overwrite
153 *
154 * @return array|mixed|string
155 * @throws WPDBBackup_Destination_Dropbox_API_Exception
156 */
157 public function multipartUpload( $file, $path = '', $overwrite = true ) {
158 $file = str_replace( '\\', '/', $file );
159
160 if ( ! is_readable( $file ) ) {
161 throw new WPDBBackup_Destination_Dropbox_API_Exception( "Error: File \"$file\" is not readable or doesn't exist." );
162 }
163
164 $chunk_size = 4194304; // 4194304 = 4MB
165
166 $file_handel = fopen( $file, 'rb' );
167 if ( ! $file_handel ) {
168 throw new WPDBBackup_Destination_Dropbox_API_Exception( 'Can not open source file for transfer.' );
169 }
170
171 if ( ! isset( $this->job_object->steps_data[ $this->job_object->step_working ]['uploadid'] ) ) {
172 // $this->job_object->log(__('Beginning new file upload session', 'backwpup'));
173 $session = $this->filesUploadSessionStart();
174 $this->job_object->steps_data[ $this->job_object->step_working ]['uploadid'] = $session['session_id'];
175 }
176 if ( ! isset( $this->job_object->steps_data[ $this->job_object->step_working ]['offset'] ) ) {
177 $this->job_object->steps_data[ $this->job_object->step_working ]['offset'] = 0;
178 }
179 if ( ! isset( $this->job_object->steps_data[ $this->job_object->step_working ]['totalread'] ) ) {
180 $this->job_object->steps_data[ $this->job_object->step_working ]['totalread'] = 0;
181 }
182
183 // seek to current position
184 if ( $this->job_object->steps_data[ $this->job_object->step_working ]['offset'] > 0 ) {
185 fseek( $file_handel, $this->job_object->steps_data[ $this->job_object->step_working ]['offset'] );
186 }
187
188 while ( $data = fread( $file_handel, $chunk_size ) ) {
189 $chunk_upload_start = microtime( true );
190
191 if ( $this->job_object->is_debug() ) {
192 $this->job_object->log( sprintf( __( 'Uploading %s of data', 'backwpup' ), size_format( strlen( $data ) ) ) );
193 }
194
195 $this->filesUploadSessionAppendV2(
196 array(
197 'contents' => $data,
198 'cursor' => array(
199 'session_id' => $this->job_object->steps_data[ $this->job_object->step_working ]['uploadid'],
200 'offset' => $this->job_object->steps_data[ $this->job_object->step_working ]['offset'],
201 ),
202 )
203 );
204 $chunk_upload_time = microtime( true ) - $chunk_upload_start;
205 $this->job_object->steps_data[ $this->job_object->step_working ]['totalread'] += strlen( $data );
206
207 // args for next chunk
208 $this->job_object->steps_data[ $this->job_object->step_working ]['offset'] += $chunk_size;
209 if ( $this->job_object->job['backuptype'] === 'archive' ) {
210 $this->job_object->substeps_done = $this->job_object->steps_data[ $this->job_object->step_working ]['offset'];
211 if ( strlen( $data ) == $chunk_size ) {
212 $time_remaining = $this->job_object->do_restart_time();
213 // calc next chunk
214 if ( $time_remaining < $chunk_upload_time ) {
215 $chunk_size = floor( $chunk_size / $chunk_upload_time * ( $time_remaining - 3 ) );
216 if ( $chunk_size < 0 ) {
217 $chunk_size = 1024;
218 }
219 if ( $chunk_size > 4194304 ) {
220 $chunk_size = 4194304;
221 }
222 }
223 }
224 }
225 $this->job_object->update_working_data();
226 // correct position
227 fseek( $file_handel, $this->job_object->steps_data[ $this->job_object->step_working ]['offset'] );
228 }
229
230 fclose( $file_handel );
231
232 $this->job_object->log( sprintf( __( 'Finishing upload session with a total of %s uploaded', 'backwpup' ), size_format( $this->job_object->steps_data[ $this->job_object->step_working ]['totalread'] ) ) );
233 $response = $this->filesUploadSessionFinish(
234 array(
235 'cursor' => array(
236 'session_id' => $this->job_object->steps_data[ $this->job_object->step_working ]['uploadid'],
237 'offset' => $this->job_object->steps_data[ $this->job_object->step_working ]['totalread'],
238 ),
239 'commit' => array(
240 'path' => $path,
241 'mode' => ( $overwrite ) ? 'overwrite' : 'add',
242 ),
243 )
244 );
245
246 unset( $this->job_object->steps_data[ $this->job_object->step_working ]['uploadid'] );
247 unset( $this->job_object->steps_data[ $this->job_object->step_working ]['offset'] );
248
249 return $response;
250 }
251
252 // Authentication
253
254 /**
255 * Set the oauth tokens for this request.
256 *
257 * @param $token
258 *
259 * @throws WPDBBackup_Destination_Dropbox_API_Exception
260 */
261 public function setOAuthTokens( $token ) {
262 if ( empty( $token['access_token'] ) ) {
263 throw new WPDBBackup_Destination_Dropbox_API_Exception( 'No oAuth token specified.' );
264 }
265
266 $this->oauth_token = $token;
267 }
268
269 /**
270 * Returns the URL to authorize the user.
271 *
272 * @return string The authorization URL
273 */
274 public function oAuthAuthorize() {
275 return self::API_WWW_URL . 'oauth2/authorize?response_type=code&client_id=' . $this->oauth_app_key;
276 }
277
278 /**
279 * Tkes the oauth code and returns the access token.
280 *
281 * @param string $code The oauth code
282 *
283 * @return array An array including the access token, account ID, and
284 * other information.
285 */
286 public function oAuthToken( $code ) {
287 return $this->request(
288 'oauth2/token',
289 array(
290 'code' => trim( $code ),
291 'grant_type' => 'authorization_code',
292 'client_id' => $this->oauth_app_key,
293 'client_secret' => $this->oauth_app_secret,
294 ),
295 'oauth'
296 );
297 }
298
299 // Auth Endpoints
300
301 /**
302 * Revokes the auth token.
303 *
304 * @return array
305 */
306 public function authTokenRevoke() {
307 return $this->request( 'auth/token/revoke' );
308 }
309
310 // Files Endpoints
311
312 /**
313 * Deletes a file.
314 *
315 * @param array $args An array of arguments
316 *
317 * @return array Information on the deleted file
318 */
319 public function filesDelete( $args ) {
320 $args['path'] = $this->formatPath( $args['path'] );
321
322 try {
323 return $this->request( 'files/delete', $args );
324 } catch ( WPDBBackup_Destination_Dropbox_API_Request_Exception $e ) {
325 $this->handleFilesDeleteError( $e->getError() );
326 }
327 }
328
329 /**
330 * Gets the metadata of a file.
331 *
332 * @param array $args An array of arguments
333 *
334 * @return array The file's metadata
335 */
336 public function filesGetMetadata( $args ) {
337 $args['path'] = $this->formatPath( $args['path'] );
338 try {
339 return $this->request( 'files/get_metadata', $args );
340 } catch ( WPDBBackup_Destination_Dropbox_API_Request_Exception $e ) {
341 $this->handleFilesGetMetadataError( $e->getError() );
342 }
343 }
344
345 /**
346 * Gets a temporary link from Dropbox to access the file.
347 *
348 * @param array $args An array of arguments
349 *
350 * @return array Information on the file and link
351 */
352 public function filesGetTemporaryLink( $args ) {
353 $args['path'] = $this->formatPath( $args['path'] );
354 try {
355 return $this->request( 'files/get_temporary_link', $args );
356 } catch ( WPDBBackup_Destination_Dropbox_API_Request_Exception $e ) {
357 $this->handleFilesGetTemporaryLinkError( $e->getError() );
358 }
359 }
360
361 /**
362 * Lists all the files within a folder.
363 *
364 * @param array $args An array of arguments
365 *
366 * @return array A list of files
367 */
368 public function filesListFolder( $args ) {
369 $args['path'] = $this->formatPath( $args['path'] );
370 try {
371 return $this->request( 'files/list_folder', $args );
372 } catch ( WPDBBackup_Destination_Dropbox_API_Request_Exception $e ) {
373 $this->handleFilesListFolderError( $e->getError() );
374 }
375 }
376
377 /**
378 * Continue to list more files.
379 *
380 * When a folder has a lot of files, the API won't return all at once.
381 * So this method is to fetch more of them.
382 *
383 * @param array $args An array of arguments
384 *
385 * @return array An array of files
386 */
387 public function filesListFolderContinue( $args ) {
388 try {
389 return $this->request( 'files/list_folder/continue', $args );
390 } catch ( WPDBBackup_Destination_Dropbox_API_Request_Exception $e ) {
391 $this->handleFilesListFolderContinueError( $e->getError() );
392 }
393 }
394
395 /**
396 * Uploads a file to Dropbox.
397 *
398 * The file must be no greater than 150 MB.
399 *
400 * @param array $args An array of arguments
401 *
402 * @return array The uploaded file's information.
403 */
404 public function filesUpload( $args ) {
405 $args['path'] = $this->formatPath( $args['path'] );
406
407 if ( isset( $args['client_modified'] )
408 && $args['client_modified'] instanceof DateTime
409 ) {
410 $args['client_modified'] = $args['client_modified']->format( 'Y-m-d\TH:m:s\Z' );
411 }
412
413 try {
414 return $this->request( 'files/upload', $args, 'upload' );
415 } catch ( WPDBBackup_Destination_Dropbox_API_Request_Exception $e ) {
416 $this->handleFilesUploadError( $e->getError() );
417 }
418 }
419
420 /**
421 * Append more data to an uploading file
422 *
423 * @param array $args An array of arguments
424 */
425 public function filesUploadSessionAppendV2( $args ) {
426 try {
427 return $this->request(
428 'files/upload_session/append_v2',
429 $args,
430 'upload'
431 );
432 } catch ( WPDBBackup_Destination_Dropbox_API_Request_Exception $e ) {
433 $error = $e->getError();
434
435 // See if we can fix the error first
436 if ( $error['.tag'] == 'incorrect_offset' ) {
437 $args['cursor']['offset'] = $error['correct_offset'];
438 return $this->request(
439 'files/upload_session/append_v2',
440 $args,
441 'upload'
442 );
443 }
444
445 // Otherwise, can't fix
446 $this->handleFilesUploadSessionLookupError( $error );
447 }
448 }
449
450 /**
451 * Finish an upload session.
452 *
453 * @param array $args
454 *
455 * @return array Information on the uploaded file
456 */
457 public function filesUploadSessionFinish( $args ) {
458 $args['commit']['path'] = $this->formatPath( $args['commit']['path'] );
459
460 try {
461 return $this->request( 'files/upload_session/finish', $args, 'upload' );
462 } catch ( WPDBBackup_Destination_Dropbox_API_Request_Exception $e ) {
463 $error = $e->getError();
464 if ( $error['.tag'] == 'lookup_failed' ) {
465 if ( $error['lookup_failed']['.tag'] == 'incorrect_offset' ) {
466 $args['cursor']['offset'] = $error['lookup_failed']['correct_offset'];
467 return $this->request( 'files/upload_session/finish', $args, 'upload' );
468 }
469 }
470 $this->handleFilesUploadSessionFinishError( $e->getError() );
471 }
472 }
473
474 /**
475 * Starts an upload session.
476 *
477 * When a file larger than 150 MB needs to be uploaded, then this API
478 * endpoint is used to start a session to allow the file to be uploaded in
479 * chunks.
480 *
481 * @param array $args
482 *
483 * @return array An array containing the session's ID.
484 */
485 public function filesUploadSessionStart( $args = array() ) {
486 return $this->request( 'files/upload_session/start', $args, 'upload' );
487 }
488
489 // Users endpoints
490
491 /**
492 * Get user's current account info.
493 *
494 * @return array
495 */
496 public function usersGetCurrentAccount() {
497 return $this->request( 'users/get_current_account' );
498 }
499
500 /**
501 * Get quota info for this user.
502 *
503 * @return array
504 */
505 public function usersGetSpaceUsage() {
506 return $this->request( 'users/get_space_usage' );
507 }
508
509 // Private functions
510
511 /**
512 * @param $url
513 * @param array $args
514 * @param string $endpointFormat
515 * @param string $data
516 * @param bool $echo
517 *
518 * @throws WPDBBackup_Destination_Dropbox_API_Exception
519 * @return array|mixed|string
520 */
521 private function request( $endpoint, $args = array(), $endpointFormat = 'rpc', $echo = false ) {
522 // Get complete URL
523 switch ( $endpointFormat ) {
524 case 'oauth':
525 $url = self::API_URL . $endpoint;
526 break;
527
528 case 'rpc':
529 $url = self::API_URL . self::API_VERSION_URL . $endpoint;
530 break;
531
532 case 'upload':
533 case 'download':
534 $url = self::API_CONTENT_URL . self::API_VERSION_URL . $endpoint;
535 break;
536 }
537
538 if ( $this->job_object && $this->job_object->is_debug() && $endpointFormat != 'oauth' ) {
539 $message = 'Call to ' . $endpoint;
540 $parameters = $args;
541 if ( isset( $parameters['contents'] ) ) {
542 $message .= ', with ' . size_format( strlen( $parameters['contents'] ) ) . ' of data';
543 unset( $parameters['contents'] );
544 }
545 if ( ! empty( $parameters ) ) {
546 $message .= ', with parameters: ' . json_encode( $parameters );
547 }
548 $this->job_object->log( $message );
549 }
550
551 // Build cURL Request
552 // $ch = curl_init();
553 // curl_setopt($ch, CURLOPT_URL, $url);
554 // curl_setopt($ch, CURLOPT_POST, true);
555
556 $headers['Expect'] = '';
557
558 if ( $endpointFormat != 'oauth' ) {
559 $headers['Authorization'] = 'Bearer ' . $this->oauth_token['access_token'];
560 }
561
562 if ( $endpointFormat == 'oauth' ) {
563 $POSTFIELDS = http_build_query( $args, null, '&' );
564 // curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($args, null, '&'));
565 $headers['Content-Type'] = 'application/x-www-form-urlencoded';
566 } elseif ( $endpointFormat == 'rpc' ) {
567 if ( ! empty( $args ) ) {
568 $POSTFIELDS = $args;
569 } else {
570 $POSTFIELDS = array();
571 }
572 $headers['Content-Type'] = 'application/json';
573 } elseif ( $endpointFormat == 'upload' ) {
574 if ( isset( $args['contents'] ) ) {
575 $POSTFIELDS = $args['contents'];
576 unset( $args['contents'] );
577 } else {
578 $POSTFIELDS = array();
579 }
580 $headers['Content-Type'] = 'application/octet-stream';
581 if ( ! empty( $args ) ) {
582 $headers['Dropbox-API-Arg'] = json_encode( $args );
583 } else {
584 $headers['Dropbox-API-Arg'] = '{}';
585 }
586 } else {
587 // curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
588 $headers['Dropbox-API-Arg'] = json_encode( $args );
589 }
590 $Agent = 'WP-Database-Backup/V.4.5.1; WordPress/4.8.2; ' . home_url();
591 // curl_setopt($ch, CURLOPT_USERAGENT, $Agent);
592 // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
593 // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
594 // curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
595 $output = '';
596 if ( $echo ) {
597 // echo curl_exec($ch);
598 } else {
599 // curl_setopt($ch, CURLOPT_HEADER, true);
600 // $responce = explode("\r\n\r\n", curl_exec($ch), 2);
601 // if (!empty($responce[1])) {
602 // $output = json_decode($responce[1], true);
603 // }
604 }
605 // $status = curl_getinfo($ch);
606
607 $request = new WP_Http();
608 $result = $request->request(
609 $url,
610 array(
611 'method' => 'POST',
612 'body' => $POSTFIELDS,
613 'user-agent' => $Agent,
614 'sslverify' => false,
615 'headers' => $headers,
616 )
617 );
618 $responce = wp_remote_retrieve_body( $result );
619 $output = json_decode( $responce, true );
620
621 // Handle error codes
622 // If 409 (endpoint-specific error), let the calling method handle it
623
624 // Code 429 = rate limited
625 if ( wp_remote_retrieve_response_code( $result ) == 429 ) {
626 $wait = 0;
627 if ( preg_match( "/retry-after:\s*(.*?)\r/i", $responce[0], $matches ) ) {
628 $wait = trim( $matches[1] );
629 }
630 // only wait if we get a retry-after header.
631 if ( ! empty( $wait ) ) {
632 trigger_error( sprintf( '(429) Your app is making too many requests and is being rate limited. Error 429 can be triggered on a per-app or per-user basis. Wait for %d seconds.', $wait ), E_USER_WARNING );
633 sleep( $wait );
634 } else {
635 throw new WPDBBackup_Destination_Dropbox_API_Exception( '(429) This indicates a transient server error.' );
636 }
637
638 // redo request
639 return $this->request( $url, $args, $endpointFormat, $data, $echo );
640 } // We can't really handle anything else, so throw it back to the caller
641 elseif ( isset( $output['error'] ) || wp_remote_retrieve_response_code( $result ) >= 400 ) {
642 $code = wp_remote_retrieve_response_code( $result );
643 // if (curl_errno($ch) != 0) {
644 // $message = '(' . curl_errno($ch) . ') ' . curl_error($ch);
645 // $code = 0;
646 // } else
647 if ( wp_remote_retrieve_response_code( $result ) == 400 ) {
648 $message = '(400) Bad input parameter: ' . strip_tags( $responce[1] );
649 } elseif ( wp_remote_retrieve_response_code( $result ) == 401 ) {
650 $message = '(401) Bad or expired token. This can happen if the user or Dropbox revoked or expired an access token. To fix, you should re-authenticate the user.';
651 } elseif ( wp_remote_retrieve_response_code( $result ) == 409 ) {
652 $message = $output['error_summary'];
653 } elseif ( wp_remote_retrieve_response_code( $result ) >= 500 ) {
654 $message = '(' . wp_remote_retrieve_response_code( $result ) . ') There is an error on the Dropbox server.';
655 } else {
656 $message = '(' . wp_remote_retrieve_response_code( $result ) . ') Invalid response.';
657 }
658 if ( $this->job_object && $this->job_object->is_debug() ) {
659 $this->job_object->log( 'Response with header: ' . $responce[0] );
660 }
661 // throw new WPDBBackup_Destination_Dropbox_API_Request_Exception($message, $code, null, isset($output['error']) ? $output['error'] : null);
662 } else {
663 // curl_close($ch);
664 if ( ! is_array( $output ) ) {
665 return $responce[1];
666 } else {
667 return $output;
668 }
669 }
670 }
671
672 /**
673 * Formats a path to be valid for Dropbox.
674 *
675 * @param string $path
676 *
677 * @return string The formatted path
678 */
679 private function formatPath( $path ) {
680 if ( ! empty( $path ) && substr( $path, 0, 1 ) != '/' ) {
681 $path = "/$path";
682 } elseif ( $path == '/' ) {
683 $path = '';
684 }
685
686 return $path;
687 }
688
689 // Error Handlers
690
691 private function handleFilesDeleteError( $error ) {
692 switch ( $error['.tag'] ) {
693 case 'path_lookup':
694 $this->handleFilesLookupError( $error['path_lookup'] );
695 break;
696
697 case 'path_write':
698 $this->handleFilesWriteError( $error['path_write'] );
699 break;
700
701 case 'other':
702 trigger_error( 'Could not delete file.', E_USER_WARNING );
703 break;
704 }
705 }
706
707 private function handleFilesGetMetadataError( $error ) {
708 switch ( $error['.tag'] ) {
709 case 'path':
710 $this->handleFilesLookupError( $error['path'] );
711 break;
712
713 case 'other':
714 trigger_error( 'Cannot look up file metadata.', E_USER_WARNING );
715 break;
716 }
717 }
718
719 private function handleFilesGetTemporaryLinkError( $error ) {
720 switch ( $error['.tag'] ) {
721 case 'path':
722 $this->handleFilesLookupError( $error['path'] );
723 break;
724
725 case 'other':
726 trigger_error( 'Cannot get temporary link.', E_USER_WARNING );
727 break;
728 }
729 }
730
731 private function handleFilesListFolderError( $error ) {
732 switch ( $error['.tag'] ) {
733 case 'path':
734 $this->handleFilesLookupError( $error['path'] );
735 break;
736
737 case 'other':
738 trigger_error( 'Cannot list files in folder.', E_USER_WARNING );
739 break;
740 }
741 }
742
743 private function handleFilesListFolderContinueError( $error ) {
744 switch ( $error['.tag'] ) {
745 case 'path':
746 $this->handleFilesLookupError( $error['path'] );
747 break;
748
749 case 'reset':
750 trigger_error( 'This cursor has been invalidated.', E_USER_WARNING );
751 break;
752
753 case 'other':
754 trigger_error( 'Cannot list files in folder.', E_USER_WARNING );
755 break;
756 }
757 }
758
759 private function handleFilesLookupError( $error ) {
760 switch ( $error['.tag'] ) {
761 case 'malformed_path':
762 trigger_error( 'The path was malformed.', E_USER_WARNING );
763 break;
764
765 case 'not_found':
766 trigger_error( 'File could not be found.', E_USER_WARNING );
767 break;
768
769 case 'not_file':
770 trigger_error( 'That is not a file.', E_USER_WARNING );
771 break;
772
773 case 'not_folder':
774 trigger_error( 'That is not a folder.', E_USER_WARNING );
775 break;
776
777 case 'restricted_content':
778 trigger_error( 'This content is restricted.', E_USER_WARNING );
779 break;
780
781 case 'invalid_path_root':
782 trigger_error( 'Path root is invalid.', E_USER_WARNING );
783 break;
784
785 case 'other':
786 trigger_error( 'File could not be found.', E_USER_WARNING );
787 break;
788 }
789 }
790
791 private function handleFilesUploadSessionFinishError( $error ) {
792 switch ( $error['.tag'] ) {
793 case 'lookup_failed':
794 $this->handleFilesUploadSessionLookupError(
795 $error['lookup_failed']
796 );
797 break;
798
799 case 'path':
800 $this->handleFilesWriteError( $error['path'] );
801 break;
802
803 case 'too_many_shared_folder_targets':
804 trigger_error( 'Too many shared folder targets.', E_USER_WARNING );
805 break;
806
807 case 'other':
808 trigger_error( 'The file could not be uploaded.', E_USER_WARNING );
809 break;
810 }
811 }
812
813 private function handleFilesUploadSessionLookupError( $error ) {
814 switch ( $error['.tag'] ) {
815 case 'not_found':
816 trigger_error( 'Session not found.', E_USER_WARNING );
817 break;
818
819 case 'incorrect_offset':
820 trigger_error(
821 'Incorrect offset given. Correct offset is ' .
822 $error['correct_offset'] . '.',
823 E_USER_WARNING
824 );
825 break;
826
827 case 'closed':
828 trigger_error(
829 'This session has been closed already.',
830 E_USER_WARNING
831 );
832 break;
833
834 case 'not_closed':
835 trigger_error( 'This session is not closed.', E_USER_WARNING );
836 break;
837
838 case 'other':
839 trigger_error(
840 'Could not look up the file session.',
841 E_USER_WARNING
842 );
843 break;
844 }
845 }
846
847 private function handleFilesUploadError( $error ) {
848 switch ( $error['.tag'] ) {
849 case 'path':
850 $this->handleFilesUploadWriteFailed( $error['path'] );
851 break;
852
853 case 'other':
854 trigger_error( 'There was an unknown error when uploading the file.', E_USER_WARNING );
855 break;
856 }
857 }
858
859 private function handleFilesUploadWriteFailed( $error ) {
860 $this->handleFilesWriteError( $error['reason'] );
861 }
862
863 private function handleFilesWriteError( $error ) {
864 $message = '';
865
866 // Type of error
867 switch ( $error['.tag'] ) {
868 case 'malformed_path':
869 $message = 'The path was malformed.';
870 break;
871
872 case 'conflict':
873 $message = 'Cannot write to the target path due to conflict.';
874 break;
875
876 case 'no_write_permission':
877 $message = 'You do not have permission to save to this location.';
878 break;
879
880 case 'insufficient_space':
881 $message = 'You do not have enough space in your Dropbox.';
882 break;
883
884 case 'disallowed_name':
885 $message = 'The given name is disallowed by Dropbox.';
886 break;
887
888 case 'team_folder':
889 $message = 'Unable to modify team folders.';
890 break;
891
892 case 'other':
893 $message = 'There was an unknown error when uploading the file.';
894 break;
895 }
896
897 trigger_error( $message, E_USER_WARNING );
898 }
899
900 }
901 }
902 /**
903 *
904 */
905 if ( ! class_exists( 'WPDBBackup_Destination_Dropbox_API_Exception' ) ) {
906 class WPDBBackup_Destination_Dropbox_API_Exception extends Exception {
907
908
909 }
910 }
911 /**
912 * Exception thrown when there is an error in the Dropbox request.
913 */
914 if ( ! class_exists( 'WPDBBackup_Destination_Dropbox_API_Request_Exception' ) ) {
915 class WPDBBackup_Destination_Dropbox_API_Request_Exception extends WPDBBackup_Destination_Dropbox_API_Exception {
916
917
918 /**
919 * The request error array.
920 */
921 protected $error;
922
923 public function __construct( $message, $code = 0, $previous = null, $error = null ) {
924 $this->error = $error;
925 parent::__construct( $message, $code, $previous );
926 }
927
928 public function getError() {
929 return $this->error;
930 }
931
932 }
933 }
934