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

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