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