PluginProbe
WP Database Backup – Unlimited Database & Files Backup by Backup for WP / 6.11
WP Database Backup – Unlimited Database & Files Backup by Backup for WP v6.11
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.11, at includes/admin/Destination/Dropbox/DropboxClient.php

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