* @version $Id$ * @access public * @license http://opensource.org/licenses/gpl-3.0.html */ // we check if the given token is correct // else we quit if(!isset($_GET['token']) || $_GET['token'] != SECRET_KEY) die('Invalid token!'); $files = [SITE_PATH. 'config/config.ini', SITE_PATH. 'config/release.ini', SITE_PATH. 'config/.curver']; $config_file = SITE_PATH. 'config/config.ini'; $target = __DIR__ . '/backups/'; $name = date('Y-m-d').'_'.md5(uniqid(rand(), true)); $dest = $target.$name; // we retrieve info from INI file $ini = parse_ini_file($config_file); $current_theme = THEME_PUBLIC; $dbhost = DB_HOST; $dbuser = DB_USER; $dbpass = DB_PASS; $dbname = DB_NAME; // when called from CRONJOB // test if $sql_object exists and $_GET['libraryBackup'] not passed as parameter if(isset($sql_object) && !isset($_GET['libraryBackup'])) { $plug = new plugin(getCurrentPluginFolder(__FILE__)); $options = $plug->retrieveValues($sql_object); isset($options['backup-library']) && $options['backup-library'] == 1 ? $libraryBackup = 1 : $libraryBackup = 0; isset($options['backup-plugins']) && $options['backup-plugins'] == 1 ? $pluginsBackup = 1 : $pluginsBackup = 0; } else { // when generating backup from Back-office UI link $_GET['libraryBackup'] == 'true' ? $libraryBackup = 1 : $libraryBackup = 0; $_GET['pluginsBackup'] == 'true' ? $pluginsBackup = 1 : $pluginsBackup = 0; } // 0 - we create the destination folders mkdir($dest.'/config/cron/', 0755, true); mkdir($dest.'/'.THEME_DIRECTORY.'/public/', 0755, true); // mkdir($dest.'/newsletter/input/', 0755, true); // mkdir($dest.'/export/inc_report/', 0755, true); if($libraryBackup) mkdir($dest.'/library/userfiles/', 0755, true); if($pluginsBackup) mkdir($dest.'/plugins/', 0755, true); // 1- we copy files AND cron folders except for default cronjob // copy($config_file, $dest.'/config/config.ini'); foreach($files as $f) { copy($f, str_replace(SITE_PATH, $dest.'/', $f)); } recurse_copy(SITE_PATH.'config/cron', $dest.'/config/cron/'); @unlink($dest.'config/cron/1_default'); // 2.a - we copy public templates recurse_copy(SITE_PATH.THEME_DIRECTORY.'/public/'.$current_theme.'/', $dest.'/'.THEME_DIRECTORY.'/public/'.$current_theme.'/'); // 2.b - we copy newsletter templates // recurse_copy(SITE_PATH.'/newsletter/input/', $dest.'/newsletter/input/'); // 2.c - we copy export inc_report folder content // recurse_copy(SITE_PATH.'/export/inc_report/', $dest.'/export/inc_report/'); // 2.d - we copy general override folder if exists if(file_exists(SITE_PATH.THEME_DIRECTORY. '/override/')) recurse_copy(SITE_PATH.THEME_DIRECTORY. '/override/', $dest.'/'.THEME_DIRECTORY.'/override/'); // 2.e - we copy export inc_report folder content if($libraryBackup) recurse_copy(SITE_PATH.'/library/userfiles/', $dest.'/library/userfiles/'); // 2.f - we copy export inc_report folder content if($pluginsBackup) { foreach (glob(str_replace('../', SITE_PATH, "../plugins/l21_*/")) as $folderpath) { // do not copy l21_backupSuite folder if(strpos($folderpath,'l21_backupSuite') === false) recurse_copy($folderpath, $dest.'/plugins/'.basename($folderpath).'/'); } } // 3 - we dump the database system('mysqldump --host='.$dbhost.' --user="'.$dbuser.'" --password="'.$dbpass.'" '.$dbname.' > '.$dest.'/'.$dbname.'.sql' ); // 4 - we Zip everything // Zip($dest, $dest.'.zip'); // https://stackoverflow.com/questions/12424787/how-to-check-if-a-shell-command-exists-from-php // https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru // https://forum.ovh.com/showthread.php/53072-Compression-zip-dossier // we rely on zip system call to prevent memory issues from browsers if(command_exists('zsip')) { system('zip -r ' . $dest.'.zip ' . $dest); // syntax zip -r filename.zip foldername/ logfile(LOG_MAINFILE, array('[action] backup', 'method : zip - system shell call')); } else { OptimizedZip($dest, $dest.'.zip'); logfile(LOG_MAINFILE, array('[action] backup', 'method : OptimizedZip PHP function call')); } // ExtendedZip::zipTree($dest, $dest.'.zip', ZipArchive::CREATE); // 5 - we finally delete unzipped files SureRemoveDir($dest, true); if(isset($_GET['todo']) && $_GET['todo'] == 'generate') { $filename = $dest.'.zip'; // we download automatically the file header('Location: ../library/dl.php?file=plugins/'.$plug->getVar('name').'/backups/'.basename($filename)); } /************************************************************************ ************************************************************************/ /** * Checks if a command exist. Works for both Windows and Linux systems * @param mixed $command_name * @return bool * @ https://beamtic.com/if-command-exists-php */ function command_exists($command_name) { $test_method = (false === stripos(PHP_OS, 'win')) ? 'command -v' : 'where'; return (null === shell_exec("$test_method $command_name")) ? false : true; } function recurse_copy($src,$dst) { $dir = opendir($src); @mkdir($dst); while(false !== ( $file = readdir($dir)) ) { if (( $file != '.' ) && ( $file != '..' )) { if ( is_dir($src . '/' . $file) ) { recurse_copy($src . '/' . $file,$dst . '/' . $file); } else { copy($src . '/' . $file,$dst . '/' . $file); } } } closedir($dir); } // from https://stackoverflow.com/questions/4914750/how-to-zip-a-whole-folder-using-php function OptimizedZip($source, $destination) { // Get real path for our folder // $rootPath = realpath($source); // @simo, not sure we need to $rootPath = $source; // Initialize archive object $zip = new ZipArchive(); $zip->open($destination, ZipArchive::CREATE | ZipArchive::OVERWRITE); // Create recursive directory iterator /** @var SplFileInfo[] $files */ $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($rootPath), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($files as $name => $file) { // Skip directories (they would be added automatically) if (!$file->isDir()) { // Get real and relative path for current file $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($rootPath) + 1); // Add current file to archive $zip->addFile($filePath, $relativePath); } } // Zip archive will be created only after closing object $zip->close(); } function Zip($source, $destination) { if (!extension_loaded('zip') || !file_exists($source)) { return false; } $zip = new ZipArchive(); if (!$zip->open($destination, ZIPARCHIVE::CREATE)) { return false; } $source = str_replace('\\', '/', realpath($source)); if (is_dir($source) === true) { $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); foreach ($files as $file) { $file = str_replace('\\', '/', $file); // Ignore "." and ".." folders if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) ) continue; $file = realpath($file); if (is_dir($file) === true) { $zip->addEmptyDir(str_replace($source . '/', '', $file . '/')); } else if (is_file($file) === true) { $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file)); } } } else if (is_file($source) === true) { $zip->addFromString(basename($source), file_get_contents($source)); } return $zip->close(); } // https://stackoverflow.com/questions/1334613/how-to-recursively-zip-a-directory-in-php class ExtendedZip extends ZipArchive { // Member function to add a whole file system subtree to the archive public function addTree($dirname, $localname = '') { if ($localname) $this->addEmptyDir($localname); $this->_addTree($dirname, $localname); } // Internal function, to recurse protected function _addTree($dirname, $localname) { $dir = opendir($dirname); while ($filename = readdir($dir)) { // Discard . and .. if ($filename == '.' || $filename == '..') continue; // Proceed according to type $path = $dirname . '/' . $filename; $localpath = $localname ? ($localname . '/' . $filename) : $filename; if (is_dir($path)) { // Directory: add & recurse $this->addEmptyDir($localpath); $this->_addTree($path, $localpath); } else if (is_file($path)) { // File: just add $this->addFile($path, $localpath); } } closedir($dir); } // Helper function public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '') { $zip = new self(); $zip->open($zipFilename, $flags); $zip->addTree($dirname, $localname); $zip->close(); } } ?>