From: Marcin Haba Date: Wed, 10 Jun 2020 23:23:38 +0000 (+0200) Subject: baculum: Improve restore wizard X-Git-Tag: Release-9.6.5~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f56dd9555a74e60974270f88a63a7a7b22ede6d;p=thirdparty%2Fbacula.git baculum: Improve restore wizard - make it working faster with thousands of files - the wizard should start working with PHP 7.4 - improve preserving information in fields during moving back and forward by wizard steps - add clientid property to BVFS versions API endpoint - fix javascript error in the wizard --- diff --git a/gui/baculum/protected/API/Pages/API/BVFSVersions.php b/gui/baculum/protected/API/Pages/API/BVFSVersions.php index c513fe54d..9131ce461 100644 --- a/gui/baculum/protected/API/Pages/API/BVFSVersions.php +++ b/gui/baculum/protected/API/Pages/API/BVFSVersions.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2019 Kern Sibbald + * Copyright (C) 2013-2020 Kern Sibbald * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -40,6 +40,12 @@ class BVFSVersions extends ConsoleOutputPage { $client = null; if ($this->Request->contains('client') && $this->getModule('misc')->isValidName($this->Request['client'])) { $client = $this->Request['client']; + } elseif ($this->Request->contains('clientid')) { + $clientid = intval($this->Request['clientid']); + $client_row = $this->getModule('client')->getClientById($clientid); + if (is_object($client_row)) { + $client = $client_row->name; + } } if (is_null($client)) { diff --git a/gui/baculum/protected/API/openapi_baculum.json b/gui/baculum/protected/API/openapi_baculum.json index b24102901..c9b8f88a3 100644 --- a/gui/baculum/protected/API/openapi_baculum.json +++ b/gui/baculum/protected/API/openapi_baculum.json @@ -3639,10 +3639,19 @@ } }, "parameters": [ + { + "name": "clientid", + "in": "query", + "description": "Client identifier (can be used instead of client value)", + "required": true, + "schema": { + "type": "integer" + } + }, { "name": "client", "in": "query", - "description": "Client name", + "description": "Client name (can be used instead clientid)", "required": true, "schema": { "type": "string" diff --git a/gui/baculum/protected/Common/Class/BClientScript.php b/gui/baculum/protected/Common/Class/BClientScript.php index 8d916f4df..a0adc7c28 100644 --- a/gui/baculum/protected/Common/Class/BClientScript.php +++ b/gui/baculum/protected/Common/Class/BClientScript.php @@ -31,7 +31,7 @@ Prado::using('System.Web.UI.WebControls.TClientScript'); */ class BClientScript extends TClientScript { - const SCRIPTS_VERSION = 7; + const SCRIPTS_VERSION = 8; public function getScriptUrl() { diff --git a/gui/baculum/protected/Web/JavaScript/misc.js b/gui/baculum/protected/Web/JavaScript/misc.js index b89b018fa..6fb192435 100644 --- a/gui/baculum/protected/Web/JavaScript/misc.js +++ b/gui/baculum/protected/Web/JavaScript/misc.js @@ -643,6 +643,10 @@ var W3SideBar = { }, init: function() { this.sidebar = document.getElementById(this.ids.sidebar); + if (!this.sidebar) { + // don't initialize for pages without sidebar + return; + } this.overlay_bg = document.getElementById(this.ids.overlay_bg); this.page_main = $(this.css.page_main); var hide = Cookies.get_cookie(this.cookies.side_bar_hide); diff --git a/gui/baculum/protected/Web/Pages/RestoreWizard.page b/gui/baculum/protected/Web/Pages/RestoreWizard.page index d8361eb3c..f3c9d518e 100644 --- a/gui/baculum/protected/Web/Pages/RestoreWizard.page +++ b/gui/baculum/protected/Web/Pages/RestoreWizard.page @@ -125,9 +125,9 @@ <%[ To start, please select backup Client which data you want to restore. ]%>

-
+
- +
@@ -207,6 +207,7 @@ var oJobsToRestoreList = { var table = $('#' + this.ids.job_list).DataTable({ data: <%=json_encode(array_values($this->getPage()->jobs_to_restore))%>, deferRender: true, + stateSave: true, columns: [ { className: 'details-control', @@ -304,6 +305,9 @@ var oJobsToRestoreList = { radio.name = 'backup_to_restore'; radio.value = data; radio.className = 'w3-radio'; + if ('<%=$this->Session->contains('restore_jobid') ? $this->Session['restore_jobid'] : ''%>' == data) { + radio.setAttribute('checked', 'checked'); + } ret = radio.outerHTML; } else { ret = data; @@ -407,7 +411,7 @@ oJobsToRestoreList.init(); document.getElementById('restore-browser-files-loading').style.display = 'none'; - make_draggable('<%=$this->getPage()->DataGridFiles->ClientID%>'); + make_draggable('restore-browser-files-content');  <%[ OK ]%> @@ -418,66 +422,155 @@ oJobsToRestoreList.init();
- - -
- <%[ It seems that there is no files for choosing or file records in database for this job has been purged (file retention period expired) ]%> -
-
- - - - <%=($this->getParent()->Data['name'] != '/') ? preg_replace('/\/$/', '', $this->getParent()->Data['name']) : '/'%> -
- - <%=isset($this->getParent()->Data['lstat']['size']) ? $this->getParent()->Data['lstat']['size'] : '0'%> -
-
- -
-
-
- +
+
+ + + + + Formatters.set_formatters(); + + + document.getElementById('restore-browser-files-loading').style.display = 'block'; @@ -485,63 +578,155 @@ oJobsToRestoreList.init(); document.getElementById('restore-browser-files-loading').style.display = 'none'; -
- - -
- <%[ To see file versions please click a file on the left files browser. ]%> -
-
- - - - - - <%=$this->getParent()->Data['name']%> - - - MTIME:<%=date("Y-m-d H:i:s", $this->getParent()->Data['lstat']['mtime'])%> - - - <%[ Size: ]%> - <%=$this->getParent()->Data['lstat']['size']%> - - - - - - -
-
+
+ + + @@ -552,51 +737,163 @@ oJobsToRestoreList.init(); OnCallback="removeSelectedFile" ClientSide.OnComplete="set_formatters();" /> - - - - -
- <%[ To add a file to restore please click 'Add' link or please drag here the file from the top frame or from the frame on the left. ]%> -
-
- - - - - - <%=$this->getParent()->Data['name']%> - - - MTIME:<%=is_array($this->getParent()->Data['lstat']) ? date("Y-m-d H:i:s", $this->getParent()->Data['lstat']['mtime']) : '-'%> - - - <%[ Size: ]%><%=is_array($this->getParent()->Data['lstat']) ? $this->getParent()->Data['lstat']['size'] : '0'%> - - - - - -
-
+
+ + @@ -633,7 +930,7 @@ oJobsToRestoreList.init(); set_browser_sizes(); }); set_browser_sizes(); - make_draggable('<%=$this->getPage()->DataGridFiles->ClientID%>'); + make_draggable('restore-browser-files-content'); Formatters.set_formatters(); @@ -757,7 +1054,7 @@ oJobsToRestoreList.init(); <%[ Source parameters ]%>
<%[ Backup data from client: ]%>
-
<%=$this->BackupClientName->SelectedValue%>
+
<%=$this->BackupClient->SelectedItem->Text%>
<%[ Backup selection method: ]%>
@@ -792,7 +1089,7 @@ oJobsToRestoreList.init(); <%[ Destination parameters ]%>
<%[ Restore to client: ]%>
-
<%=$this->RestoreClient->SelectedValue%>
+
<%=$this->RestoreClient->SelectedItem->Text%>
<%[ Restore to path: ]%>
diff --git a/gui/baculum/protected/Web/Pages/RestoreWizard.php b/gui/baculum/protected/Web/Pages/RestoreWizard.php index 602d2188c..67f20faf5 100644 --- a/gui/baculum/protected/Web/Pages/RestoreWizard.php +++ b/gui/baculum/protected/Web/Pages/RestoreWizard.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2019 Kern Sibbald + * Copyright (C) 2013-2020 Kern Sibbald * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -44,34 +44,36 @@ class RestoreWizard extends BaculumWebPage * Job levels allowed to restore. */ - private $joblevel = array('F', 'I', 'D'); + private $joblevel = ['F', 'I', 'D']; + /** * Job statuses allowed to restore. */ - private $jobstatus = array('T', 'W', 'A', 'E', 'e', 'f'); + private $jobstatus = ['T', 'W', 'A', 'E', 'e', 'f']; /** * File browser special directories. */ - private $browser_root_dir = array( + private $browser_root_dir = [ 'name' => '.', 'type' => 'dir', 'fileid' => null, + 'pathid' => null, + 'filenameid' => null, + 'jobid' => null, 'lstat' => '', 'uniqid' => null - ); - private $browser_up_dir = array( + ]; + private $browser_up_dir = [ 'name' => '..', 'type' => 'dir', 'fileid' => null, + 'pathid' => null, + 'filenameid' => null, + 'jobid' => null, 'lstat' => '', 'uniqid' => null - ); - - /** - * Used to provide in template selected by user single jobid to restore. - */ - public $restore_single_jobid; + ]; /** * Stores file relocation option. Used in template. @@ -79,12 +81,13 @@ class RestoreWizard extends BaculumWebPage public $file_relocation_opt; /** - * FIle browser elements for which 'Add' button is unavailable. + * Stores list of jobs possible to select to restore. */ - public $excluded_elements_from_add = array('.', '..'); - public $jobs_to_restore; + /** + * If set to true, show modal with error message about problem during restore start. + */ public $show_error = false; /** @@ -92,35 +95,48 @@ class RestoreWizard extends BaculumWebPage */ const BVFS_PATH_PREFIX = 'b2'; + /** + * Initialize restore page. + * + * @param TXmlElement $param page config + * @return none + */ public function onInit($param) { parent::onInit($param); - if (!$this->IsPostBack && !$this->IsCallBack) { - $this->resetWizard(); - $this->loadBackupClients(); - $this->setPreDefinedJobIdToRestore(); + if ($this->IsPostBack || $this->IsCallBack) { + return; + } + $this->resetWizard(); + $this->loadBackupClients(); + if ($this->Request->contains('jobid')) { + $this->setJobIdToRestore($this->Request['jobid']); } } + /** + * On pre-render action. + * + * @param TXmlElement $param page config + * @return none + */ public function onPreRender($param) { parent::onPreRender($param); $this->setNavigationButtons(); } /** - * Set pre-defined jobid to restore. + * Set jobid to restore. * Used to restore specific job by jobid. * * @return none */ - public function setPreDefinedJobIdToRestore() { - if ($this->Request->contains('jobid')) { - $jobid = intval($this->Request['jobid']); - $this->setRestoreByJobId($jobid); - $this->RestoreWizard->setActiveStep($this->Step3); - $param = new stdClass; - $param->CurrentStepIndex = 1; - $this->RestoreWizard->raiseEvent('OnNextButtonClick', null, $param); - } + public function setJobIdToRestore($jobid) { + $jobid = intval($jobid); + $this->setRestoreByJobId($jobid); + $this->RestoreWizard->setActiveStep($this->Step3); + $param = new stdClass; + $param->CurrentStepIndex = 1; + $this->RestoreWizard->raiseEvent('OnNextButtonClick', null, $param); } /** @@ -129,20 +145,18 @@ class RestoreWizard extends BaculumWebPage * @return none */ public function setRestoreByJobId($jobid) { - $_SESSION['restore_single_jobid'] = $jobid; - $job = $this->getModule('api')->get(array('jobs', $_SESSION['restore_single_jobid']))->output; + $this->Session->add('restore_jobid', $jobid); + $job = $this->getModule('api')->get( + ['jobs', $jobid] + )->output; if (is_object($job)) { $this->loadRestoreClients(); - $client = $this->getBackupClient($job->clientid); - // client is null for restore backup from deleted clients in catalog - if (!is_null($client)) { - $this->BackupClientName->SelectedValue = $client; - $this->RestoreClient->SelectedValue = $client; - $this->loadBackupsForClient(); - $step_index = new stdClass; - $step_index->CurrentStepIndex = 3; - $this->wizardNext(null, $step_index); - } + $this->BackupClient->SelectedValue = $job->clientid; + $this->RestoreClient->SelectedValue = $job->clientid; + $this->loadBackupsForClient(); + $step_index = new stdClass; + $step_index->CurrentStepIndex = 3; + $this->wizardNext(null, $step_index); } } @@ -174,31 +188,36 @@ class RestoreWizard extends BaculumWebPage $this->loadGroupBackupToRestore(); $this->loadGroupFileSetToRestore(); $this->loadRestoreClients(); - if (isset($_SESSION['restore_single_jobid'])) { - $this->restore_single_jobid = $_SESSION['restore_single_jobid']; + if ($this->BackupClient->DataChanged) { + // remove previous restore jobid only if user changed client selection + $this->Session->remove('restore_jobid'); } } elseif ($param->CurrentStepIndex === 1) { if ($this->Request->contains('backup_to_restore')) { - $_SESSION['restore_single_jobid'] = $this->Request['backup_to_restore']; - } - if (isset($_SESSION['restore_path'])) { - $_SESSION['restore_path'] = array(); + $this->Session->add( + 'restore_jobid', + $this->Request['backup_to_restore'] + ); } + $this->setRestorePath(); $this->setFileVersions(); - $this->loadSelectedFiles(); - $this->loadFileVersions(); + $this->loadSelectedFiles(null, null); + $this->loadFileVersions(null, null); $this->goToPath(); } elseif ($param->CurrentStepIndex === 2) { $this->loadRequiredVolumes(); } elseif ($param->CurrentStepIndex === 3) { - if (isset($_SESSION['file_relocation'])) { - $this->file_relocation_opt = $_SESSION['file_relocation']; + if ($this->Session->contains('file_relocation')) { + $this->file_relocation_opt = $this->Session['file_relocation']; } } elseif ($param->CurrentStepIndex === 4) { if ($this->Request->contains('file_relocation')) { - $_SESSION['file_relocation'] = $this->Request['file_relocation']; + $this->Session->add( + 'file_relocation', + $this->Request['file_relocation'] + ); } - $this->file_relocation_opt = $_SESSION['file_relocation']; + $this->file_relocation_opt = $this->Session['file_relocation']; } $this->setNavigationButtons(); } @@ -211,16 +230,15 @@ class RestoreWizard extends BaculumWebPage * @return none */ public function wizardPrev($sender, $param) { - if ($param->CurrentStepIndex === 2) { - $this->restore_single_jobid = $_SESSION['restore_single_jobid']; + if ($param->CurrentStepIndex === 1) { + } elseif ($param->CurrentStepIndex === 2) { $this->loadBackupsForClient(); } elseif ($param->CurrentStepIndex === 3) { - $this->setFileVersions(); - $this->loadSelectedFiles(); - $this->loadFileVersions(); + $this->loadSelectedFiles(null, null); + $this->loadFileVersions(null, null); $this->goToPath(); } elseif ($param->CurrentStepIndex === 5) { - $this->file_relocation_opt = $_SESSION['file_relocation']; + $this->file_relocation_opt = $this->Session['file_relocation']; } } @@ -242,14 +260,18 @@ class RestoreWizard extends BaculumWebPage * @return none */ public function loadBackupClients() { - $client_list = array(); - $clients = $this->getModule('api')->get(array('clients'))->output; - for ($i = 0; $i < count($clients); $i++) { - $client_list[$clients[$i]->name] = $clients[$i]->name; + $client_list = []; + $clients = $this->getModule('api')->get( + ['clients'] + )->output; + if (is_array($clients)) { + for ($i = 0; $i < count($clients); $i++) { + $client_list[$clients[$i]->clientid] = $clients[$i]->name; + } + asort($client_list); } - asort($client_list); - $this->BackupClientName->dataSource = $client_list; - $this->BackupClientName->dataBind(); + $this->BackupClient->DataSource = $client_list; + $this->BackupClient->dataBind(); } /** @@ -258,13 +280,18 @@ class RestoreWizard extends BaculumWebPage * @return none */ public function loadRestoreClients() { - $client_list = array(); - $clients = $this->getModule('api')->get(array('clients'))->output; - for ($i = 0; $i < count($clients); $i++) { - $client_list[$clients[$i]->name] = $clients[$i]->name; + $client_list = []; + $clients = $this->getModule('api')->get( + ['clients'] + )->output; + if (is_array($clients)) { + for ($i = 0; $i < count($clients); $i++) { + $client_list[$clients[$i]->clientid] = $clients[$i]->name; + } + asort($client_list); } - $this->RestoreClient->SelectedValue = $this->BackupClientName->SelectedValue; - $this->RestoreClient->dataSource = $client_list; + $this->RestoreClient->DataSource = $client_list; + $this->RestoreClient->SelectedValue = $this->BackupClient->SelectedValue; $this->RestoreClient->dataBind(); } @@ -274,10 +301,12 @@ class RestoreWizard extends BaculumWebPage * @return none */ public function loadBackupsForClient() { - $clientid = $this->getBackupClientId(); - $jobs_for_client = $this->getModule('api')->get(array('clients', $clientid, 'jobs'))->output; + $clientid = $this->BackupClient->SelectedValue; + $jobs_for_client = $this->getModule('api')->get( + ['clients', $clientid, 'jobs'] + )->output; $jobs = $this->getModule('misc')->objectToArray($jobs_for_client); - $this->jobs_to_restore = array_filter($jobs, array($this, 'isJobToRestore')); + $this->jobs_to_restore = array_filter($jobs, [$this, 'isJobToRestore']); } /** @@ -287,7 +316,7 @@ class RestoreWizard extends BaculumWebPage * @return true if job should be listed to restore, otherwise false */ private function isJobToRestore($job) { - $jobtype = array('B'); + $jobtype = ['B']; if ($this->EnableCopyJobRestore->Checked) { $jobtype[] = 'C'; } @@ -305,25 +334,7 @@ class RestoreWizard extends BaculumWebPage $this->setFileVersions(); $this->setFilesToRestore(); $this->markFileToRestore(null, null); - $_SESSION['restore_path'] = array(); - } - - - /** - * Get selected backup client identifier. - * - * @return mixed client identifier or null if no clientid found - */ - public function getBackupClientId() { - $clientid = null; - $clients = $this->getModule('api')->get(array('clients'))->output; - for ($i = 0; $i < count($clients); $i++) { - if ($clients[$i]->name === $this->BackupClientName->SelectedValue) { - $clientid = $clients[$i]->clientid; - break; - } - } - return $clientid; + $this->setRestorePath(); } /** @@ -334,7 +345,7 @@ class RestoreWizard extends BaculumWebPage */ public function getBackupClient($clientid) { $client = null; - $clients = $this->getModule('api')->get(array('clients'))->output; + $clients = $this->getModule('api')->get(['clients'])->output; for ($i = 0; $i < count($clients); $i++) { if ($clients[$i]->clientid === $clientid) { $client = $clients[$i]->name; @@ -350,18 +361,18 @@ class RestoreWizard extends BaculumWebPage * @return none */ public function loadGroupBackupToRestore() { - $jobs = $this->getModule('api')->get(array('jobs'))->output; + $jobs = $this->getModule('api')->get(['jobs'])->output; $jobs = $this->getModule('misc')->objectToArray($jobs); - $clientid = $this->getBackupClientId(); - $job_group_list = array(); + $clientid = intval($this->BackupClient->SelectedValue); + $job_group = []; for ($i = 0; $i < count($jobs); $i++) { - $job = $this->getModule('misc')->objectToArray($jobs[$i]); if ($this->isJobToRestore($jobs[$i]) && $jobs[$i]['clientid'] === $clientid) { - $job_group_list[$jobs[$i]['name']] = $jobs[$i]['name']; + $job_group[$jobs[$i]['name']] = $jobs[$i]['name']; } } + asort($job_group); - $this->GroupBackupToRestore->dataSource = $job_group_list; + $this->GroupBackupToRestore->DataSource = $job_group; $this->GroupBackupToRestore->dataBind(); } @@ -371,14 +382,14 @@ class RestoreWizard extends BaculumWebPage * @return none */ public function loadGroupFileSetToRestore() { - $filesets = $this->getModule('api')->get(array('filesets'))->output; - $fileset_list = array(); + $filesets = $this->getModule('api')->get(['filesets'])->output; + $fileset_group = []; for ($i = 0; $i < count($filesets); $i++) { - $fileset_list[$filesets[$i]->filesetid] = $filesets[$i]->fileset . ' (' . $filesets[$i]->createtime . ')'; + $fileset_group[$filesets[$i]->filesetid] = $filesets[$i]->fileset . ' (' . $filesets[$i]->createtime . ')'; } - asort($fileset_list); + asort($fileset_group); - $this->GroupBackupFileSet->dataSource = $fileset_list; + $this->GroupBackupFileSet->DataSource = $fileset_group; $this->GroupBackupFileSet->dataBind(); } @@ -389,46 +400,47 @@ class RestoreWizard extends BaculumWebPage */ private function prepareBrowserContent() { $jobids = $this->getElementaryBackup(); - $elements = array(); + $elements = []; if (!empty($jobids)) { // generating Bvfs may take a moment $this->generateBvfsCache($jobids); // get directory and file list - $query = '?' . http_build_query(array( + $query = '?' . http_build_query([ 'jobids' => $jobids, - 'path' => implode($_SESSION['restore_path']), + 'path' => implode($this->Session['restore_path']), 'output' => 'json' - )); + ]); $bvfs_dirs = $this->getModule('api')->get( - array('bvfs', 'lsdirs', $query) + ['bvfs', 'lsdirs', $query] ); - $dirs = array(); + $dirs = []; if ($bvfs_dirs->error === 0) { $dirs = json_decode(json_encode($bvfs_dirs->output), true); } // get files list $bvfs_files = $this->getModule('api')->get( - array('bvfs', 'lsfiles', $query) + ['bvfs', 'lsfiles', $query] ); - $files = array(); + $files = []; if ($bvfs_files->error === 0) { $files = json_decode(json_encode($bvfs_files->output), true); } $elements = array_merge($dirs, $files); - $elements = array_map(array('RestoreWizard', 'addUniqid'), $elements); - if (count($_SESSION['restore_path']) > 0) { + $elements = array_map(['RestoreWizard', 'addUniqid'], $elements); + if (count($this->Session['restore_path']) > 0) { array_unshift($elements, $this->browser_root_dir); } } if (count($elements) > 0) { $this->NoFileFound->Display = 'None'; - } elseif (isset($_SESSION['restore_single_jobid'])) { + } elseif ($this->Session->contains('restore_jobid')) { $this->NoFileFound->Display = 'Dynamic'; } - $this->loadBrowserFiles($elements); + $this->setBrowserFiles($elements); + $this->loadBrowserFiles(null, null); } /** @@ -456,18 +468,18 @@ class RestoreWizard extends BaculumWebPage */ private function getElementaryBackup() { $jobids = ''; - if ($this->OnlySelectedBackupSelection->Checked && isset($_SESSION['restore_single_jobid'])) { + if ($this->OnlySelectedBackupSelection->Checked && $this->Session->contains('restore_jobid')) { $params = [ - 'jobid' => $_SESSION['restore_single_jobid'] + 'jobid' => $this->Session['restore_jobid'] ]; if ($this->EnableCopyJobRestore->Checked) { $params['inc_copy_job'] = 1; } $query = '?' . http_build_query($params); $jobs = $this->getModule('api')->get( - array('bvfs', 'getjobids', $query) + ['bvfs', 'getjobids', $query] ); - $ids = is_object($jobs) ? $jobs->output : array(); + $ids = is_object($jobs) ? $jobs->output : []; foreach ($ids as $jobid) { if (preg_match('/^([\d\,]+)$/', $jobid, $match) == 1) { $jobids = $match[1]; @@ -475,23 +487,23 @@ class RestoreWizard extends BaculumWebPage } } if (empty($jobids)) { - $jobids = $_SESSION['restore_single_jobid']; + $jobids = $this->Session['restore_jobid']; } } else { $params = [ - 'client' => $this->BackupClientName->SelectedValue, + 'clientid' => $this->BackupClient->SelectedValue, 'filesetid' => $this->GroupBackupFileSet->SelectedValue ]; if ($this->EnableCopyJobRestore->Checked) { $params['inc_copy_job'] = 1; } $query = '?' . http_build_query($params); - $jobs_recent = $this->getModule('api')->get(array( + $jobs_recent = $this->getModule('api')->get([ 'jobs', 'recent', $this->GroupBackupToRestore->SelectedValue, $query - )); + ]); if (count($jobs_recent->output) > 0) { $ids = $jobs_recent->output; $jobids = implode(',', $ids); @@ -531,19 +543,23 @@ class RestoreWizard extends BaculumWebPage * @return none */ private function goToPath($path = '', $full_path = false) { - if (!empty($path) && !$full_path) { + if (!empty($path) && !$full_path && $this->Session->contains('restore_path')) { if ($path == $this->browser_up_dir['name']) { - array_pop($_SESSION['restore_path']); + $rp = $this->Session['restore_path']; + array_pop($rp); + $this->Session->add('restore_path', $rp); } elseif ($path == $this->browser_root_dir['name']) { - $_SESSION['restore_path'] = array(); + $this->setRestorePath(); } else { - array_push($_SESSION['restore_path'], $path); + $rp = $this->Session['restore_path']; + array_push($rp, $path); + $this->Session->add('restore_path', $rp); } } if ($full_path && is_array($path)) { - $_SESSION['restore_path'] = $path; + $this->setRestorePath($path); } - $this->setBrowserPath(); + $this->loadBrowserPath(); $this->prepareBrowserContent(); } @@ -556,39 +572,22 @@ class RestoreWizard extends BaculumWebPage * @return none */ public function addFileToRestore($sender, $param) { - $uniqid = null; - $source_element_id = null; - $file_prop = array(); - if (get_class($param) == 'Prado\Web\UI\ActiveControls\TCallbackEventParameter') { - $id_parts = explode('_', $sender->ClientID, 6); - $source_element_id = $id_parts[3]; - $uniqid = $param->CallbackParameter; - } else { - $control = $param->DraggableControl; - $item = $control->getNamingContainer(); - $id_parts = explode('_', $control->ClientID, 6); - $source_element_id = $id_parts[3]; - } - if ($source_element_id == $this->VersionsDataGrid->ID) { - if (is_null($uniqid)) { - $uniqid = $this->VersionsDataGrid->getDataKeys()->itemAt($item->getItemIndex()); - } + $file_prop = []; + list($source, $uniqid) = explode('|', $param->CallbackParameter, 2); + if ($source === 'version_browser') { $file_prop = $this->getFileVersions($uniqid); - } else { - if (is_null($uniqid)) { - $uniqid = $this->DataGridFiles->getDataKeys()->itemAt($item->getItemIndex()); - } + } elseif ($source === 'file_browser') { $file_prop = $this->getBrowserFile($uniqid); } if ($file_prop['name'] != $this->browser_root_dir['name'] && $file_prop['name'] != $this->browser_up_dir['name']) { $this->markFileToRestore($uniqid, $file_prop); - $this->loadSelectedFiles(); + $this->loadSelectedFiles(null, null); } } /** - * Remove file from files marked to restre. + * Remove file from files marked to restore. * * @param TCallback $sender sender object * @param TEventParameter $param param object @@ -597,7 +596,7 @@ class RestoreWizard extends BaculumWebPage public function removeSelectedFile($sender, $param) { $uniqid = $param->CallbackParameter; $this->unmarkFileToRestore($uniqid); - $this->loadSelectedFiles(); + $this->loadSelectedFiles(null, null); } /** @@ -614,9 +613,9 @@ class RestoreWizard extends BaculumWebPage $this->goToPath($filename); return; } - $clientname = $this->BackupClientName->SelectedValue; + $clientid = $this->BackupClient->SelectedValue; $params = [ - 'client' => $clientname, + 'clientid' => $clientid, 'jobid' => $jobid, 'pathid' => $pathid, 'filenameid' => $filenameid, @@ -638,21 +637,15 @@ class RestoreWizard extends BaculumWebPage }; $query = '?' . http_build_query($params); - $versions = $this->getModule('api')->get(array('bvfs', 'versions', $query))->output; + $versions = $this->getModule('api')->get( + ['bvfs', 'versions', $query] + )->output; $versions = json_decode(json_encode($versions), true); $file_versions = array_map($add_version_filename_func, $versions); - $file_versions = array_map(array('RestoreWizard', 'addUniqid'), $file_versions); + $file_versions = array_map(['RestoreWizard', 'addUniqid'], $file_versions); $this->setFileVersions($file_versions); - $this->VersionsDataGrid->dataSource = $file_versions; - $this->VersionsDataGrid->dataBind(); - $this->loadSelectedFiles(); - } - - /** - * Call formatters method. - */ - public function callFormatters($sender, $param) { - $this->getCallbackClient()->callClientFunction('set_formatters'); + $this->loadFileVersions(null, null); + $this->loadSelectedFiles(null, null); } /* @@ -661,10 +654,9 @@ class RestoreWizard extends BaculumWebPage * @param array $files files to list. * @return none */ - private function loadBrowserFiles($files) { - $this->setBrowserFiles($files); - $this->DataGridFiles->dataSource = $files; - $this->DataGridFiles->dataBind(); + public function loadBrowserFiles($sender, $param) { + $files = $this->Session->contains('files_browser') ? $this->Session['files_browser'] : []; + $this->getCallbackClient()->callClientFunction('oRestoreBrowserFiles.populate', [$files]); } /** @@ -672,9 +664,9 @@ class RestoreWizard extends BaculumWebPage * * @return none; */ - private function loadFileVersions() { - $this->VersionsDataGrid->dataSource = $_SESSION['files_versions']; - $this->VersionsDataGrid->dataBind(); + public function loadFileVersions($sender, $param) { + $versions = $this->Session->contains('files_versions') ? $this->Session['files_versions'] : []; + $this->getCallbackClient()->callClientFunction('oRestoreBrowserVersions.populate', [array_values($versions)]); } /** @@ -682,9 +674,9 @@ class RestoreWizard extends BaculumWebPage * * @return none */ - private function loadSelectedFiles() { - $this->SelectedVersionsDataGrid->dataSource = $_SESSION['restore']; - $this->SelectedVersionsDataGrid->dataBind(); + public function loadSelectedFiles($sender, $param) { + $files = $this->Session->contains('files_restore') ? $this->Session['files_restore'] : []; + $this->getCallbackClient()->callClientFunction('oRestoreBrowserSelectedFiles.populate', [array_values($files)]); } /** @@ -692,8 +684,9 @@ class RestoreWizard extends BaculumWebPage * * @return none */ - private function setBrowserPath() { - $this->PathField->Text = implode($_SESSION['restore_path']); + private function loadBrowserPath() { + $path = $this->Session->contains('restore_path') ? $this->Session['restore_path'] : []; + $this->PathField->Text = implode($path); } /** @@ -704,8 +697,8 @@ class RestoreWizard extends BaculumWebPage */ private function generateBvfsCache($jobids) { $this->getModule('api')->set( - array('bvfs', 'update'), - array('jobids' => $jobids) + ['bvfs', 'update'], + ['jobids' => $jobids] ); } @@ -715,8 +708,8 @@ class RestoreWizard extends BaculumWebPage * @param array $versions file versions data * @return none */ - private function setFileVersions($versions = array()) { - $_SESSION['files_versions'] = $versions; + private function setFileVersions($versions = []) { + $this->Session->add('files_versions', $versions); } /** @@ -726,11 +719,13 @@ class RestoreWizard extends BaculumWebPage * @return none */ private function getFileVersions($uniqid) { - $versions = array(); - foreach ($_SESSION['files_versions'] as $file) { - if (key_exists('uniqid', $file) && $file['uniqid'] === $uniqid) { - $versions = $file; - break; + $versions = []; + if ($this->Session->contains('files_versions')) { + foreach ($this->Session['files_versions'] as $file) { + if (key_exists('uniqid', $file) && $file['uniqid'] === $uniqid) { + $versions = $file; + break; + } } } return $versions; @@ -742,8 +737,18 @@ class RestoreWizard extends BaculumWebPage * @param array $files file list * @return none */ - private function setBrowserFiles($files = array()) { - $_SESSION['files_browser'] = $files; + private function setBrowserFiles($files = []) { + $this->Session->add('files_browser', $files); + } + + /** + * Set restore browser path. + * + * @param array $files file list + * @return none + */ + private function setRestorePath($path = []) { + $this->Session->add('restore_path', $path); } /** @@ -753,11 +758,13 @@ class RestoreWizard extends BaculumWebPage * @return none */ private function getBrowserFile($uniqid) { - $element = array(); - foreach ($_SESSION['files_browser'] as $file) { - if (key_exists('uniqid', $file) && $file['uniqid'] === $uniqid) { - $element = $file; - break; + $element = []; + if ($this->Session->contains('files_browser')) { + foreach ($this->Session['files_browser'] as $file) { + if (key_exists('uniqid', $file) && $file['uniqid'] === $uniqid) { + $element = $file; + break; + } } } return $element; @@ -772,9 +779,11 @@ class RestoreWizard extends BaculumWebPage */ private function markFileToRestore($uniqid, $file) { if (is_null($uniqid)) { - $_SESSION['restore'] = array(); + $this->setFilesToRestore(); } elseif ($file['name'] != $this->browser_root_dir['name'] && $file['name'] != $this->browser_up_dir['name']) { - $_SESSION['restore'][$uniqid] = $file; + $fr = $this->Session['files_restore']; + $fr[$uniqid] = $file; + $this->Session->add('files_restore', $fr); } } @@ -785,8 +794,10 @@ class RestoreWizard extends BaculumWebPage * @return none */ private function unmarkFileToRestore($uniqid) { - if (key_exists($uniqid, $_SESSION['restore'])) { - unset($_SESSION['restore'][$uniqid]); + if (key_exists($uniqid, $this->Session['files_restore'])) { + $fr = $this->Session['files_restore']; + unset($fr[$uniqid]); + $this->Session['files_restore'] = $fr; } } @@ -796,7 +807,7 @@ class RestoreWizard extends BaculumWebPage * @return array list with files to restore */ public function getFilesToRestore() { - return $_SESSION['restore']; + return ($this->Session->contains('files_restore') ? $this->Session['files_restore'] : []); } /** @@ -805,8 +816,8 @@ class RestoreWizard extends BaculumWebPage * @param array $files files to restore * @return none */ - public function setFilesToRestore($files = array()) { - $_SESSION['restore'] = $files; + public function setFilesToRestore($files = []) { + $this->Session->add('files_restore', $files); } /** @@ -816,9 +827,9 @@ class RestoreWizard extends BaculumWebPage * @return array list fileids and dirids */ public function getRestoreElements($as_object = false) { - $fileids = array(); - $dirids = array(); - $findexes = array(); + $fileids = []; + $dirids = []; + $findexes = []; foreach ($this->getFilesToRestore() as $uniqid => $properties) { if ($properties['type'] == 'dir') { $dirids[] = $properties['pathid']; @@ -829,7 +840,11 @@ class RestoreWizard extends BaculumWebPage } } } - $ret = array('fileid' => $fileids, 'dirid' => $dirids, 'findex' => $findexes); + $ret = [ + 'fileid' => $fileids, + 'dirid' => $dirids, + 'findex' => $findexes + ]; if ($as_object === true) { $ret = (object)$ret; } @@ -845,7 +860,7 @@ class RestoreWizard extends BaculumWebPage $jobids = $this->getElementaryBackup(); $path = self::BVFS_PATH_PREFIX . getmypid(); $restore_elements = $this->getRestoreElements(); - $cmd_props = array('jobids' => $jobids, 'path' => $path); + $cmd_props = ['jobids' => $jobids, 'path' => $path]; $is_element = false; if (count($restore_elements['fileid']) > 0) { $cmd_props['fileid'] = implode(',', $restore_elements['fileid']); @@ -863,7 +878,7 @@ class RestoreWizard extends BaculumWebPage $jobid = null; $ret = new stdClass; $restore_props = []; - $restore_props['client'] = $this->RestoreClient->SelectedValue; + $restore_props['client'] = $this->RestoreClient->SelectedItem->Text; if ($_SESSION['file_relocation'] == 2) { if (!empty($this->RestoreStripPrefix->Text)) { $restore_props['strip_prefix'] = $this->RestoreStripPrefix->Text; @@ -885,27 +900,39 @@ class RestoreWizard extends BaculumWebPage $restore_props['replace'] = $this->ReplaceFiles->SelectedValue; $restore_props['restorejob'] = $this->RestoreJob->SelectedValue; if ($is_element) { - $this->getModule('api')->create(array('bvfs', 'restore'), $cmd_props); + $this->getModule('api')->create( + ['bvfs', 'restore'], + $cmd_props + ); $restore_props['rpath'] = $path; - $ret = $this->getModule('api')->create(array('jobs', 'restore'), $restore_props); + $ret = $this->getModule('api')->create( + ['jobs', 'restore'], + $restore_props + ); $jobid = $this->getModule('misc')->findJobIdStartedJob($ret->output); // Remove temporary BVFS table - $this->getModule('api')->set(array('bvfs', 'cleanup'), array('path' => $path)); - } elseif (count($_SESSION['files_browser']) === 0 && isset($_SESSION['restore_single_jobid'])) { + $this->getModule('api')->set(['bvfs', 'cleanup'], ['path' => $path]); + } elseif (count($this->Session['files_browser']) === 0 && $this->Session->contains('restore_jobid')) { $restore_props['full'] = 1; - $restore_props['id'] = $_SESSION['restore_single_jobid']; - $job = $this->getModule('api')->get(array('jobs', $_SESSION['restore_single_jobid']))->output; + $restore_props['id'] = $this->Session['restore_jobid']; + $job = $this->getModule('api')->get( + ['jobs', $this->Session['restore_jobid']] + )->output; if (is_object($job)) { $restore_props['fileset'] = $job->fileset; } - $ret = $this->getModule('api')->create(array('jobs', 'restore'), $restore_props); + $ret = $this->getModule('api')->create( + ['jobs', 'restore'], + $restore_props + ); $jobid = $this->getModule('misc')->findJobIdStartedJob($ret->output); } else { $ret->output = ['No file to restore found']; } - $url_params = array(); + $url_params = []; if (is_numeric($jobid)) { + $this->resetWizard(); $url_params['jobid'] = $jobid; $this->goToPage('JobHistoryView', $url_params); } else { @@ -920,8 +947,10 @@ class RestoreWizard extends BaculumWebPage * @return none */ private function loadRestoreJobs() { - $restore_job_tasks = $this->getModule('api')->get(array('jobs', 'resnames', '?type=R'))->output; - $jobs = array(); + $restore_job_tasks = $this->getModule('api')->get( + ['jobs', 'resnames', '?type=R'] + )->output; + $jobs = []; foreach ($restore_job_tasks as $director => $restore_jobs) { $jobs = array_merge($jobs, $restore_jobs); } @@ -930,7 +959,7 @@ class RestoreWizard extends BaculumWebPage } private function loadRequiredVolumes() { - $volumes = array(); + $volumes = []; foreach ($this->getFilesToRestore() as $uniqid => $props) { list($jobid, $pathid, $fileid) = explode(':', $uniqid, 3); if ($jobid === '0') { @@ -942,13 +971,15 @@ class RestoreWizard extends BaculumWebPage continue; } // it can be expensive for many restore paths - $result = $this->getModule('api')->get(array('volumes', 'required', $jobid, $fileid)); + $result = $this->getModule('api')->get( + ['volumes', 'required', $jobid, $fileid] + ); if ($result->error === 0) { for ($i = 0; $i < count($result->output); $i++) { - $volumes[$result->output[$i]->volume] = array( + $volumes[$result->output[$i]->volume] = [ 'volume' => $result->output[$i]->volume, 'inchanger' => $result->output[$i]->inchanger - ); + ]; } } } @@ -966,11 +997,13 @@ class RestoreWizard extends BaculumWebPage $this->setBrowserFiles(); $this->setFileVersions(); $this->setFilesToRestore(); - $this->markFileToRestore(null, null); + $this->Session->remove('files_browser'); + $this->Session->remove('files_versions'); + $this->Session->remove('files_restore'); $this->loadRestoreJobs(); - $_SESSION['restore_path'] = array(); - $_SESSION['restore_single_jobid'] = null; - unset($_SESSION['file_relocation']); + $this->Session->remove('restore_path'); + $this->Session->remove('restore_jobid'); + $this->Session->remove('file_relocation'); } } ?> diff --git a/gui/baculum/themes/Baculum-v2/css/restore-wizard.css b/gui/baculum/themes/Baculum-v2/css/restore-wizard.css index 5508df7d1..c298e7c04 100644 --- a/gui/baculum/themes/Baculum-v2/css/restore-wizard.css +++ b/gui/baculum/themes/Baculum-v2/css/restore-wizard.css @@ -11,7 +11,6 @@ width: 100%; height: 100% !important; background-color: white; - padding: 0 4px; } #restore-browser-files-loading { @@ -21,29 +20,39 @@ background: rgba(182,182,182,0.4) url('/themes/Baculum-v2/loader-small.gif') no-repeat center center; } +#restore-browser-files-content { + position: relative; + height: 100%; +} + .file-browser-detail { width: 100%; } -tr.file-browser-element { +div.file-browser-element { cursor: pointer; + padding: 4px 8px; + clear: both; } -tr.file-browser-element:hover { +div.file-browser-element:hover { background-color: rgb(219, 222, 223); } -.restore-browser-element-size { +.restore-browser-element-right { float: right; width: 100px; } -.restore-browser-element-size { +.restore-browser-element-right { line-height: 24px; } .file-browser-watermark { - padding: 68px 10px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); text-align: center; font-size: 21px; color: rgb(185, 184, 184);