YaWK  24.1
Yet another WebKit
backup.php
Go to the documentation of this file.
1 <?php
2 namespace YAWK\BACKUP
3 {
4 
5  use YAWK\db;
6 
7  /**
8  * @details <b>Backup Class</b>
9  * <p>Methods to backup and restore complete or partial project data including:
10  * pages folder, media folder, system folder and database. The Backup can be
11  * stored and overwritten in current Folder. Otherwise it is possible to archive
12  * any backup. To do this, you can create a new folder to store the backup within.</p>
13  *
14  * @package YAWK
15  * @author Daniel Retzl <[email protected]>
16  * @copyright 2018 Daniel Retzl
17  * @license https://opensource.org/licenses/MIT
18  * @version 1.0.0
19  * @brief Backup Main Class
20  */
21  class backup
22  {
23  /** @param object mysql backup object */
24  public $mysqlBackup;
25  /** @param object files backup object */
26  public $fileBackup;
27  /** @param string path, where the backup will be stored */
28  public $targetFolder = '../system/backup/current/';
29  /** @param string source folder to backup */
30  public $sourceFolder = '';
31  /** @param string current backup folder path */
32  public $currentBackupFolder = '../system/backup/current/';
33  /** @param array files in current backup folder */
34  public $currentBackupFiles = array();
35  /** @param string archive backup folder path */
36  public $archiveBackupFolder = '../system/backup/archive/';
37  /** @param array all sub folders in archiveBackupFolder */
38  public $archiveBackupSubFolders = array();
39  /** @param string archive working subfolder */
40  public $archiveBackupSubFolder = '';
41  /** @param array files in archive backup folder */
42  public $archiveBackupFiles = array();
43  /** @param string archive backup file */
44  public $archiveBackupFile = '';
45  /** @param string new archive file */
46  public $archiveBackupNewFile = '';
47  /** @param string upload folder */
48  public $downloadFolder = '../system/backup/download/';
49  /** @param string tmp folder */
50  public $tmpFolder = '../system/backup/tmp/';
51  /** @param string files|database|complete */
52  public $backupMethod = "database";
53  /** @param string filename of the config file (default: backup.ini) */
54  public $configFilename = "backup.ini";
55  /** @param string config file, including path */
56  public $configFile = '';
57  /** @param array backup settings */
58  public $backupSettings = array();
59  /** @param string overwrite backup files? */
60  public $overwriteBackup = "true";
61  /** @param string zip backup if possible */
62  public $zipBackup = "true";
63  /** @param string remove files after zip is complete */
64  public $removeAfterZip = "true";
65  /** @param string should .sql backup be stored in tmp folder? */
66  public $storeSqlTmp = "false";
67  /** @param string restore file (zip file) */
68  public $restoreFile = '';
69  /** @param array restorable files (files from tmp folder) */
70  public $restoreFiles = array();
71  /** @param array restore folders (content, media, system) */
72  public $restoreFolders = array();
73  /** @param string restore from folder */
74  public $restoreFolder = '';
75  /** @param string restore mode (database, mediafolder, complete, custom) */
76  public $restoreMode = '';
77  /** @param array holds information about the restore process states */
78  public $restoreStatus = array();
79 
80 
81  /**
82  * @brief backup constructor. prepare temp folder on class instantiation
83  * @param $db
84  */
85  public function __construct($db)
86  { // prepare temp folder on class instantiation
87  // check and create required folders
88  $requiredFolders = array($this->tmpFolder, $this->currentBackupFolder, $this->archiveBackupFolder);
89 
90  foreach ($requiredFolders as $folder)
91  {
92  // if tmp folder does not exist
93  if (!is_dir($folder))
94  { // create tmp folder
95  if (!mkdir($folder))
96  { // unable to create tmp folder
97  \YAWK\sys::setSyslog($db, 52, 2, "failed to create " . $folder . "", 0, 0, 0, 0);
98  // return false;
99  }
100  else
101  { // tmp folder created - try to set owner + group writeable
102  if (chmod($folder, 0775))
103  { // ok...
104  // return true;
105  }
106  else
107  { // unable to set folder properties
108  \YAWK\sys::setSyslog($db, 52, 2, "failed to set permissions of folder " . $folder . "", 0, 0, 0, 0);
109  // return false;
110  }
111  }
112  }
113  }
114  }
115 
116  /**
117  * @brief Init Backup Class (run backup)
118  * @param object $db database object
119  * @return bool true: backup init success | false: backup init failed
120  */
121  public function init($db)
122  {
123  // run backup system
124  if ($this->run($db) === true)
125  { // init successful
126  return true;
127  }
128  else
129  { // backup init failed
130  return false;
131  }
132  }
133 
134  /**
135  * @brief Run a new backup, depending on chosen backup method
136  * @param object $db database object
137  * @return bool true: backup successful | false: backup failed
138  */
139  public function run($db)
140  { /** @param $db db */
141  // check if backup method is set
142  if (isset($this->backupMethod) && (!empty($this->backupMethod)))
143  { // which backup method should be executed?
144  switch ($this->backupMethod)
145  {
146  // do a complete backup
147  case "complete":
148  {
149  $this->storeSqlTmp = "true";
150 
151  // run database backup
152  if ($this->runDatabaseBackup($db, $this->storeSqlTmp) === true)
153  { // db backup was successful
154  // return true;
155  }
156  else
157  { // failed to run db backup
158  // set syslog entry: db backup could not be made
159  }
160 
161  // run backup of complete system (including database)
162  if ($this->runFileBackup($db) === true)
163  { // success
164  return true;
165  }
166  else
167  { // media folder backup failed
168  return false;
169  }
170  }
171  break;
172 
173  // database only
174  case "database":
175  {
176  $this->storeSqlTmp = "false";
177  // run database backup
178  if ($this->runDatabaseBackup($db, $this->storeSqlTmp) === true)
179  { // db backup was successful
180  return true;
181  }
182  else
183  { // failed to run db backup
184  return false;
185  }
186  }
187  break;
188 
189  // media folder only
190  case "mediaFolder":
191  { // run backup of media folder
192  if ($this->runFileBackup($db) === true)
193  { // success
194  return true;
195  }
196  else
197  { // media folder backup failed
198  return false;
199  }
200  }
201  break;
202 
203  // custom backup selected
204  case "custom":
205  {
206  // store .sql file in tmp folder (because we're doing a file package)
207  $this->storeSqlTmp = "true";
208 
209  // check if database backup is requested by form
210  if (isset($_POST['database']) && (!empty($_POST['database'])))
211  {
212  // run database backup
213  if ($this->runDatabaseBackup($db, $this->storeSqlTmp) === true)
214  {
215  // db backup successful
216  }
217  else
218  { // db backup FAILED
219  // return false;
220  }
221  }
222 
223  // run backup of custom folder
224  if($this->runFileBackup($db) === true)
225  { // success
226  return true;
227  }
228  else
229  { // custom folder backup failed
230  return false;
231  }
232  }
233  break;
234  }
235  // unknown backup method -
236  return false;
237  }
238  else
239  {
240  // what if no backup method is set?
241  // add default behavior
242  return false;
243  }
244  }
245 
246  /**
247  * @brief Set backup information file (backup.ini)
248  * @param object $db database handle
249  * @return bool
250  * @details will be added to every .zip file to identify what to do during restore process
251  * @version 1.0.0
252  * @link http://yawk.io
253  * @author Daniel Retzl <[email protected]>
254  */
255  public function setIniFile(object $db): bool
256  { // check if target folder is set
257 
258  // check if target folder is writeable
259  if (is_writeable($this->targetFolder))
260  { // set configfile (string that includes path + filename)
261  $this->configFile = $this->targetFolder.$this->configFilename;
262 
263  if (isset($this->storeSqlTmp) && ($this->storeSqlTmp == "true"))
264  {
265  if (!is_dir($this->tmpFolder."database"))
266  {
267  mkdir($this->tmpFolder."database");
268  }
269  $this->configFile = $this->tmpFolder."database/".$this->configFilename;
270  }
271 
272  // check if ini file was written
273  if (\YAWK\sys::writeIniFile($this->backupSettings, $this->configFile) === true)
274  {
275  // check if config file is there
276  if (is_file($this->configFile))
277  { // config file found!
278  return true;
279  }
280  else
281  { // config file not found
282  \YAWK\sys::setSyslog($db, 51, 1, "backup ini file written, but not found - please check: $this->configFile", 0, 0, 0, 0);
283  return false;
284  }
285  }
286  else
287  { // unable to write config file
288  \YAWK\sys::setSyslog($db, 52, 2, "failed to write backup config file $this->configFile", 0, 0, 0, 0);
289  return false;
290  }
291  }
292  else
293  { // target folder not writeable
294  \YAWK\sys::setSyslog($db, 51, 1, "failed to write backup config file: $this->configFile - target folder not writeable", 0, 0, 0, 0);
295  return false;
296  }
297  }
298 
299  /**
300  * @brief Parse backup ini file
301  * @param $db
302  * @param $iniFile
303  * @return array|false
304  */
305  public function parseIniFile($db, $iniFile)
306  { // set config file property
307  $this->configFile = $iniFile;
308  // check if ini file is there
309  if (is_file($this->configFile))
310  {
311  // update backup settings from ini file
312  $this->backupSettings = parse_ini_file($this->configFile);
313  // check backup settings array is set
314  if (is_array($this->backupSettings))
315  { // array is set, return backup settings
316  return $this->backupSettings;
317  }
318  else
319  { // failed parse ini file: but array is not set
320  \YAWK\sys::setSyslog($db, 52, 1, "failed to parse ini file: $this->configFile is there, but backupSettings array is not set", 0, 0, 0, 0);
321  return false;
322  }
323  }
324  else
325  { // no ini file found!
326  // set syslog entry
327  \YAWK\sys::setSyslog($db, 51, 1, "failed to parse ini file: $this->configFile not found", 0, 0, 0, 0);
328  return false;
329  }
330  }
331 
332  /**
333  * @brief get all files from current backup folder into array
334  * @return array|false
335  */
336  public function getCurrentBackupFilesArray()
337  {
338  // get current backup files into array
339  $this->currentBackupFiles = \YAWK\filemanager::getFilesFromFolderToArray($this->currentBackupFolder);
340  // check if backup files are set
341  if (is_array($this->currentBackupFiles))
342  { // ok, return files
344  }
345  else
346  { // array is not set
347  return false;
348  }
349  }
350 
351  /**
352  * @brief get all files from archive backup folder into array
353  * @return array|false
354  */
355  public function getArchiveBackupFilesArray()
356  {
357  // get current backup files into array
358  $this->archiveBackupFiles = \YAWK\filemanager::getFilesFromFolderToArray($this->archiveBackupSubFolder);
359  // check if backup files are set
360  if (is_array($this->archiveBackupFiles))
361  { // ok, return files
363  }
364  else
365  { // array is not set
366  return false;
367  }
368  }
369 
370  /**
371  * @brief Include mysql backup class and run mysqldump backup
372  * @return bool
373  */
374  public function runDatabaseBackup($db, $storeSqlTmp)
375  {
376  if (isset($storeSqlTmp) && (!empty($storeSqlTmp)))
377  {
378  $this->storeSqlTmp = $storeSqlTmp;
379  }
380  // include backup-database class
381  require_once 'backup-mysqlBackup.php';
382  // create new database backup object
383  $this->mysqlBackup = new \YAWK\BACKUP\DATABASE\mysqlBackup($this->backupSettings);
384 
385  // initialize database backup (this will run mysqldump-php)
386  if ($this->mysqlBackup->initMysqlBackup($db, $this->overwriteBackup, $this->zipBackup, $this->storeSqlTmp) === true)
387  { // database backup successful
388  return true;
389  }
390  else
391  { // database backup failed
392  return false;
393  }
394  }
395 
396 
397  /**
398  * @brief Run File Backup from $sourceFolder
399  * @return bool
400  */
401  public function runFileBackup($db)
402  {
403  // include fileBackup class
404  require_once 'backup-fileBackup.php';
405  // create new file backup object
406  $this->fileBackup = new \YAWK\BACKUP\FILES\fileBackup($db);
407 
408  // initialize database backup (this will run mysqldump-php)
409  if ($this->fileBackup->initFolderBackup($db, $this->overwriteBackup, $this->zipBackup) === true)
410  { // file backup successful
411  return true;
412  }
413  else
414  { // file backup failed
415  return false;
416  }
417  }
418 
419 
420  /**
421  * @brief Check if ZipArchive function exists
422  * @return bool
423  */
424  public function checkZipFunction()
425  {
426  // check if zip extension is loaded
427  if (extension_loaded('zip'))
428  { // ok...
429  return true;
430  }
431  else
432  { // zip extension is not loaded
433  return false;
434  }
435  }
436 
437  /**
438  * @brief Zip a whole folder from $source to $destination.zip
439  * @return bool
440  */
441  function zipFolder($db, $source, $destination)
442  {
443  // check if zip extension is available
444  if ($this->checkZipFunction() === false)
445  { // if not
446  return false;
447  }
448 
449  // make sure $source file/folder exists
450  if (!file_exists($source))
451  { // if not
452  return false;
453  }
454 
455  // create new zip object
456  $zip = new \ZipArchive();
457 
458  // make sure to create and open new zip archive
459  if (!$zip->open($destination, \ZIPARCHIVE::CREATE))
460  { // if not
461  return false;
462  }
463 
464  // set path slashes correctly
465  $source = str_replace('\\', '/', realpath($source));
466 
467  // check if $source is a directoy
468  if (is_dir($source) === true)
469  {
470  // run recusrive iterators to store files in array
471  $elements = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source), \RecursiveIteratorIterator::SELF_FIRST);
472 
473  // walk through folder
474  foreach ($elements as $file)
475  {
476  // set path slashes correctly
477  $file = str_replace('\\', '/', $file);
478 
479  // ignore dot folders (. and ..)
480  if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
481  continue;
482 
483  // set file including path
484  $file = realpath($file);
485 
486  // check if current element is a directory
487  if (is_dir($file) === true)
488  { // add folder to zip file
489  $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
490  }
491  // check if current element is a file
492  else if (is_file($file) === true)
493  { // add file to zip archive
494  $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
495  }
496  }
497  }
498  // if $source is a file
499  else if (is_file($source) === true)
500  { // add file to zip archive
501  $zip->addFromString(basename($source), file_get_contents($source));
502  }
503 
504  // all done, close (and write) zip archive
505  $zip->close();
506 
507  // check if .zip file is there
508  if (is_file($destination))
509  {
510  // INSTANT-DOWNLOAD WORKAROUND -
511  // to improve usability, the file will be served as direct downloaded.
512  // this piece of JS code changes the link (from generating .zip to download/zipfile.zip)
513  // due this method its not needed to send location headers (which is not possible at this stage)
514 
515  // this 'hack' should work in most browsers, but may not work in some. (eg: untested in safari)
516 
517  // check if archive ID is set
518  if (isset($_GET['archiveID']) && (!empty($_GET['archiveID'])))
519  { // set var for JS: downloadArchiveLink (selector)
520  $downloadArchiveLink = "#archive-".$_GET['archiveID'];
521  // set var for JS: link to the file to download
522  $downloadFile = $this->downloadFolder.$_GET['folder'].".zip";
523  // dirty lil piece of JS code to emulate the user's click
524  // (this avoids that he have to click twice to 1)generate + 2)download)
525  echo "
526  <script type='text/javascript'>
527  $(document).ready(function()
528  { // change href attribute for this archive to direct donwload file
529  $('$downloadArchiveLink').attr('href', '$downloadFile')
530  // emulate a users click to force direct download
531  $('$downloadArchiveLink')[0].click();
532  // if this is not working, the user have to click on that link.
533  });
534  </script>";
535  }
536  // ZIP file created, force download js fired.
537  return true;
538  }
539  else
540  { // failed to create download archive
541  \YAWK\sys::setSyslog($db, 52, 3, "failed to create download archive: $destination", 0, 0, 0, 0);
542  return false;
543  }
544  }
545 
546  /**
547  * @brief Manage how a backup will be restored from backup folder
548  * @param $db
549  * @param $file
550  * @param $folder
551  * @return array|false
552  */
553  public function restore($db, $file, $folder)
554  {
555  if (isset($file) && (!empty($file)
556  && (isset($folder) && (!empty($folder)))))
557  {
558  // set restore file property
559  $this->restoreFile = $file;
560  $this->restoreFolder = $folder;
561 
562  // check which backup should be made
563  if (is_writeable($this->tmpFolder))
564  {
565  $source = $this->restoreFolder.$this->restoreFile;
566  $target = $this->tmpFolder.$this->restoreFile;
567 
568  // copy file to tmp folder
569  copy($source, $target);
570 
571  // check if backup file was copied...
572  if (is_file($target))
573  { // file exists...
574  if ($this->checkZipFunction() === true)
575  { // ok, create new zip object
576  $zip = new \ZipArchive;
577  // open zip archive
578  $res = $zip->open($target);
579  // if zip open was successful
580  if ($res === TRUE)
581  { // extract zip file
582  $zip->extractTo($this->tmpFolder);
583  // close zip file
584  $zip->close();
585  // zip extraction successful
586 
587  // check if backup.ini file is there...
588  if (is_file($this->tmpFolder.$this->configFilename))
589  {
590  // ok, backup.ini found, parse data from file into array
591  $this->backupSettings = $this->parseIniFile($db, $this->tmpFolder.$this->configFilename);
592 
593  // check if backup settings array is set and not empty
594  if (is_array($this->backupSettings) && (!empty($this->backupSettings)))
595  {
596  // PROCESS RESTORE METHODS
597  switch ($this->backupSettings['METHOD'])
598  {
599  // COMPLETE PROCESSING
600  case "complete":
601  {
602  // set folders for complete restore
603  $this->restoreFolders = \YAWK\filemanager::getSubfoldersToArray($this->tmpFolder);
604  $this->restoreStatus = $this->doRestore($db, $this->restoreFolders);
605  {
606  return $this->restoreStatus;
607  }
608  }
609  break;
610 
611  case "database":
612  { // restore database
613  $this->restoreFolders = array('database');
614  $this->restoreStatus = $this->doRestore($db, $this->restoreFolders);
615  {
616  return $this->restoreStatus;
617  }
618  }
619  break;
620 
621  case "mediaFolder":
622  { // set media folder restore
623  // $this->restoreFolders = \YAWK\filemanager::getSubfoldersToArray($this->tmpFolder);
624  $this->restoreFolders = array('media/');
625  $this->restoreStatus = $this->doRestore($db, $this->restoreFolders);
626  {
627  return $this->restoreStatus;
628  }
629  }
630  break;
631 
632  case "custom":
633  { // get custom restore folders
634  $this->restoreFolders = \YAWK\filemanager::getSubfoldersToArray($this->tmpFolder);
635  $this->restoreStatus = $this->doRestore($db, $this->restoreFolders);
636  {
637  return $this->restoreStatus;
638  }
639  }
640  break;
641  }
642 // return true;
643  }
644  else
645  {
646  // backup settings not set or empty
647  \YAWK\sys::setSyslog($db, 52, 1, "failed to restore backup: restore settings array is not set", 0, 0, 0, 0);
648  return false;
649  }
650  }
651  else
652  {
653  // backup.ini file not found - abort
654  \YAWK\sys::setSyslog($db, 52, 1, "failed to restore backup: ini file not found - $this->tmpFolder.$this->configFilename", 0, 0, 0, 0);
655  return false;
656  }
657  }
658  else
659  { // unable to open zip file
660  \YAWK\sys::setSyslog($db, 52, 1, "failed to restore: unable to open ZIP file", 0, 0, 0, 0);
661  return false;
662  }
663  }
664  else
665  { // zip extension not loaded
666  \YAWK\sys::setSyslog($db, 52, 1, "failed to restore: unable to unzip backup package - ZIP extension not loaded.", 0, 0, 0, 0);
667  return false;
668  }
669  }
670  else
671  { // target file not found - no backup file copied to tmp folder
672  \YAWK\sys::setSyslog($db, 52, 1, "failed to copy backup package: $source not copied to $target", 0, 0, 0, 0);
673  return false;
674  }
675  }
676  else
677  {
678  // tmp folder is not writeable
679  \YAWK\sys::setSyslog($db, 52, 1, "failed to restore backup: tmp folder ($this->tmpFolder) is not writeable", 0, 0, 0, 0);
680  return false;
681  }
682  }
683  else
684  { // no file set
685  \YAWK\sys::setSyslog($db, 52, 1, "failed to restore backup: file not set", 0, 0, 0, 0);
686  return false;
687  }
688  }
689 
690  /**
691  * @brief Restore Data physically to folder, restore .sql file to database if needed.
692  * @param $db
693  * @param $restoreFolders
694  * @return array
695  */
696  public function doRestore($db, $restoreFolders)
697  {
698  /** @param db $db */
699  // check if restore folders are set
700  if (isset($restoreFolders) && (!empty($restoreFolders)))
701  { // restore folders not set or empty
702  $this->restoreFolders = $restoreFolders;
703  }
704 
705  // restore each required folder
706  foreach ($this->restoreFolders as $folder)
707  {
708  // check if content, database, media and system folder exists...
709  if (is_dir(dirname($this->tmpFolder.$folder)))
710  {
711  // copy all folders except database
712  if ($folder !== "database")
713  {
714  // restore folder
715  if (\YAWK\sys::xcopy($this->tmpFolder . $folder, "../$folder") === true)
716  {
717  $this->restoreStatus[][$folder]['success'] = "true";
718  }
719  else
720  {
721  // failed to restore folder
722  $this->restoreStatus[][$folder]['success'] = "false";
723  $this->restoreStatus[][$folder]['error'] = "failed to copy " . $this->tmpFolder . "$folder check permissions of ../$folder";
724  }
725  }
726 
727  // IF DATABASE RESTORE IS REQUESTED
728  else
729  {
730 
731  if (is_file($this->tmpFolder."database-backup.sql_error"))
732  {
733  unlink($this->tmpFolder."database-backup.sql_error");
734  }
735 
736  if (is_file($this->tmpFolder."database-backup.sql_filepointer"))
737  {
738  unlink($this->tmpFolder."database-backup.sql_filepointer");
739  }
740 
741 
742  // check if database file is in tmp/
743  if (file_exists($this->tmpFolder."database-backup.sql"))
744  {
745  // check if backup.ini exists in tmp/database folder
746  if (is_file($this->tmpFolder.$this->configFilename))
747  {
748  // ok, database folder found, parse data from database/folder
749  $this->backupSettings = $this->parseIniFile($db, $this->tmpFolder.$this->configFilename);
750  // get array with all tables that should be updated
751  $activeTables = explode(',', $this->backupSettings['TABLES']);
752  // delete not needed last item of array
753  array_pop($activeTables);
754  // drop all tables that should be updated
755  $db->dropTables($activeTables);
756  }
757 
758  if ($db->import($this->tmpFolder."database-backup.sql", '') === true)
759  {
760  $this->restoreStatus[]['database']['success'] = "true";
761  //return $this->restoreStatus;
762  }
763  else
764  {
765  $this->restoreStatus[]['database']['success'] = "true";
766  $this->restoreStatus[]['database']['error'] = "failed to restore database backup.";
767  //return $this->restoreStatus;
768  }
769  }
770  // check if database dir exists: tmp/database
771  else if (is_dir(dirname($this->tmpFolder."database/")))
772  {
773  // check if backup.ini exists in tmp/database folder
774  if (is_file($this->tmpFolder."database/".$this->configFilename))
775  {
776  // ok, database folder found, parse data from database/folder
777  $this->backupSettings = $this->parseIniFile($db, $this->tmpFolder."database/".$this->configFilename);
778  // get array with all tables that should be updated
779  $activeTables = explode(',', $this->backupSettings['TABLES']);
780  // delete not needed last item of array
781  array_pop($activeTables);
782  // drop all tables that should be updated
783  $db->dropTables($activeTables);
784  }
785 
786  // check if database file exists in tmp/database
787  if (file_exists($this->tmpFolder."database/database-backup.sql"))
788  {
789  if ($db->import($this->tmpFolder."database/database-backup.sql", '') === true)
790  {
791  $this->restoreStatus[]['database']['success'] = "true";
792  //return $this->restoreStatus;
793  }
794  else
795  {
796  $this->restoreStatus[]['database']['success'] = "true";
797  $this->restoreStatus[]['database']['error'] = "failed to restore database backup.";
798  //return $this->restoreStatus;
799  }
800  }
801  }
802 
803  }
804  }
805  else
806  { // failed to restore - folder does not exist or not writeable
807  $this->restoreStatus[][$folder]['error'] = "failed to restore ../$folder : folder is not there or not writeable";
808  }
809  }
810 
811  // restore fin - delete tmp folder
812  \YAWK\sys::recurseRmdir($this->tmpFolder);
813  // and return restore status
814  return $this->restoreStatus;
815  }
816 
817  /**
818  * @brief check restore folders, check + set permissions of restore folders
819  * @param $restoreFolders
820  * @return bool
821  */
822  public function checkFolders($restoreFolders)
823  {
824  if (!isset($restoreFolders) || (empty($restoreFolders)))
825  {
826  return false;
827  }
828  // set folders to process
829  // $restoreFolders = array('../content/', '../media/', '../system/fonts/', '../system/widgets/');
830  // set filemode
831  $filemode = 0755;
832 
833  // walk through folders
834  foreach ($restoreFolders as $folder)
835  { // check if permissions are high enough
836  if ($this->checkPermissions($folder) !== 0775
837  || ($this->checkPermissions($folder) !== 0777))
838  {
839  $folder = "../".$folder;
840  // if not:
841  // iterate folder recursive
842  $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folder));
843  // walk through items...
844  foreach($iterator as $item)
845  { // try to set folder permissions
846  if ($this->setPermissions($item, $filemode) === false)
847  { // unable to set permissions
848  return false;
849  }
850  }
851  }
852  }
853  return true;
854  }
855 
856  /**
857  * @brief set folder permissions and do some chmod stuff to with given $filemode to $folder
858  * @param $folder
859  * @param $filemode
860  * @return bool
861  */
862  public function setPermissions($folder, $filemode): bool
863  { // check if filemode is set
864  if (!isset($filemode) || (empty($filemode)))
865  { // nope -
866  return false;
867  }
868 
869  // check if folder is set, not empty and correct type
870  if (isset($folder) && (!empty($folder) && (is_string($folder))))
871  {
872  // set path
873  $folder = "../".$folder;
874 
875  // check if folder exists...
876  if (is_dir(dirname($folder)))
877  {
878  // try to set folder to writeable for owner + group
879  if (chmod($folder, $filemode))
880  {
881  return true;
882  }
883  else
884  { // failed to chmod
885  // PERMISSION PROBLEM - user have to edit chmod settings via FTP manually
886  return false;
887  }
888  }
889  else
890  { // directory not exists
891  return false;
892  }
893  }
894  else
895  { // folder not set, empty or wrong type
896  return false;
897  }
898  }
899 
900 
901  /**
902  * @brief check folder permissions and return permissions as string (eg 0755)
903  * @param $folder
904  * @return false|string|null
905  */
906  public function checkPermissions($folder)
907  {
908  // check if folder is set, not empty and correct type
909  if (isset($folder) && (!empty($folder) && (is_string($folder))))
910  {
911  // set path
912  $folder = "../".$folder;
913  // check if folder exists...
914  if (is_dir(dirname($folder)))
915  { // return permissions as string eg '0755'
916  return substr(sprintf('%o', fileperms($folder)), -4);
917  }
918  else
919  { // folder does not exist
920  return null;
921  }
922  }
923  else
924  { // folder not set, empty or wrong type
925  return null;
926  }
927  }
928  }
929 }
$folder
Definition: actions.php:9
if(!isset($language)||(!isset($lang))) $item
run($db)
Run a new backup, depending on chosen backup method.
Definition: backup.php:138
doRestore($db, $restoreFolders)
Restore Data physically to folder, restore .sql file to database if needed.
Definition: backup.php:695
checkFolders($restoreFolders)
check restore folders, check + set permissions of restore folders
Definition: backup.php:821
runFileBackup($db)
Run File Backup from $sourceFolder.
Definition: backup.php:400
setPermissions($folder, $filemode)
set folder permissions and do some chmod stuff to with given $filemode to $folder
Definition: backup.php:861
checkPermissions($folder)
check folder permissions and return permissions as string (eg 0755)
Definition: backup.php:905
__construct($db)
backup constructor. prepare temp folder on class instantiation
Definition: backup.php:84
setIniFile(object $db)
Set backup information file (backup.ini)
Definition: backup.php:254
getArchiveBackupFilesArray()
get all files from archive backup folder into array
Definition: backup.php:354
runDatabaseBackup($db, $storeSqlTmp)
Include mysql backup class and run mysqldump backup.
Definition: backup.php:373
init($db)
Init Backup Class (run backup)
Definition: backup.php:120
checkZipFunction()
Check if ZipArchive function exists.
Definition: backup.php:423
getCurrentBackupFilesArray()
get all files from current backup folder into array
Definition: backup.php:335
parseIniFile($db, $iniFile)
Parse backup ini file.
Definition: backup.php:304
zipFolder($db, $source, $destination)
Zip a whole folder from $source to $destination.zip.
Definition: backup.php:440
restore($db, $file, $folder)
Manage how a backup will be restored from backup folder.
Definition: backup.php:552
Mysqli database class; returns db connection object.
Definition: db.php:16
static getFilesFromFolderToArray($folder)
returns an array containing only files from folder (no subfolders)
static getSubfoldersToArray($folder)
returns an array containing only files from folder (no subfolders)
static xcopy($source, $dest, $permissions=0755)
Copy a file, or recursively copy a folder and its contents.
Definition: sys.php:473
static recurseRmdir($dir)
remove a directory recurse
Definition: sys.php:1127
static writeIniFile($array, $file)
write ini file
Definition: sys.php:2085
This class serves methods to create backup from files.
Definition: AdminLTE.php:2
print $_GET['id']
Definition: page-edit.php:357
$backup archiveBackupFiles