Current File : /home/pacjaorg/public_html/copp/copp/wp-content/plugins/backwpup/inc/class-destination-msazure.php
<?php

use Inpsyde\BackWPup\MsAzureDestinationConfiguration;
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
use MicrosoftAzure\Storage\Blob\Models\Blob;
use MicrosoftAzure\Storage\Blob\Models\BlockList;
use MicrosoftAzure\Storage\Blob\Models\Container;
use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions;
use MicrosoftAzure\Storage\Blob\Models\ListBlobsOptions;
use MicrosoftAzure\Storage\Blob\Models\PublicAccessType;

/**
 * Documentation: http://www.windowsazure.com/en-us/develop/php/how-to-guides/blob-service/.
 */
class BackWPup_Destination_MSAzure extends BackWPup_Destinations
{
    public const MSAZUREDIR = 'msazuredir';
    public const MSAZUREMAXBACKUPS = 'msazuremaxbackups';
    public const MSAZURESYNCNODELETE = 'msazuresyncnodelete';
    public const NEWMSAZURECONTAINER = 'newmsazurecontainer';

    public function option_defaults(): array
    {
        return [MsAzureDestinationConfiguration::MSAZURE_ACCNAME => '', MsAzureDestinationConfiguration::MSAZURE_KEY => '', MsAzureDestinationConfiguration::MSAZURE_CONTAINER => '', self::MSAZUREDIR => trailingslashit(sanitize_file_name(get_bloginfo('name'))), self::MSAZUREMAXBACKUPS => 15, self::MSAZURESYNCNODELETE => true];
    }

