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

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