PATH:
home
/
thebhoeo
/
.trash
/
backwpup
/
inc
<?php use WPMedia\BackWPup\Backup\FailureContext\Dropbox\DropboxFailureContextMapper; use WPMedia\BackWPup\Backup\ReasonCode; /** * This class allows the user to back up to Dropbox. * * Documentation: https://www.dropbox.com/developers/documentation/http/overview */ class BackWPup_Destination_Dropbox extends BackWPup_Destinations { /** * Service name * * @var string */ private const SERVICE_NAME = 'Dropbox'; /** * Dropbox. * * Instance of Dropbox API * * @var BackWPup_Destination_Dropbox_API|null */ protected $dropbox; /** * Default Options. * * @return array The default options for dropbox */ public function option_defaults(): array { return [ 'dropboxtoken' => [], 'dropboxroot' => 'sandbox', 'dropboxmaxbackups' => 15, 'dropboxsyncnodelete' => true, 'dropboxdir' => '/' . trailingslashit( sanitize_file_name( get_bloginfo( 'name' ) ) ), ]; } /** * {@inheritdoc} * * @param int|array $jobid the job id. * * @throws BackWPup_Destination_Dropbox_API_Exception If the destionation instance cannot be created. * * @phpcs:disable WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */ public function edit_form_post_save( $jobid ): void { $jobids = (array) $jobid; // Bet auth. if ( ! empty( $_POST['sandbox_code'] ) ) { try { $dropbox = new BackWPup_Destination_Dropbox_API( 'sandbox' ); $dropboxtoken = $dropbox->o_auth_token( $_POST['sandbox_code'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput foreach ( $jobids as $id ) { BackWPup_Option::update( $id, 'dropboxtoken', $dropboxtoken ); BackWPup_Option::update( $id, 'dropboxroot', 'sandbox' ); } } catch ( Exception $e ) { BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(), true ); throw $e; } } if ( ! empty( $_POST['dropbbox_code'] ) ) { try { $dropbox = new BackWPup_Destination_Dropbox_API( 'dropbox' ); $dropboxtoken = $dropbox->o_auth_token( $_POST['dropbbox_code'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput foreach ( $jobids as $id ) { BackWPup_Option::update( $id, 'dropboxtoken', $dropboxtoken ); BackWPup_Option::update( $id, 'dropboxroot', 'dropbox' ); } } catch ( Exception $e ) { BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(), true ); throw $e; } } $_POST['dropboxdir'] = trailingslashit( str_replace( '//', '/', str_replace( '\\', '/', trim( sanitize_text_field( $_POST['dropboxdir'] ) ) ) ) // phpcs:ignore WordPress.Security ); if ( '/' === $_POST['dropboxdir'] ) { $_POST['dropboxdir'] = ''; } // Delete auth. if ( ! empty( $_POST['delete_auth'] ) ) { // We need to check if the token is used on another job. $temp_jobs_ids = BackWPup_Option::get_job_ids(); $job_token = BackWPup_Option::get( $jobids[0], 'dropboxtoken' ); $is_job_token_used_on_other_job = false; foreach ( $temp_jobs_ids as $id ) { // We need to cast the id to int, because the job id is sometimes a string. if ( (int) $id !== (int) $jobids[0] && BackWPup_Option::get( $id, 'dropboxtoken' ) === $job_token ) { $is_job_token_used_on_other_job = true; break; } } // If the token is used on another job, we don't need to revoke it. if ( ! $is_job_token_used_on_other_job ) { // Try to revoke the token on dropbox. try { $dropbox = $this->get_dropbox( $jobids[0] ); $dropbox->auth_token_revoke(); } catch ( Exception $e ) { BackWPup_Admin::message( sprintf( // translators: %s is the error message. __( 'Failed to revoke Dropbox token: %s', 'backwpup' ), esc_html( $e->getMessage() ) ), true ); } } // We delete the token from the jobs and seet the root to sandbox. foreach ( $jobids as $id ) { BackWPup_Option::update( $id, 'dropboxtoken', [] ); BackWPup_Option::update( $id, 'dropboxroot', 'sandbox' ); } } // Save settings. foreach ( $jobids as $id ) { BackWPup_Option::update( $id, 'dropboxsyncnodelete', ! empty( $_POST['dropboxsyncnodelete'] ) ); BackWPup_Option::update( $id, 'dropboxmaxbackups', isset( $_POST['dropboxmaxbackups'] ) && is_numeric( $_POST['dropboxmaxbackups'] ) ? absint( $_POST['dropboxmaxbackups'] ) : $this->option_defaults()['dropboxmaxbackups'] ); BackWPup_Option::update( $id, 'dropboxdir', $_POST['dropboxdir'] ); } } // phpcs:enable /** * Delete File. * * @param string $jobdest The destination for this job. * @param string $backupfile The file to delete. */ public function file_delete( string $jobdest, string $backupfile ): void { $files = get_site_transient( 'backwpup_' . strtolower( $jobdest ) ); [$jobid, $dest] = explode( '_', $jobdest ); try { $dropbox = $this->get_dropbox( $jobid ); $dropbox->files_delete( [ 'path' => $backupfile ] ); // Update file list. foreach ( $files as $key => $file ) { if ( is_array( $file ) && $backupfile === $file['file'] ) { unset( $files[ $key ] ); } } unset( $dropbox ); } catch ( Exception $e ) { BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(), true ); } $key = 'backwpup_' . strtolower( $jobdest ); /** * Fires after jobs is updated. * * @since 5.2.1 * * @param string $key The newly backup reference key. * @param array $files An array of files data. */ do_action( 'backwpup_update_backup_history', $key, $files ); } /** * File Update List. * * Update the list of files in the transient. * * @param BackWPup_Job|int $job Either the job object or job ID. * @param bool $delete Whether to delete old backups. */ public function file_update_list( $job, bool $delete = false ): void { if ( $job instanceof BackWPup_Job ) { $job_object = $job; $jobid = $job->job['jobid']; } else { $job_object = null; $jobid = $job; } $backupfilelist = []; $filecounter = 0; $files = []; $dropbox = $this->get_dropbox( $jobid ); $files_list = $dropbox->list_folder( BackWPup_Option::get( $jobid, 'dropboxdir' ) ); foreach ( $files_list as $data ) { if ( 'file' === $data['.tag'] && $this->is_backup_owned_by_job( $data['name'], $jobid ) ) { $file = $data['name']; if ( $this->is_backup_archive( $file ) ) { $backupfilelist[ strtotime( (string) $data['server_modified'] ) ] = $file; } $files[ $filecounter ]['folder'] = dirname( (string) $data['path_display'] ); $files[ $filecounter ]['file'] = $data['path_display']; $files[ $filecounter ]['filename'] = $data['name']; $files[ $filecounter ]['downloadurl'] = network_admin_url( 'admin.php?page=backwpupbackups&action=downloaddropbox&file=' . $data['path_display'] . '&local_file=' . $data['name'] . '&jobid=' . $jobid ); $files[ $filecounter ]['filesize'] = $data['size']; $files[ $filecounter ]['time'] = strtotime( (string) $data['server_modified'] ); ++$filecounter; } } if ( $delete && $job_object && BackWPup_Option::get( $jobid, 'dropboxmaxbackups' ) > 0 ) { // Delete old backups. if ( count( $backupfilelist ) > $job_object->job['dropboxmaxbackups'] ) { ksort( $backupfilelist ); $numdeltefiles = 0; $deleted_files = []; while ( ! empty( $backupfilelist ) ) { $file = array_shift( $backupfilelist ); if ( count( $backupfilelist ) < $job_object->job['dropboxmaxbackups'] ) { break; } $response = $dropbox->files_delete( [ 'path' => $job_object->job['dropboxdir'] . $file ] ); // Delete files on Cloud. foreach ( $files as $key => $filedata ) { if ( $filedata['file'] === $job_object->job['dropboxdir'] . $file && ! empty( $response ) ) { $deleted_files[] = $filedata['filename']; unset( $files[ $key ] ); break; } } ++$numdeltefiles; } if ( $numdeltefiles > 0 ) { $job_object->log( sprintf( // translators: %d: number of files. _n( '%d file deleted from Dropbox', '%d files deleted on Dropbox', $numdeltefiles, 'backwpup' ), $numdeltefiles ), E_USER_NOTICE ); } parent::remove_file_history_from_database( $deleted_files, 'DROPBOX' ); } } $key = 'backwpup_' . $jobid . '_dropbox'; /** * Fires after jobs is updated. * * @since 5.2.1 * * @param string $key The newly backup reference key. * @param array $files An array of files data. */ do_action( 'backwpup_update_backup_history', $key, $files ); } /** * Run the archive job for Dropbox. * * @param BackWPup_Job $job_object Job object. * * @return bool */ public function job_run_archive( BackWPup_Job $job_object ): bool { $job_object->substeps_todo = 2 + $job_object->backup_filesize; if ( $job_object->steps_data[ $job_object->step_working ]['SAVE_STEP_TRY'] !== $job_object->steps_data[ $job_object->step_working ]['STEP_TRY'] ) { $job_object->log( sprintf( /* translators: %d: attempt number. */ __( '%d. Try to send backup file to Dropbox …', 'backwpup' ), $job_object->steps_data[ $job_object->step_working ]['STEP_TRY'] ) ); } try { $dropbox = $this->get_dropbox( $job_object ); // Get account info. if ( $job_object->steps_data[ $job_object->step_working ]['SAVE_STEP_TRY'] !== $job_object->steps_data[ $job_object->step_working ]['STEP_TRY'] ) { $info = $dropbox->users_get_current_account(); if ( ! empty( $info['account_id'] ) ) { if ( $job_object->is_debug() ) { $user = $info['name']['display_name'] . ' (' . $info['email'] . ')'; } else { $user = $info['name']['display_name']; } $job_object->log( sprintf( /* translators: %s: Dropbox user. */ __( 'Authenticated with Dropbox of user: %s', 'backwpup' ), $user ) ); // Quota. if ( $job_object->is_debug() ) { $quota = $dropbox->users_get_space_usage(); $dropbox_free_space = $this->free_space_from_quota( is_array( $quota ) ? $quota : [] ); if ( null !== $dropbox_free_space ) { $job_object->log( sprintf( /* translators: %s: available space. */ __( '%s available on your Dropbox', 'backwpup' ), size_format( $dropbox_free_space, 2 ) ) ); } else { $job_object->log( __( 'Dropbox free space could not be determined from the quota response.', 'backwpup' ) ); } } } else { $job_object->log( __( 'Not Authenticated with Dropbox!', 'backwpup' ), E_USER_ERROR, __FILE__, __LINE__, [ 'reason_code' => ReasonCode::REASON_INCORRECT_LOGIN, 'destination' => 'DROPBOX', 'provider_code' => 'not_authenticated', ] ); return false; } $job_object->log( __( 'Uploading to Dropbox …', 'backwpup' ) ); } // Put the file. if ( $job_object->substeps_done <= $job_object->backup_filesize ) { // Only if upload not complete. $errors_before = $job_object->errors; $response = $dropbox->upload( $job_object->backup_folder . $job_object->backup_file, $job_object->job['dropboxdir'] . $job_object->backup_file ); if ( ! is_array( $response ) || ! isset( $response['size'] ) ) { if ( $job_object->errors > $errors_before ) { return false; } $fallback = $this->upload_failure_fallback( $job_object, $dropbox ); $message = $fallback['message']; $context = $fallback['context']; if ( is_array( $response ) && ! empty( $response['error'] ) ) { $message .= ' ' . $response['error']; } $job_object->log( $message, E_USER_ERROR, __FILE__, __LINE__, $context ); return false; } if ( $job_object->backup_filesize === $response['size'] ) { if ( ! empty( $job_object->job['jobid'] ) ) { BackWPup_Option::update( $job_object->job['jobid'], 'lastbackupdownloadurl', network_admin_url( 'admin.php' ) . '?page=backwpupbackups&action=downloaddropbox&file=' . ltrim( (string) $response['path_display'], '/' ) . '&jobid=' . $job_object->job['jobid'] ); } $job_object->substeps_done = 1 + $job_object->backup_filesize; $job_object->log( sprintf( /* translators: %s: destination path. */ __( 'Backup transferred to %s', 'backwpup' ), $response['path_display'] ), E_USER_NOTICE ); } else { if ( $response['size'] !== $job_object->backup_filesize ) { $job_object->log( __( 'Uploaded file size and local file size don\'t match.', 'backwpup' ), E_USER_ERROR ); } else { $job_object->log( sprintf( /* translators: %s: destination service name. */ __( 'Error transfering backup to %s.', 'backwpup' ) . ' ' . $response['error'], __( 'Dropbox', 'backwpup' ) ), E_USER_ERROR ); } return false; } } $this->file_update_list( $job_object, true ); } catch ( Exception $e ) { $job_object->log( sprintf( /* translators: %s: error message. */ __( 'Dropbox API: %s', 'backwpup' ), $e->getMessage() ), E_USER_ERROR, $e->getFile(), $e->getLine(), $this->error_context( $e ) ); return false; } ++$job_object->substeps_done; return true; } /** * Check if Dropbox destination can run. * * @param array $job_settings * @param bool $test_connection Job settings. * * @return bool */ public function can_run( array $job_settings, bool $test_connection = true ): bool { return ! ( empty( $job_settings['dropboxtoken'] ) ); } /** * Get Dropbox. * * Gets the Dropbox API instance. * * @param BackWPup_Job|int $job Either the job object or job ID. * * @return BackWPup_Destination_Dropbox_API */ protected function get_dropbox( $job ): BackWPup_Destination_Dropbox_API { if ( ! $this->dropbox ) { if ( $job instanceof BackWPup_Job ) { $this->dropbox = new BackWPup_Destination_Dropbox_API( $job->job['dropboxroot'], $job ); $jobid = $job->job['jobid']; $token = $job->job['dropboxtoken']; } else { $this->dropbox = new BackWPup_Destination_Dropbox_API( BackWPup_Option::get( $job, 'dropboxroot' ) ); $jobid = $job; $token = BackWPup_Option::get( $job, 'dropboxtoken' ); } $this->dropbox->set_o_auth_tokens( $token, function ( $token ) use ( $jobid ): void { BackWPup_Option::update( $jobid, 'dropboxtoken', $token ); } ); } return $this->dropbox; } /** * Get service name */ public function get_service_name(): string { return self::SERVICE_NAME; } /** * Build error context for Dropbox errors. * * @param \Exception $e Exception object. * @return array */ private function error_context( \Exception $e ): array { if ( $e instanceof BackWPup_Destination_Dropbox_API_Exception ) { $context = $e->getContext(); if ( ! empty( $context ) ) { return $context; } } $mapper = new DropboxFailureContextMapper(); return $mapper->map_reason( ReasonCode::REASON_UNKNOWN_ERROR ); } /** * Build the narrow upload fallback used only when the API layer did not log a structured failure. * * @param BackWPup_Job $job_object Current job object. * @param BackWPup_Destination_Dropbox_API $dropbox Dropbox API instance. * @return array */ private function upload_failure_fallback( BackWPup_Job $job_object, BackWPup_Destination_Dropbox_API $dropbox ): array { $fallback = [ 'message' => __( 'Dropbox API: Upload failed.', 'backwpup' ), 'context' => [ 'destination' => 'DROPBOX', ], ]; try { $quota = $dropbox->users_get_space_usage(); } catch ( Exception $exception ) { $quota = null; } $free_space = is_array( $quota ) ? $this->free_space_from_quota( $quota ) : null; if ( null !== $free_space && $job_object->backup_filesize > $free_space ) { $fallback = [ 'message' => __( 'You do not have enough space in your Dropbox.', 'backwpup' ), 'context' => [ 'reason_code' => ReasonCode::REASON_NOT_ENOUGH_STORAGE, 'destination' => 'DROPBOX', 'provider_code' => 'insufficient_space', ], ]; } return $fallback; } /** * Extract available Dropbox space from the quota payload. * * @param array $quota Dropbox quota payload. * @return int|null */ private function free_space_from_quota( array $quota ): ?int { if ( ! isset( $quota['allocation']['allocated'], $quota['used'] ) || ! is_numeric( $quota['allocation']['allocated'] ) || ! is_numeric( $quota['used'] ) ) { return null; } return max( 0, (int) $quota['allocation']['allocated'] - (int) $quota['used'] ); } }
[-] class-system-tests-runner.php
[edit]
[-] class-jobtype-dbdump.php
[edit]
[-] class-destination-rsc.php
[edit]
[-] class-encryption.php
[edit]
[-] class-destination-downloader-factory.php
[edit]
[-] class-destination-downloader-interface.php
[edit]
[-] class-destination-ftp-type-ftp.php
[edit]
[-] class-path-fixer.php
[edit]
[-] class-message-box.php
[edit]
[-] class-destination-dropbox-api.php
[edit]
[-] class-option.php
[edit]
[-] class-destination-dropbox-api-request-exception.php
[edit]
[-] class-page-about.php
[edit]
[-] class-migrate.php
[edit]
[-] class-system-requirements.php
[edit]
[-] class-adminbar.php
[edit]
[-] class-msazure-destination-configuration.php
[edit]
[-] class-job.php
[edit]
[-] class-destination-ftp-type-exception.php
[edit]
[-] class-destination-sugarsync-api.php
[edit]
[-] class-download-file-interface.php
[edit]
[-] class-encryption-fallback.php
[edit]
[-] BackWPup.php
[edit]
[-] class-page-backwpup.php
[edit]
[-] class-destination-downloader-data.php
[edit]
[-] class-mysqldump-exception.php
[edit]
[-] class-s3-destination.php
[edit]
[-] class-destination-ftp.php
[edit]
[-] class-cron.php
[edit]
[+]
Notice
[-] class-destination-downloader.php
[edit]
[-] class-destinations.php
[edit]
[-] class-destination-ftp-downloader.php
[edit]
[-] class-destination-dropbox-downloader.php
[edit]
[-] class-download-handler.php
[edit]
[-] class-destination-dropbox.php
[edit]
[-] class-system-tests.php
[edit]
[-] class-destination-folder-downloader.php
[edit]
[-] class-destination-ftp-type.php
[edit]
[-] class-thirdparties.php
[edit]
[-] class-jobtype-wpplugin.php
[edit]
[-] class-directory.php
[edit]
[-] class-recursive-directory.php
[edit]
[-] class-destination-msazure-downloader.php
[edit]
[-] class-destination-connect-interface.php
[edit]
[-] class-install.php
[edit]
[-] class-admin.php
[edit]
[-] class-jobtype-file.php
[edit]
[-] functions.php
[edit]
[+]
Utils
[+]
ThirdParty
[-] class-destination-s3-downloader.php
[edit]
[-] class-destination-rsc-downloader.php
[edit]
[-] class-destination-sugarsync-downloader.php
[edit]
[-] class-destination-email.php
[edit]
[+]
..
[-] class-mysqldump.php
[edit]
[-] class-page-firstbackup.php
[edit]
[-] class-jobtype-wpexp.php
[edit]
[-] class-jobtype-dbcheck.php
[edit]
[-] class-file.php
[edit]
[-] class-sanitize-path.php
[edit]
[+]
Settings
[-] class-destination-s3.php
[edit]
[-] class-page-logs.php
[edit]
[-] class-factory-exception.php
[edit]
[-] class-page-restore.php
[edit]
[+]
dependencies
[-] class-create-archive-exception.php
[edit]
[-] class-page-editjob.php
[edit]
[-] class-page-backups.php
[edit]
[-] class-destination-dropbox-api-exception.php
[edit]
[-] class-create-archive.php
[edit]
[-] class-encryption-openssl.php
[edit]
[-] class-destination-onedrive-config-trait.php
[edit]
[-] class-destination-download-exception.php
[edit]
[-] class-download-file.php
[edit]
[-] class-page-settings.php
[edit]
[-] class-destination-msazure.php
[edit]
[-] class-page-onboarding.php
[edit]
[-] class-destination-folder.php
[edit]
[-] class-jobtypes.php
[edit]
[-] class-destination-connect-exception.php
[edit]
[-] class-destination-sugarsync.php
[edit]
[-] class-page-jobs.php
[edit]
[-] class-destination-sugarsync-api-exception.php
[edit]
[-] class-encryption-mcrypt.php
[edit]