    public function edit_tab(int $jobid): void
    {
        ?>
		<h3 class="title"><?php esc_html_e('MS Azure access keys', 'backwpup'); ?></h3>
		<p></p>
		<table class="form-table">
			<tr>
				<th scope="row"><label for="msazureaccname"><?php esc_html_e('Account name', 'backwpup'); ?></label></th>
				<td>
					<input id="msazureaccname" name="msazureaccname" type="text"
						   value="<?php echo esc_attr(BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_ACCNAME)); ?>" class="regular-text" autocomplete="off" />
				</td>
			</tr>
			<tr>
				<th scope="row"><label for="msazurekey"><?php esc_html_e('Access key', 'backwpup'); ?></label></th>
				<td>
					<input id="msazurekey" name="msazurekey" type="password"
						   value="<?php echo esc_attr(BackWPup_Encryption::decrypt(BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_KEY))); ?>" class="regular-text" autocomplete="off" />
				</td>
			</tr>
		</table>

		<h3 class="title"><?php esc_html_e('Blob container', 'backwpup'); ?></h3>
		<p></p>
		<table class="form-table">
			<tr>
				<th scope="row"><label for="msazurecontainerselected"><?php esc_html_e('Container selection', 'backwpup'); ?></label></th>
				<td>
					<input id="msazurecontainerselected" name="msazurecontainerselected" type="hidden" value="<?php echo esc_attr(BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_CONTAINER)); ?>" />
					<?php if (BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_ACCNAME) && BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_KEY)) {
            $this->edit_ajax([
                MsAzureDestinationConfiguration::MSAZURE_ACCNAME => BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_ACCNAME),
                MsAzureDestinationConfiguration::MSAZURE_KEY => BackWPup_Encryption::decrypt(BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_KEY)),
                'msazureselected' => BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_CONTAINER),
            ]);
        } ?>
				</td>
			</tr>
			<tr>
				<th scope="row"><label for="newmsazurecontainer"><?php esc_html_e('Create a new container', 'backwpup'); ?></label></th>
				<td>
					<input id="newmsazurecontainer" name="newmsazurecontainer" type="text" value="" class="regular-text" autocomplete="off" />
				</td>
			</tr>
		</table>

		<h3 class="title"><?php esc_html_e('Backup settings', 'backwpup'); ?></h3>
		<p></p>
		<table class="form-table">
			<tr>
				<th scope="row"><label for="idmsazuredir"><?php esc_html_e('Folder in container', 'backwpup'); ?></label></th>
				<td>
					<input id="idmsazuredir" name="msazuredir" type="text" value="<?php echo esc_attr(BackWPup_Option::get(
            $jobid,
            self::MSAZUREDIR
        )); ?>" class="regular-text" />
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e('File deletion', 'backwpup'); ?></th>
				<td>
					<?php
                    if (BackWPup_Option::get($jobid, 'backuptype') === 'archive') {
                        ?>
						<label for="idmsazuremaxbackups">
							<input id="idmsazuremaxbackups" name="msazuremaxbackups" type="number" min="0" step="1" value="<?php echo esc_attr(BackWPup_Option::get(
                            $jobid,
                            self::MSAZUREMAXBACKUPS
                        )); ?>" class="small-text" />
							&nbsp;<?php esc_html_e('Number of files to keep in folder.', 'backwpup'); ?>
						</label>
						<p><?php _e('<strong>Warning</strong>: Files belonging to this job are now tracked. Old backup archives which are untracked will not be automatically deleted.', 'backwpup'); ?></p>
					<?php
                    } else { ?>
						<label for="idmsazuresyncnodelete">
							<input class="checkbox" value="1" type="checkbox" <?php checked(BackWPup_Option::get(
                            $jobid,
                            self::MSAZURESYNCNODELETE
                        ), true); ?> name="msazuresyncnodelete" id="idmsazuresyncnodelete" />
							&nbsp;<?php esc_html_e('Do not delete files while syncing to destination!', 'backwpup'); ?>
						</label>
					<?php } ?>
				</td>
			</tr>
		</table>
		<?php
    }

    public function edit_form_post_save(int $jobid): void
    {
        try {
            $msazureConfiguration = $this->msazureConfiguration();
        } catch (\UnexpectedValueException $exception) {
            BackWPup_Admin::message(__('Microsoft Azure Configuration: ', 'backwpup') . $exception->getMessage(), true);

            return;
        }

        if ($msazureConfiguration->isNew()) {
            try {
                $this->createContainer($msazureConfiguration);

                BackWPup_Admin::message(
                    sprintf(
                        __('MS Azure container "%s" created.', 'backwpup'),
                        esc_html(sanitize_text_field($msazureConfiguration->msazurecontainer()))
                    )
                );
            } catch (Exception $e) {
                BackWPup_Admin::message(sprintf(__('MS Azure container create: %s', 'backwpup'), $e->getMessage()), true);

                return;
            }
        }

        BackWPup_Option::update(
            $jobid,
            MsAzureDestinationConfiguration::MSAZURE_ACCNAME,
            $msazureConfiguration->msazureaccname()
        );
        BackWPup_Option::update(
            $jobid,
            MsAzureDestinationConfiguration::MSAZURE_KEY,
            $msazureConfiguration->msazurekey()
        );
        BackWPup_Option::update(
            $jobid,
            MsAzureDestinationConfiguration::MSAZURE_CONTAINER,
            $msazureConfiguration->msazurecontainer()
        );

        $msazureDir = $this->msazureDir();

        BackWPup_Option::update($jobid, self::MSAZUREDIR, $msazureDir);

        BackWPup_Option::update(
            $jobid,
            self::MSAZUREMAXBACKUPS,
            filter_input(INPUT_POST, self::MSAZUREMAXBACKUPS, FILTER_SANITIZE_NUMBER_INT) ?: 0
        );

        BackWPup_Option::update(
            $jobid,
            self::MSAZURESYNCNODELETE,
            filter_input(INPUT_POST, self::MSAZURESYNCNODELETE) ?: ''
        );
    }

    public function file_delete(string $jobdest, string $backupfile): void
    {
        $files = get_site_transient('backwpup_' . strtolower($jobdest));
        [$jobid, $dest] = explode('_', $jobdest);

        if (BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_ACCNAME)
            && BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_KEY)
            && BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_CONTAINER)) {
            try {
                $blobClient = $this->createBlobClient(
                    BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_ACCNAME),
                    BackWPup_Encryption::decrypt(
                        BackWPup_Option::get($jobid, MsAzureDestinationConfiguration::MSAZURE_KEY)
                    )
                );

                $this->deleteBlob(
                    $blobClient,
                    BackWPup_Option::get(
                        $jobid,
                        MsAzureDestinationConfiguration::MSAZURE_CONTAINER
                    ),
                    $backupfile
                );

                //update file list
                foreach ($files as $key => $file) {
                    if (is_array($file) && $file['file'] == $backupfile) {
                        unset($files[$key]);
                    }
                }
            } catch (Exception $e) {
                BackWPup_Admin::message('MS AZURE: ' . $e->getMessage(), true);
            }
        }

        set_site_transient('backwpup_' . strtolower($jobdest), $files, YEAR_IN_SECONDS);
    }

    /**
     * {@inheritdoc}
     */
    public function file_get_list(string $jobdest): array
    {
        $list = (array) get_site_transient('backwpup_' . strtolower($jobdest));

        return array_filter($list);
    }

    public function job_run_archive(BackWPup_Job $job_object): bool
    {
        $job_object->substeps_todo = $job_object->backup_filesize + 2;

        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(__('%d. Try sending backup to a Microsoft Azure (Blob)&#160;&hellip;', 'backwpup'), $job_object->steps_data[$job_object->step_working]['STEP_TRY']), E_USER_NOTICE);
        }

        try {
            $blobRestProxy = $this->createBlobClient(
                $job_object->job[MsAzureDestinationConfiguration::MSAZURE_ACCNAME],
                BackWPup_Encryption::decrypt($job_object->job[MsAzureDestinationConfiguration::MSAZURE_KEY])
            );

            if ($job_object->steps_data[$job_object->step_working]['SAVE_STEP_TRY'] != $job_object->steps_data[$job_object->step_working]['STEP_TRY']) {
                //test vor existing container
                $containers = $this->getContainers($blobRestProxy);

                $job_object->steps_data[$job_object->step_working]['container_url'] = '';

                foreach ($containers as $container) {
                    if ($container->getName() == $job_object->job[MsAzureDestinationConfiguration::MSAZURE_CONTAINER]) {
                        $job_object->steps_data[$job_object->step_working]['container_url'] = $container->getUrl();
                        break;
                    }
                }

                if (!$job_object->steps_data[$job_object->step_working]['container_url']) {
                    $job_object->log(sprintf(__('MS Azure container "%s" does not exist!', 'backwpup'), $job_object->job[MsAzureDestinationConfiguration::MSAZURE_CONTAINER]), E_USER_ERROR);

                    return true;
                }
                $job_object->log(sprintf(__('Connected to MS Azure container "%s".', 'backwpup'), $job_object->job[MsAzureDestinationConfiguration::MSAZURE_CONTAINER]), E_USER_NOTICE);

                $job_object->log(__('Starting upload to MS Azure&#160;&hellip;', 'backwpup'), E_USER_NOTICE);
            }

            //Prepare Upload
            $file_handel = null;
            if ($file_handel = fopen($job_object->backup_folder . $job_object->backup_file, 'rb')) {
                fseek($file_handel, $job_object->substeps_done);

                if (empty($job_object->steps_data[$job_object->step_working]['BlockList'])) {
                    $job_object->steps_data[$job_object->step_working]['BlockList'] = [];
                }

                while (!feof($file_handel)) {
                    $data = fread($file_handel, 1048576 * 4); //4MB
                    if (strlen($data) == 0) {
                        continue;
                    }
                    $chunk_upload_start = microtime(true);
                    $block_count = count($job_object->steps_data[$job_object->step_working]['BlockList']) + 1;
                    $block_id = base64_encode(str_pad($block_count, 6, '0', STR_PAD_LEFT));

                    $blobRestProxy->createBlobBlock(
                        $job_object->job[MsAzureDestinationConfiguration::MSAZURE_CONTAINER],
                        $job_object->job[self::MSAZUREDIR] . $job_object->backup_file,
                        $block_id,
                        $data
                    );

                    $job_object->steps_data[$job_object->step_working]['BlockList'][] = $block_id;
                    $chunk_upload_time = microtime(true) - $chunk_upload_start;
                    $job_object->substeps_done = $job_object->substeps_done + strlen($data);
                    $time_remaining = $job_object->do_restart_time();
                    if ($time_remaining < $chunk_upload_time) {
                        $job_object->do_restart_time(true);
                    }
                    $job_object->update_working_data();
                }
                fclose($file_handel);
            } else {
                $job_object->log(__('Can not open source file for transfer.', 'backwpup'), E_USER_ERROR);

                return false;
            }

            $blocklist = $this->createBlockList();

            foreach ($job_object->steps_data[$job_object->step_working]['BlockList'] as $block_id) {
                $blocklist->addUncommittedEntry($block_id);
            }
            unset($job_object->steps_data[$job_object->step_working]['BlockList']);

            //Commit Blocks
            $blobRestProxy->commitBlobBlocks($job_object->job[MsAzureDestinationConfiguration::MSAZURE_CONTAINER], $job_object->job[self::MSAZUREDIR] . $job_object->backup_file, $blocklist->getEntries());

            ++$job_object->substeps_done;
            $job_object->log(sprintf(__('Backup transferred to %s', 'backwpup'), $job_object->steps_data[$job_object->step_working]['container_url'] . '/' . $job_object->job[self::MSAZUREDIR] . $job_object->backup_file), E_USER_NOTICE);
            if (!empty($job_object->job['jobid'])) {
                BackWPup_Option::update($job_object->job['jobid'], 'lastbackupdownloadurl', network_admin_url('admin.php') . '?page=backwpupbackups&action=downloadmsazure&file=' . $job_object->job[self::MSAZUREDIR] . $job_object->backup_file . '&jobid=' . $job_object->job['jobid']);
            }
        } catch (Exception $e) {
            $job_object->log(E_USER_ERROR, sprintf(__('Microsoft Azure API: %s', 'backwpup'), $e->getMessage()), $e->getFile(), $e->getLine());
            $job_object->substeps_done = 0;
            unset($job_object->steps_data[$job_object->step_working]['BlockList']);
            if (isset($file_handel) && is_resource($file_handel)) {
                fclose($file_handel);
            }

            return false;
        }

        try {
            $backupfilelist = [];
            $filecounter = 0;
            $files = [];

            $blob_options = $this->createListBlobsOptions();
            $blob_options->setPrefix($job_object->job[self::MSAZUREDIR]);

            $blobs = $this->getBlobs(
                $blobRestProxy,
                $job_object->job[MsAzureDestinationConfiguration::MSAZURE_CONTAINER],
                $blob_options
            );

            if (is_array($blobs)) {
                foreach ($blobs as $blob) {
                    $file = basename($blob->getName());
                    if ($this->is_backup_archive($file) && $this->is_backup_owned_by_job($file, $job_object->job['jobid']) == true) {
                        $backupfilelist[$blob->getProperties()->getLastModified()->getTimestamp()] = $file;
                    }
                    $files[$filecounter]['folder'] = $job_object->steps_data[$job_object->step_working]['container_url'] . '/' . dirname($blob->getName()) . '/';
                    $files[$filecounter]['file'] = $blob->getName();
                    $files[$filecounter]['filename'] = basename($blob->getName());
                    $files[$filecounter]['downloadurl'] = network_admin_url('admin.php') . '?page=backwpupbackups&action=downloadmsazure&file=' . $blob->getName() . '&jobid=' . $job_object->job['jobid'];
                    $files[$filecounter]['filesize'] = $blob->getProperties()->getContentLength();
                    $files[$filecounter]['time'] = $blob->getProperties()->getLastModified()->getTimestamp() + (get_option('gmt_offset') * 3600);
                    ++$filecounter;
                }
            }
            // Delete old backups
            if (!empty($job_object->job[self::MSAZUREMAXBACKUPS]) && $job_object->job[self::MSAZUREMAXBACKUPS] > 0) {
                if (count($backupfilelist) > $job_object->job[self::MSAZUREMAXBACKUPS]) {
                    ksort($backupfilelist);
                    $numdeltefiles = 0;

                    while ($file = array_shift($backupfilelist)) {
                        if (count($backupfilelist) < $job_object->job[self::MSAZUREMAXBACKUPS]) {
                            break;
                        }
                        $blobRestProxy->deleteBlob($job_object->job[MsAzureDestinationConfiguration::MSAZURE_CONTAINER], $job_object->job[self::MSAZUREDIR] . $file);

                        foreach ($files as $key => $filedata) {
                            if ($filedata['file'] == $job_object->job[self::MSAZUREDIR] . $file) {
                                unset($files[$key]);
                            }
                        }
                        ++$numdeltefiles;
                    }
                    if ($numdeltefiles > 0) {
                        $job_object->log(sprintf(_n('One file deleted on Microsoft Azure container.', '%d files deleted on Microsoft Azure container.', $numdeltefiles, 'backwpup'), $numdeltefiles), E_USER_NOTICE);
                    }
                }
            }
            set_site_transient('backwpup_' . $job_object->job['jobid'] . '_msazure', $files, YEAR_IN_SECONDS);
        } catch (Exception $e) {
            $job_object->log(E_USER_ERROR, sprintf(__('Microsoft Azure API: %s', 'backwpup'), $e->getMessage()), $e->getFile(), $e->getLine());

            return false;
        }

        $job_object->substeps_done = $job_object->backup_filesize + 2;

        return true;
    }

    public function can_run(array $job_settings): bool
    {
        if (empty($job_settings[MsAzureDestinationConfiguration::MSAZURE_ACCNAME])) {
            return false;
        }

        if (empty($job_settings[MsAzureDestinationConfiguration::MSAZURE_KEY])) {
            return false;
        }

        return !(empty($job_settings[MsAzureDestinationConfiguration::MSAZURE_CONTAINER]));
    }

    public function edit_inline_js(): void
    {
        ?>
		<script type="text/javascript">
			jQuery(document).ready(function ($) {
				function msazuregetcontainer() {
					var data = {
						action: 'backwpup_dest_msazure',
						msazureaccname: $('#msazureaccname').val(),
						msazurekey: $('#msazurekey').val(),
						msazureselected: $('#msazurecontainerselected').val(),
						_ajax_nonce: $('#backwpupajaxnonce').val()
					};
					$.post(ajaxurl, data, function (response) {
						$('#msazurecontainererror').remove();
						$('#msazurecontainer').remove();
						$('#msazurecontainerselected').after(response);
					});
				}

				$('#msazureaccname').backwpupDelayKeyup(function () {
					msazuregetcontainer();
				});
				$('#msazurekey').backwpupDelayKeyup(function () {
					msazuregetcontainer();
				});
			});
		</script>
	<?php
    }

    public function edit_ajax(array $args = []): void
    {
        $error = '';
        $ajax = false;

        $msazureName = filter_input(
            INPUT_POST,
            MsAzureDestinationConfiguration::MSAZURE_ACCNAME
        ) ?: '';
        $msazureKey = filter_input(
            INPUT_POST,
            MsAzureDestinationConfiguration::MSAZURE_KEY
        ) ?: '';
        $msazureSelected = filter_input(
            INPUT_POST,
            'msazureselected'
        ) ?: '';

        if ($msazureName || $msazureKey) {
            if (!current_user_can('backwpup_jobs_edit')) {
                wp_die(-1);
            }
            check_ajax_referer('backwpup_ajax_nonce');
            $args[MsAzureDestinationConfiguration::MSAZURE_ACCNAME] = $msazureName;
            $args[MsAzureDestinationConfiguration::MSAZURE_KEY] = $msazureKey;
            $args['msazureselected'] = $msazureSelected;
            $ajax = true;
        }
        echo '<span id="msazurecontainererror" class="bwu-message-error">';

        $containers = null;

        if (!empty($args[MsAzureDestinationConfiguration::MSAZURE_ACCNAME]) && !empty($args[MsAzureDestinationConfiguration::MSAZURE_KEY])) {
            try {
                $blobClient = $this->createBlobClient(
                    $args[MsAzureDestinationConfiguration::MSAZURE_ACCNAME],
                    BackWPup_Encryption::decrypt($args[MsAzureDestinationConfiguration::MSAZURE_KEY])
                );

                $containers = $blobClient->listContainers()->getContainers();
            } catch (Exception $e) {
                $error = $e->getMessage();
            }
        }

        if (empty($args[MsAzureDestinationConfiguration::MSAZURE_ACCNAME])) {
            _e('Missing account name!', 'backwpup');
        } elseif (empty($args[MsAzureDestinationConfiguration::MSAZURE_KEY])) {
            _e('Missing access key!', 'backwpup');
        } elseif (!empty($error)) {
            echo esc_html($error);
        } elseif (empty($containers)) {
            _e('No container found!', 'backwpup');
        }
        echo '</span>';

        if (!empty($containers)) {
            echo '<select name="msazurecontainer" id="msazurecontainer">';

            foreach ($containers as $container) {
                echo '<option ' . selected(strtolower((string) $args['msazureselected']), strtolower($container->getName()), false) . '>' . esc_html($container->getName()) . '</option>';
            }
            echo '</select>';
        }
        if ($ajax) {
            exit();
        }
    }

    /**
     * Creates the service used to access the blob.
     */
    public function createBlobClient(string $accountName, string $accountKey): BlobRestProxy
    {
        $connectionString = 'DefaultEndpointsProtocol=https;AccountName='
            . $accountName . ';AccountKey=' . $accountKey;

        return BlobRestProxy::createBlobService($connectionString);
    }

    protected function msazureConfiguration(): MsAzureDestinationConfiguration
    {
        $msazureaccname = filter_input(INPUT_POST, MsAzureDestinationConfiguration::MSAZURE_ACCNAME);
        $msazurekey = filter_input(INPUT_POST, MsAzureDestinationConfiguration::MSAZURE_KEY);
        $msazurecontainer = filter_input(
            INPUT_POST,
            MsAzureDestinationConfiguration::MSAZURE_CONTAINER
        );

        if (!$msazurecontainer) {
            $newmsazurecontainer = filter_input(
                INPUT_POST,
                self::NEWMSAZURECONTAINER
            );

            return MsAzureDestinationConfiguration::withNewContainer(
                $msazureaccname,
                $msazurekey,
                $newmsazurecontainer
            );
        }

        return new MsAzureDestinationConfiguration(
            $msazureaccname,
            $msazurekey,
            $msazurecontainer
        );
    }

    protected function createContainer(MsAzureDestinationConfiguration $configuration): void
    {
        $blobClient = $this->createBlobClient(
            $configuration->msazureaccname(),
            $configuration->msazurekey()
        );

        $createContainerOptions = $this->createContainerOptionsFactory();
        $createContainerOptions->setPublicAccess(PublicAccessType::NONE);

        $blobClient->createContainer(
            $configuration->msazurecontainer(),
            $createContainerOptions
        );
    }

    protected function createContainerOptionsFactory(): CreateContainerOptions
    {
        return new CreateContainerOptions();
    }

    protected function deleteBlob(BlobRestProxy $blobClient, string $container, string $backupfile): void
    {
        $blobClient->deleteBlob(
            $container,
            $backupfile
        );
    }

    /**
     * @return Blob[]
     */
    protected function getBlobs(BlobRestProxy $blobClient, string $container, ListBlobsOptions $options): array
    {
        return $blobClient->listBlobs(
            $container,
            $options
        )->getBlobs();
    }

    /**
     * @return Container[]
     */
    protected function getContainers(BlobRestProxy $blobClient): array
    {
        return $blobClient->listContainers()->getContainers();
    }

    protected function createBlockList(): BlockList
    {
        return new BlockList();
    }

    protected function createListBlobsOptions(): ListBlobsOptions
    {
        return new ListBlobsOptions();
    }

    protected function msazureDir(): string
    {
        $msazureDir = trailingslashit(
            str_replace(
                '//',
                '/',
                str_replace(
                    '\\',
                    '/',
                    trim(
                        filter_input(INPUT_POST, self::MSAZUREDIR) ?: ''
                    )
                )
            )
        );

        if (substr($msazureDir, 0, 1) == '/') {
            $msazureDir = substr($msazureDir, 1);
        }

        if ($msazureDir == '/') {
            $msazureDir = '';
        }

        return $msazureDir;
    }

    /**
     * It extracts the job id from a job destination string.
     *
     * @param string $jobDestination String containing a job destination, ex. 1_SOME_DESTINATION.
     *
     * @throws RuntimeException
     *
     * @return int
     */
    protected function extractJobIdFromDestination(string $jobDestination)
    {
        $jobId = intval(substr($jobDestination, 0, strpos($jobDestination, '_', 1)));

        if (!$jobId) {
            throw new RuntimeException(
                sprintf(__('Could not extract job id from destination %s.', 'backwpup'), $jobDestination)
            );
        }

        return $jobId;
    }
}
Site is undergoing maintenance

PACJA Events

Maintenance mode is on

Site will be available soon. Thank you for your patience!