PATH:
home
/
thebhoeo
/
.trash
/
backwpup
/
inc
<?php declare(strict_types=1); use BackWPup\Utils\BackWPupHelpers; use WPMedia\BackWPup\StorageProviders\Rackspace\RackspaceProvider as Rackspace; if ( ! defined( 'ABSPATH' ) ) { exit; } class BackWPup_Destination_RSC extends BackWPup_Destinations { /** * Service name * * @var string */ private const SERVICE_NAME = 'RSC'; /** * Rackspace US * * @var string */ private string $rackspace_us = 'https://identity.api.rackspacecloud.com/v2.0/'; /** * Rackspace UK * * @var string */ private string $rackspace_uk = 'https://lon.identity.api.rackspacecloud.com/v2.0/'; /** * Default options * * @return array */ public function option_defaults(): array { return [ 'rscusername' => '', 'rscapikey' => '', 'rsccontainer' => '', 'rscregion' => 'DFW', 'rscdir' => trailingslashit( sanitize_file_name( get_bloginfo( 'name' ) ) ), 'rscmaxbackups' => 15, 'rscsyncnodelete' => true, ]; } /** * Get Auth url by region code. * * @param string $region Region code. */ public function get_auth_url_by_region( string $region ): string { $region = strtoupper( $region ); if ( 'LON' === $region ) { return $this->rackspace_uk; } return $this->rackspace_us; } /** * {@inheritdoc} * * @param int|array $id Job ID. * @return void * @throws Exception When the Rackspace Cloud API throws an exception. * * @phpcs:disable WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */ public function edit_form_post_save( $id ): void { $_POST['rscdir'] = trailingslashit( str_replace( '//', '/', str_replace( '\\', '/', trim( sanitize_text_field( $_POST['rscdir'] ) ) ) ) ); if ( substr( $_POST['rscdir'], 0, 1 ) === '/' ) { $_POST['rscdir'] = substr( $_POST['rscdir'], 1 ); } if ( '/' === $_POST['rscdir'] ) { $_POST['rscdir'] = ''; } $newrsccontainer = ''; if ( ! empty( $_POST['rscusername'] ) && ! empty( $_POST['rscapikey'] ) && ! empty( $_POST['newrsccontainer'] ) ) { try { $storage_provider = $this->get_rackspace_client( [ 'region' => $_POST['rscregion'], 'username' => $_POST['rscusername'], 'api_key' => $_POST['rscapikey'], 'container_name' => $_POST['rsccontainer'], ] ); $storage_provider->create_container( $_POST['newrsccontainer'] ); $newrsccontainer = sanitize_text_field( $_POST['newrsccontainer'] ); // translators: %s: container name. BackWPup_Admin::message( sprintf( __( 'Rackspace Cloud container "%s" created.', 'backwpup' ), esc_html( sanitize_text_field( $_POST['newrsccontainer'] ) ) ) ); } catch ( Exception $e ) { // translators: %s: error message. BackWPup_Admin::message( sprintf( __( 'Rackspace Cloud API: %s', 'backwpup' ), $e->getMessage() ), true ); } } $jobids = (array) $id; foreach ( $jobids as $id ) { BackWPup_Option::update( $id, 'rscusername', sanitize_text_field( $_POST['rscusername'] ) ); BackWPup_Option::update( $id, 'rscapikey', sanitize_text_field( $_POST['rscapikey'] ) ); BackWPup_Option::update( $id, 'rsccontainer', isset( $_POST['rsccontainer'] ) ? sanitize_text_field( $_POST['rsccontainer'] ) : '' ); BackWPup_Option::update( $id, 'rscregion', ! empty( $_POST['rscregion'] ) ? sanitize_text_field( $_POST['rscregion'] ) : 'DFW' ); BackWPup_Option::update( $id, 'rscdir', $_POST['rscdir'] ); BackWPup_Option::update( $id, 'rscmaxbackups', isset( $_POST['rscmaxbackups'] ) && is_numeric( $_POST['rscmaxbackups'] ) ? absint( $_POST['rscmaxbackups'] ) : $this->option_defaults()['rscmaxbackups'] ); BackWPup_Option::update( $id, 'rscsyncnodelete', ! empty( $_POST['rscsyncnodelete'] ) ); if ( ! empty( $newrsccontainer ) ) { BackWPup_Option::update( $id, 'rsccontainer', $newrsccontainer ); } } } // phpcs:enable /** * Delete file * * @param string $jobdest Job destination. * @param string $backupfile File to be deleted. * * @return void */ public function file_delete( string $jobdest, string $backupfile ): void { $files = get_site_transient( 'backwpup_' . strtolower( $jobdest ) ); [$jobid, $dest] = explode( '_', $jobdest ); $storage_provider = $this->get_rackspace_client( [ 'region' => BackWPup_Option::get( $jobid, 'rscregion' ), 'username' => BackWPup_Option::get( $jobid, 'rscusername' ), 'api_key' => BackWPup_Option::get( $jobid, 'rscapikey' ) , 'container_name' => BackWPup_Option::get( $jobid, 'rsccontainer' ), ] ); $delete = $storage_provider->delete_object( $backupfile, $jobid ); if ( $delete ) { foreach ( $files as $key => $file ) { if ( is_array( $file ) && $file['file'] === $backupfile ) { unset( $files[ $key ] ); } } } $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 ); } /** * Get Rackspace client. * * @param array $data Rackspace data. * * @return Rackspace */ private function get_rackspace_client( array $data ) { $rackspace_client = new Rackspace( [ 'username' => $data['username'], 'api_key' => BackWPup_Encryption::decrypt( $data['api_key'] ), 'container_name' => $data['container_name'], 'region' => $data['region'], ], ); $rackspace_client->initialise(); return $rackspace_client; } /** * Upload backup to cloud storage. * * @param BackWPup_Job $job_object Job Object. * @param Rackspace $storage_provider Storage provider. * * @return bool */ public function upload_backup( BackWPup_Job $job_object, Rackspace $storage_provider ): bool { try { // translators: %s: container name. $job_object->log( sprintf( __( 'Connected to Rackspace cloud files container %s', 'backwpup' ), $job_object->job['rsccontainer'] ) ); $job_object->log( __( 'Upload to Rackspace cloud started …', 'backwpup' ), E_USER_NOTICE ); $upload = $storage_provider->upload_object( $job_object->job['rscdir'] . $job_object->backup_file, $job_object->backup_folder . $job_object->backup_file ); if ( ! $upload ) { $job_object->log( __( 'Cannot transfer backup to Rackspace cloud.', 'backwpup' ), E_USER_ERROR ); return false; } $modified_backup_name = $job_object->job['rscdir'] . $job_object->backup_file; $job_object->log( __( 'Backup File transferred to RSC://', 'backwpup' ) . $job_object->job['rsccontainer'] . '/' . $modified_backup_name, E_USER_NOTICE ); $job_object->substeps_done = 1 + $job_object->backup_filesize; if ( ! empty( $job_object->job['jobid'] ) ) { BackWPup_Option::update( $job_object->job['jobid'], 'lastbackupdownloadurl', network_admin_url( 'admin.php' ) . '?page=backwpupbackups&action=downloadrsc&file=' . $modified_backup_name . '&jobid=' . $job_object->job['jobid'] ); } } catch ( Exception $e ) { $context = $this->error_context( $e->getMessage() ); $job_object->log( /* translators: %s: Error message. */ sprintf( __( 'Rackspace Cloud API: %s', 'backwpup' ), $e->getMessage() ), E_USER_ERROR, $e->getFile(), $e->getLine(), $context ); return false; } return true; } /** * Handle cleanup, deletion after backup is uploaded to cloud storage. * * @param BackWPup_Job $job_object Job Object. * @param Rackspace $storage_provider Storage provider. * * @return bool */ public function cleanup_after_backup_upload( BackWPup_Job $job_object, Rackspace $storage_provider ): bool { try { $backupfilelist = []; $filecounter = 0; $files = []; $object_list = $storage_provider->object_list( [ 'prefix' => $job_object->job['rscdir'], 'delimiter' => '/', ] ); foreach ( $object_list as $object ) { if ( isset( $object['subdir'] ) ) { continue; } $file = basename( (string) $object['name'] ); if ( $job_object->job['rscdir'] . $file === $object['name'] ) { // only in the folder and not in complete bucket. if ( $this->is_backup_archive( $file ) && $this->is_backup_owned_by_job( $file, $job_object->job['jobid'] ) === true ) { $backupfilelist[ strtotime( (string) $object['last_modified'] ) ] = $object; } } $files[ $filecounter ]['folder'] = 'RSC://' . $job_object->job['rsccontainer'] . '/' . dirname( (string) $object['name'] ) . '/'; $files[ $filecounter ]['file'] = $object['name']; $files[ $filecounter ]['filename'] = basename( (string) $object['name'] ); $files[ $filecounter ]['downloadurl'] = network_admin_url( 'admin.php' ) . '?page=backwpupbackups&action=downloadrsc&file=' . $object['name'] . '&jobid=' . $job_object->job['jobid']; $files[ $filecounter ]['filesize'] = $object['bytes']; $files[ $filecounter ]['time'] = strtotime( (string) $object['last_modified'] ); ++$filecounter; } if ( ! empty( $job_object->job['rscmaxbackups'] ) && $job_object->job['rscmaxbackups'] > 0 ) { // Delete old backups. if ( count( $backupfilelist ) > $job_object->job['rscmaxbackups'] ) { ksort( $backupfilelist ); $numdeltefiles = 0; $deleted_files = []; while ( ! empty( $backupfilelist ) ) { $file = array_shift( $backupfilelist ); if ( count( $backupfilelist ) < $job_object->job['rscmaxbackups'] ) { break; } foreach ( $files as $key => $filedata ) { if ( $filedata['file'] === $file['name'] ) { $deleted_files[] = $filedata['filename']; unset( $files[ $key ] ); } } $storage_provider->delete_object( $file['name'], (string) $job_object->job['jobid'] ); ++$numdeltefiles; } if ( $numdeltefiles > 0 ) { $job_object->log( sprintf( // Translators: %d is the number of files deleted from the Rackspace cloud container. _n( '%d file deleted on Rackspace cloud container.', '%d files deleted on Rackspace cloud container.', $numdeltefiles, 'backwpup' ), $numdeltefiles ), E_USER_NOTICE ); } parent::remove_file_history_from_database( $deleted_files, 'RSC' ); } } set_site_transient( 'backwpup_' . $job_object->job['jobid'] . '_rsc', $files, YEAR_IN_SECONDS ); } catch ( Exception $e ) { $context = $this->error_context( $e->getMessage() ); $job_object->log( /* translators: %s: Error message. */ sprintf( __( 'Rackspace Cloud API: %s', 'backwpup' ), $e->getMessage() ), E_USER_ERROR, $e->getFile(), $e->getLine(), $context ); return false; } return true; } /** * Upload the backup archive to Rackspace. * * @param BackWPup_Job $job_object Job object. * * @return bool True on success, false on failure. */ public function job_run_archive( BackWPup_Job $job_object ): bool { $job_object->substeps_todo = 2 + $job_object->backup_filesize; $job_object->substeps_done = 0; $job_object->log( sprintf( /* translators: %d: attempt number. */ __( '%d. Trying to send backup file to Rackspace cloud …', 'backwpup' ), $job_object->steps_data[ $job_object->step_working ]['STEP_TRY'] ), E_USER_NOTICE ); $storage_provider = $this->get_rackspace_client( [ 'region' => $job_object->job['rscregion'], 'username' => $job_object->job['rscusername'], 'api_key' => $job_object->job['rscapikey'], 'container_name' => $job_object->job['rsccontainer'], ] ); if ( ! $this->upload_backup( $job_object, $storage_provider ) ) { return false; } if ( ! $this->cleanup_after_backup_upload( $job_object, $storage_provider ) ) { return false; } ++$job_object->substeps_done; return true; } /** * Determines whether the destination can run with the provided settings. * * @param array $job_settings * @param bool $test_connection Job settings. */ public function can_run( array $job_settings, bool $test_connection = true ): bool { if ( empty( $job_settings['rscusername'] ) ) { return false; } if ( empty( $job_settings['rscapikey'] ) ) { return false; } return ! ( empty( $job_settings['rsccontainer'] ) ); } /** * Outputs inline JS for the Rackspace container selector. * * @return void */ public function edit_inline_js(): void { ?> <script type="text/javascript"> jQuery(document).ready(function ($) { function rscgetcontainer() { var data = { action: 'backwpup_dest_rsc', rscusername: $('#rscusername').val(), rscapikey: $('#rscapikey').val(), rscregion: $('#rscregion').val(), rscselected: $('#rsccontainer').val(), _ajax_nonce: $('input[name="backwpupajaxnonce"]').val() }; $.post(ajaxurl, data, function (response) { $('#rscbucketContainer').html(response); }); } $('#rscregion').on('change', function () { rscgetcontainer(); }); $('#rscusername').backwpupDelayKeyup(function () { rscgetcontainer(); }); $('#rscapikey').backwpupDelayKeyup(function () { rscgetcontainer(); }); }); </script> <?php } /** * Edit ajax * * @param array $args Storage data like username, containers, region etc. * * @return void */ public function edit_ajax( array $args = [] ): void { $error = ''; $ajax = false; if ( isset( $_POST['rscusername'] ) || isset( $_POST['rscapikey'] ) ) { if ( ! current_user_can( 'backwpup_jobs_edit' ) ) { wp_die( -1 ); } check_ajax_referer( 'backwpup_ajax_nonce' ); $post = wp_unslash( $_POST ); $args['rscusername'] = isset( $post['rscusername'] ) ? sanitize_text_field( $post['rscusername'] ) : ''; $args['rscapikey'] = isset( $post['rscapikey'] ) ? sanitize_text_field( $post['rscapikey'] ) : ''; $args['rscselected'] = isset( $post['rscselected'] ) ? sanitize_text_field( $post['rscselected'] ) : ''; $args['rscregion'] = isset( $post['rscregion'] ) ? sanitize_text_field( $post['rscregion'] ) : ''; $ajax = true; } echo '<span id="rsccontainererror" class="bwu-message-error">'; $container_list = []; if ( ! empty( $args['rscusername'] ) && ! empty( $args['rscapikey'] ) && ! empty( $args['rscregion'] ) ) { try { $storage_provider = $this->get_rackspace_client( [ 'region' => $args['rscregion'], 'username' => $args['rscusername'], 'api_key' => $args['rscapikey'], 'container_name' => '', // No container yet, so this will be blank. ] ); $containers = $storage_provider->get_containers(); if ( ! empty( $containers ) ) { foreach ( $containers as $container ) { $container_list[] = $container['name']; } } } catch ( Exception $e ) { $error = $e->getMessage(); } } if ( empty( $args['rscusername'] ) ) { esc_html_e( 'Missing username!', 'backwpup' ); } elseif ( empty( $args['rscapikey'] ) ) { esc_html_e( 'Missing API Key!', 'backwpup' ); } elseif ( ! empty( $error ) ) { echo esc_html( $error ); } elseif ( empty( $container_list ) ) { esc_html_e( 'A container could not be found!', 'backwpup' ); } echo '</span>'; if ( ! empty( $container_list ) ) { $mapped_containers = array_combine( $container_list, $container_list ); echo BackWPupHelpers::component( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 'form/select', [ 'name' => 'rsccontainer', 'identifier' => 'rsccontainer', 'label' => esc_html__( 'Container selection', 'backwpup' ), 'withEmpty' => false, 'value' => $args['rscselected'], // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 'options' => $mapped_containers, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ] ); } if ( $ajax ) { wp_die(); } } /** * Get service name */ public function get_service_name(): string { return self::SERVICE_NAME; } /** * Build error context for Rackspace errors. * * @param string $message Error message. * @return array */ private function error_context( string $message ): array { $normalized = strtolower( $message ); if ( false !== strpos( $normalized, 'authentication' ) || false !== strpos( $normalized, 'unauthorized' ) || false !== strpos( $normalized, 'forbidden' ) ) { return [ 'reason_code' => \WPMedia\BackWPup\Backup\ReasonCode::REASON_INCORRECT_LOGIN, 'destination' => 'RSC', 'provider_code' => 'auth_failed', ]; } if ( false !== strpos( $normalized, 'quota' ) || false !== strpos( $normalized, 'insufficient' ) || false !== strpos( $normalized, 'not enough' ) ) { return [ 'reason_code' => \WPMedia\BackWPup\Backup\ReasonCode::REASON_NOT_ENOUGH_STORAGE, 'destination' => 'RSC', 'provider_code' => 'quota_exceeded', ]; } return []; } }
[-] 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]