]> git.sur5r.net Git - bacula/bacula/blob - gui/baculum/protected/Web/Pages/RestoreWizard.php
4d88700e6356c908008f86a289ed53d52731246a
[bacula/bacula] / gui / baculum / protected / Web / Pages / RestoreWizard.php
1 <?php
2 /*
3  * Bacula(R) - The Network Backup Solution
4  * Baculum   - Bacula web interface
5  *
6  * Copyright (C) 2013-2016 Kern Sibbald
7  *
8  * The main author of Baculum is Marcin Haba.
9  * The original author of Bacula is Kern Sibbald, with contributions
10  * from many others, a complete list can be found in the file AUTHORS.
11  *
12  * You may use this file and others of this release according to the
13  * license defined in the LICENSE file, which includes the Affero General
14  * Public License, v3.0 ("AGPLv3") and some additional permissions and
15  * terms pursuant to its AGPLv3 Section 7.
16  *
17  * This notice must be preserved when any source code is
18  * conveyed and/or propagated.
19  *
20  * Bacula(R) is a registered trademark of Kern Sibbald.
21  */
22
23 Prado::using('Application.Web.Class.BaculumWebPage'); 
24 Prado::using('System.Exceptions.TException');
25 Prado::using('System.Web.UI.WebControls.TWizard');
26 Prado::using('System.Web.UI.ActiveControls.TActiveDropDownList');
27 Prado::using('System.Web.UI.ActiveControls.TActivePanel');
28 Prado::using('System.Web.UI.ActiveControls.TActiveLinkButton');
29 Prado::using('System.Web.UI.ActiveControls.TActiveImageButton');
30 Prado::using('System.Web.UI.ActiveControls.TDropContainer');
31 Prado::using('System.Web.UI.ActiveControls.TDraggable');
32 Prado::using('System.Web.UI.ActiveControls.TActiveRadioButton');
33 Prado::using('System.Web.UI.ActiveControls.TActiveDataGrid');
34 Prado::using('System.Web.UI.ActiveControls.TCallback');
35
36 class RestoreWizard extends BaculumWebPage
37 {
38         private $jobLevelsToRestore = array('F' => 'Full', 'I' => 'Incremental', 'D'=> 'Differential');
39         private $jobs = null;
40         private $filesets = null;
41         private $storages = null;
42         private $clients = null;
43         private $browserRootDir = array('name' => '.', 'type' => 'dir');
44         private $browserUpDir = array('name' => '..', 'type' => 'dir');
45
46         public $excludedElementsFromAdd = array('.', '..');
47
48         const BVFS_PATH_PREFIX = 'b2';
49
50         public function onPreInit($param) {
51                 parent::onPreInit($param);
52                 $this->Application->getModule('web_users')->loginUser();
53         }
54
55         public function onInit($param) {
56                 parent::onInit($param);
57                 if(!$this->IsPostBack && !$this->IsCallBack) {
58                         $this->setBrowserFiles(array());
59                         $this->setFileVersions(array());
60                         $this->setFilesToRestore(array());
61                         $this->markFileToRestore(null, null);
62                         $_SESSION['restore_path'] = array();
63                 }
64         }
65
66         public function onLoad($param) {
67                 parent::onLoad($param);
68                         if($this->RestoreWizard->ActiveStepIndex == 0) {
69                                 $this->jobs = $this->getModule('api')->get(array('jobs'))->output;
70                                 $this->filesets = $this->getModule('api')->get(array('filesets'))->output;
71                         }
72                         $this->clients = $this->getModule('api')->get(array('clients'))->output;
73
74                         if(!$this->IsCallBack && (($this->RestoreWizard->ActiveStepIndex == 1 && $this->getPage()->BackupToRestore->ItemCount > 0) || $this->RestoreWizard->ActiveStepIndex == 3)) {
75                                 $this->setFileVersions(array());
76                                 $this->setBrowserPath('');
77                                 $this->prepareFilesToRestore();
78                                 $this->prepareVersionsToRestore();
79                         }
80         }
81
82         public function addFileToRestore($sender, $param) {
83                 $fileid = null;
84                 if (isset($param->callbackParameter)) {
85                         list(, , , $sourceElementID, , ) = explode('_', $sender->ClientID, 6);
86                         $fileid = $param->callbackParameter;
87                 } else {
88                         $control = $param->getDroppedControl();
89                         $item = $control->getNamingContainer();
90                         list(, , , $sourceElementID, , ) = explode('_', $param->getDragElementID(), 6); // I know that it is ugly.
91                 }
92                 if($sourceElementID == $this->VersionsDataGrid->ID) {
93                         if (is_null($fileid)) {
94                                 $fileid = $this->VersionsDataGrid->getDataKeys()->itemAt($item->getItemIndex());
95                         }
96                         $fileProperties = $this->getFileVersions($fileid);
97                 } else {
98                         if (is_null($fileid)) {
99                                 $fileid = $this->DataGridFiles->getDataKeys()->itemAt($item->getItemIndex());
100                         }
101                         $fileProperties = $this->getBrowserFile($fileid);
102                 }
103                 if($fileProperties['name'] != $this->browserRootDir['name'] && $fileProperties['name'] != $this->browserUpDir['name']) {
104                         $this->markFileToRestore($fileid, $fileProperties);
105                         $this->prepareFilesToRestore();
106                 }
107         }
108
109         public function removeSelectedFile($sender, $param) {
110                 $fileid = $param->CallbackParameter;
111                 $this->unmarkFileToRestore($fileid);
112                 $this->prepareFilesToRestore();
113         }
114
115         public function getVersions($sender, $param) {
116                 list($filename, $pathid, $filenameid, $jobid) = explode('|', $param->CallbackParameter, 4);
117                 if($filenameid == 0) {
118                         $this->setBrowserPath($filename);
119                         return;
120                 }
121                 $clientname = null;
122                 foreach($this->clients as $client) {
123                         if($client->clientid == $this->BackupClientName->SelectedValue) {
124                                 $clientname = $client->name;
125                                 break;
126                         }
127                 }
128                 $versions = $this->getModule('api')->get(array('bvfs', 'versions', $clientname, $jobid, $pathid, $filenameid))->output;
129                 $fileVersions = $this->getModule('misc')->parseFileVersions($filename, $versions);
130                 $this->setFileVersions($fileVersions);
131                 $this->VersionsDataGrid->dataSource = $fileVersions;
132                 $this->VersionsDataGrid->dataBind();
133                 $this->prepareFilesToRestore();
134         }
135
136         public function refreshSelectedFiles($sender, $param) {
137                 $this->prepareFilesToRestore();
138                 $this->SelectedVersionsDropper->render($param->NewWriter);
139         }
140
141         public function NextStep($sender, $param) {
142         }
143         
144         public function PreviousStep($sender, $param) {
145         }
146
147         public function wizardStop($sender, $param) {
148                 $this->goToDefaultPage();
149         }
150
151         public function setJobs($sender, $param) {
152                 $jobsList = $jobsGroupList = $fileSetsList = array();
153                 if(is_array($this->jobs)) {
154                         foreach($this->jobs as $job) {
155                                 if(array_key_exists($job->level, $this->jobLevelsToRestore) && $job->type == 'B' && $job->jobstatus == 'T' && $job->clientid == $this->BackupClientName->SelectedValue) {
156                                         $jobsList[$job->jobid] = sprintf('[%s] %s, %s, %s', $job->jobid, $job->name, $this->jobLevelsToRestore[$job->level], $job->endtime);
157                                         $jobsGroupList[$job->name] = $job->name;
158                                         //$fileSetsList[$job->filesetid] = $this->getFileSet($job->filesetid)->fileset;
159                                 }
160                         }
161                 }
162                 
163                 foreach($this->filesets as $director => $filesets) {
164                         $fileSetsList = array_merge($filesets, $fileSetsList);
165                 }
166
167                 $this->BackupToRestore->dataSource = $jobsList;
168                 $this->BackupToRestore->dataBind();
169                 $this->GroupBackupToRestore->dataSource = $jobsGroupList;
170                 $this->GroupBackupToRestore->dataBind();
171                 $this->GroupBackupFileSet->dataSource = array_combine($fileSetsList, $fileSetsList);
172                 $this->GroupBackupFileSet->dataBind();
173                 $this->setRestoreClients($sender, $param);
174         }
175
176         public function setBackupClients($sender, $param) {
177                 if(!$this->IsPostBack) {
178                         $clientsList = array();
179                         foreach($this->clients as $client) {
180                                 $clientsList[$client->clientid] = $client->name;
181                         }
182                         $this->BackupClientName->dataSource = $clientsList;
183                         $this->BackupClientName->dataBind();
184                 }
185         }
186
187         public function setRestoreClients($sender, $param) {
188                 if(!$this->IsPostBack || $sender->ID == $this->BackupClientName->ID) {
189                         $clientsList = array();
190                         foreach($this->clients as $client) {
191                                 $clientsList[$client->clientid] = $client->name;
192                         }
193                         $this->RestoreClient->SelectedValue = $this->BackupClientName->SelectedValue;
194                         $this->RestoreClient->dataSource = $clientsList;
195                         $this->RestoreClient->dataBind();
196                 }
197         }
198
199         public function getFileSet($filesetId) {
200                 $filesetObj = null;
201                 foreach($this->filesets as $fileset) {
202                         if($fileset->filesetid == $filesetId) {
203                                 $filesetObj = $fileset;
204                                 break;
205                         }
206                 }
207                 return $filesetObj;
208         }
209
210         public function setStorage($sender, $param) {
211                 if(!$this->IsPostBack) {
212                         $storagesList = array();
213                         $storages = $this->getModule('api')->get(array('storages'))->output;
214                         foreach($storages as $storage) {
215                                 $storagesList[$storage->storageid] = $storage->name;
216                         }
217                         $this->GroupBackupStorage->dataSource = $storagesList;
218                         $this->GroupBackupStorage->dataBind();
219                 }
220         }
221
222         public function setPool($sender, $param) {
223                 if(!$this->IsPostBack) {
224                         $poolsList = array();
225                         $pools = $this->getModule('api')->get(array('pools'))->output;
226                         foreach($pools as $pool) {
227                                 $poolsList[$pool->poolid] = $pool->name;
228                         }
229                         $this->GroupBackupPool->dataSource = $poolsList;
230                         $this->GroupBackupPool->dataBind();
231                 }
232         }
233
234         public function setBackupClient($sender, $param) {
235                 $this->ClientToRestore->SelectedValue = $param->SelectedValue;
236         } 
237
238         public function setBackupSelection($sender, $param) {
239                 $this->GroupBackupToRestoreField->Display = ($sender->ID == $this->GroupBackupSelection->ID) ? 'Dynamic' : 'None';
240                 $this->BackupToRestoreField->Display = ($sender->ID == $this->OnlySelectedBackupSelection->ID) ? 'Dynamic' : 'None';
241                 $this->setBrowserFiles(array());
242                 $this->setFileVersions(array());
243                 $this->setFilesToRestore(array());
244                 $this->markFileToRestore(null, null);
245                 $_SESSION['restore_path'] = array();
246         }
247
248         /*public function setGroupBackup($sender, $param) {
249                 foreach($this->jobs as $job) {
250                         if($job->name == $sender->SelectedValue) {
251                                 $this->GroupBackupFileSet->SelectedValue = $job->filesetid;
252                         }
253                 }
254         }*/
255
256         public function resetFileBrowser($sender, $param) {
257                 $this->markFileToRestore(null, null);
258                 $this->setBrowserPath($this->browserRootDir['name']);
259         }
260
261         private function prepareBrowserFiles($files) {
262                 $this->setBrowserFiles($files);
263                 $this->DataGridFiles->dataSource = $files;
264                 @$this->DataGridFiles->dataBind();
265         }
266
267         private function prepareVersionsToRestore() {
268                 $this->VersionsDataGrid->dataSource = $_SESSION['files_versions'];
269                 $this->VersionsDataGrid->dataBind();
270         }
271
272         private function prepareFilesToRestore() {
273                 $this->SelectedVersionsDataGrid->dataSource = $_SESSION['restore'];
274                 $this->SelectedVersionsDataGrid->dataBind();
275         }
276
277         private function setBrowserPath($path) {
278                 if(!empty($path)) {
279                         if($path == $this->browserUpDir['name']) {
280                                 array_pop($_SESSION['restore_path']);
281                         } elseif($path == $this->browserRootDir['name']) {
282                                 $_SESSION['restore_path'] = array();
283                         } else {
284                                 array_push($_SESSION['restore_path'], $path);
285                         }
286                 }
287                 $this->setBrowserLocalizator();
288                 $this->prepareBrowserContent();
289         }
290
291         private function getBrowserPath($stringFormat = false) {
292                 return ($stringFormat === true) ? implode($_SESSION['restore_path']) : $_SESSION['restore_path'];
293         }
294
295         private function setBrowserLocalizator() {
296                 $localization = $this->getBrowserPath(true);
297                 $this->PathField->HeaderText = mb_strlen($localization) > 56 ? '...' . mb_substr($localization, -56) : $localization;
298         }
299
300         private function prepareBrowserContent() {
301                 $jobids = $this->getElementaryBackup();
302         
303                 // generating Bvfs may takes a moment
304                 $this->generateBvfsCacheByJobids($jobids);
305                 $bvfsDirsList = $this->getModule('api')->set(array('bvfs', 'lsdirs'), array('jobids' => $jobids, 'path' => $this->getBrowserPath(true)));
306                 $bvfsDirs = is_object($bvfsDirsList) ? $bvfsDirsList->output : array();
307                 $dirs = $this->getModule('misc')->parseBvfsList($bvfsDirs);
308                 $bvfsFilesList = $this->getModule('api')->set(array('bvfs', 'lsfiles'), array('jobids' => $jobids, 'path' => $this->getBrowserPath(true)));
309                 $bvfsFiles = is_object($bvfsFilesList) ? $bvfsFilesList->output : array();
310                 $files = $this->getModule('misc')->parseBvfsList($bvfsFiles);
311                 $elements = array_merge($dirs, $files);
312                 if(count($this->getBrowserPath()) > 0) {
313                         array_unshift($elements, $this->browserRootDir);
314                 }
315                 $this->prepareBrowserFiles($elements);
316         }
317
318         private function getElementaryBackup() {
319                 $jobids = null;
320                 if($this->OnlySelectedBackupSelection->Checked === true) {
321                         $jobs = $this->getModule('api')->get(array('bvfs', 'getjobids', $this->BackupToRestore->SelectedValue));
322                         $ids = is_object($jobs) ? $jobs->output : array();
323                         foreach($ids as $jobid) {
324                                 if(preg_match('/^([\d\,]+)$/', $jobid, $match) == 1) {
325                                         $jobids = $match[1];
326                                         break;
327                                 }
328                         }
329                 } else {
330                         $jobsRecent = $this->getModule('api')->get(array('jobs', 'recent', $this->GroupBackupToRestore->SelectedValue, $this->BackupClientName->SelectedValue));
331                         if(isset($jobsRecent->output) && count($jobsRecent->output) > 0) {
332                                 $ids = $jobsRecent->output;
333                                 $jobids = implode(',', $ids);
334                         }
335                 }
336
337                 $completeJobids = (!is_null($jobids)) ? $jobids : $this->BackupToRestore->SelectedValue;
338                 return $completeJobids;
339         }
340
341         private function generateBvfsCacheByJobids($jobids) {
342                 $this->getModule('api')->set(array('bvfs', 'update'), array('jobids' => $jobids));
343         }
344
345         private function setFileVersions($versions) {
346                 $_SESSION['files_versions'] = $versions;
347         }
348
349         private function getFileVersions($fileid) {
350                 $versions = array();
351                 foreach($_SESSION['files_versions'] as $file) {
352                         if(array_key_exists('fileid', $file) && $file['fileid'] == $fileid) {
353                                 $versions = $file;
354                                 break;
355                         }
356                 }
357                 return $versions;
358         }
359
360         private function setBrowserFiles($files) {
361                 $_SESSION['files_browser'] = $files;
362         }
363
364         private function getBrowserFile($fileid) {
365                 $element = array();
366                 foreach($_SESSION['files_browser'] as $file) {
367                         if(array_key_exists('fileid', $file) && $file['fileid'] == $fileid) {
368                                 $element = $file;
369                                 break;
370                         }
371                 }
372                 return $element;
373         }
374
375         private function markFileToRestore($fileid, $file) {
376                 if($fileid === null) {
377                         $_SESSION['restore'] = array();
378                 } elseif($file['name'] != $this->browserRootDir['name'] && $file['name'] != $this->browserUpDir['name']) {
379                         $_SESSION['restore'][$fileid] = $file;
380                 }
381         }
382
383         private function unmarkFileToRestore($fileid) {
384                 if(array_key_exists($fileid, $_SESSION['restore'])) {
385                         unset($_SESSION['restore'][$fileid]);
386                 }
387         }
388
389         public function getFilesToRestore() {
390                 return $_SESSION['restore'];
391         }
392
393         public function setFilesToRestore($files) {
394                 $_SESSION['restore'] = $files;
395         }
396
397         public function getRestoreElements($asObject = false) {
398                 $fileids = array();
399                 $dirids = array();
400                 foreach($this->getFilesToRestore() as $fileid => $properties) {
401                         if($properties['type'] == 'dir') {
402                                 $dirids[] = $properties['pathid'];
403                         } elseif($properties['type'] == 'file') {
404                                 $fileids[] = $fileid;
405                         }
406                 }
407                 $ret = array('fileid' => $fileids, 'dirid' => $dirids);
408                 if($asObject === true) {
409                         $ret = (object)$ret;
410                 }
411                 return $ret;
412         }
413
414         public function wizardCompleted() {
415                 $jobids = $this->getElementaryBackup();
416                 $path = self::BVFS_PATH_PREFIX . str_replace(',', '', $jobids);
417                 $restoreElements = $this->getRestoreElements();
418                 $cmdProps = array('jobids' => $jobids, 'path' => $path);
419                 if(count($restoreElements['fileid']) > 0) {
420                         $cmdProps['fileid'] = implode(',', $restoreElements['fileid']);
421                 }
422                 if(count($restoreElements['dirid']) > 0) {
423                         $cmdProps['dirid'] = implode(',', $restoreElements['dirid']);
424                 }
425
426                 $this->getModule('api')->create(array('bvfs', 'restore'), $cmdProps);
427                 $restoreProps = array();
428                 $restoreProps['rpath'] = $path;
429                 $restoreProps['clientid'] = intval($this->RestoreClient->SelectedValue);
430                 $restoreProps['fileset'] = $this->GroupBackupFileSet->SelectedValue;
431                 $restoreProps['priority'] = intval($this->RestoreJobPriority->Text);
432                 $restoreProps['where'] =  $this->RestorePath->Text;
433                 $restoreProps['replace'] = $this->ReplaceFiles->SelectedValue;
434                 
435                 $ret = $this->getModule('api')->create(array('jobs', 'restore'), $restoreProps);
436                 $jobid = $this->getModule('misc')->findJobIdStartedJob($ret->output);
437                 $urlParams = array('open' => 'Job');
438                 if (is_numeric($jobid)) {
439                         $urlParams['id'] = $jobid;
440                 }
441                 $this->goToDefaultPage($urlParams);
442         }
443 }
444 ?>