mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-22 07:53:39 +01:00
backup housekeeping feature from H.J.Tappe together with a feature to backup egroupware the files - tree from Christian Fueller; The File-backup feature is testet against relatively small eGroupware Instances; It requires ZipArchive (If you dont have that, the backup should run, but without backup of files); AND if you enable it backup takes a) more time to run and restore b) way more space, so you should enable housekeeping
This commit is contained in:
parent
b0ba5cbf50
commit
44a53ee05b
@ -34,7 +34,10 @@
|
||||
if ($f = $this->db_backup->fopen_backup())
|
||||
{
|
||||
$this->db_backup->backup($f);
|
||||
if(is_resource($f))
|
||||
fclose($f);
|
||||
/* Remove old backups. */
|
||||
$this->db_backup->housekeeping();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,10 @@ class db_backup
|
||||
* replaces backslashes, used in cvs_split
|
||||
*/
|
||||
const BACKSLASH_TOKEN = '##!!**bAcKsLaSh**!!##';
|
||||
/**
|
||||
* Configuration table.
|
||||
*/
|
||||
const TABLE = 'egw_config';
|
||||
/**
|
||||
* Reference to schema_proc
|
||||
*
|
||||
@ -47,6 +51,7 @@ class db_backup
|
||||
'egw_sessions','egw_app_sessions','phpgw_sessions','phpgw_app_sessions', // eGW's session-tables
|
||||
'phpgw_anglemail', // email's cache
|
||||
'egw_felamimail_cache','egw_felamimail_folderstatus','phpgw_felamimail_cache','phpgw_felamimail_folderstatus', // felamimail's cache
|
||||
'egw_phpfreechat', // as of the fieldnames of the table a restore would fail within egroupware, and chatcontent is of no particular intrest
|
||||
);
|
||||
/**
|
||||
* regular expression to identify system-tables => ignored for schema+backup
|
||||
@ -55,11 +60,29 @@ class db_backup
|
||||
*/
|
||||
var $system_tables = false;
|
||||
/**
|
||||
* regurar expression to identify eGW tables => if set only they are used
|
||||
* Regular expression to identify eGW tables => if set only they are used
|
||||
*
|
||||
* @var string|boolean
|
||||
*/
|
||||
var $egw_tables = false;
|
||||
/**
|
||||
* Backup directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $backup_dir;
|
||||
/**
|
||||
* Minimum number of backup files to keep. Zero for: Disable cleanup.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $backup_mincount;
|
||||
/**
|
||||
* Backup Files config value, will be overwritten by the availability of the ZibArchive libraries
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
var $backup_files = false ;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -93,6 +116,12 @@ class db_backup
|
||||
$this->db->next_record();
|
||||
$this->backup_dir = $this->db->f(0).'/db_backup';
|
||||
}
|
||||
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='files_dir'",__LINE__,__FILE__);
|
||||
$this->db->next_record();
|
||||
if (!($this->files_dir = $this->db->f(0)))
|
||||
{
|
||||
error_log(__METHOD__."->"."No files Directory set/found");
|
||||
}
|
||||
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='system_charset'",__LINE__,__FILE__);
|
||||
$this->db->next_record();
|
||||
$this->charset = $this->db->f(0);
|
||||
@ -104,6 +133,14 @@ class db_backup
|
||||
}
|
||||
$this->db->select($GLOBALS['egw_setup']->applications_table,'app_version',array('app_name'=>'phpgwapi'),__LINE__,__FILE__);
|
||||
$this->api_version = $this->db->next_record() ? $this->db->f(0) : false;
|
||||
/* Backup settings */
|
||||
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='backup_mincount'",__LINE__,__FILE__);
|
||||
$this->db->next_record();
|
||||
$this->backup_mincount = $this->db->f(0);
|
||||
// backup files too
|
||||
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='backup_files'",__LINE__,__FILE__);
|
||||
$this->db->next_record();
|
||||
$this->backup_files = (bool)$this->db->f(0);
|
||||
}
|
||||
if (!$this->charset) $this->charset = 'iso-8859-1';
|
||||
}
|
||||
@ -114,10 +151,23 @@ class db_backup
|
||||
{
|
||||
$this->backup_dir = $GLOBALS['egw_info']['server']['files_dir'].'/db_backup';
|
||||
}
|
||||
$this->files_dir = $GLOBALS['egw_info']['server']['files_dir'];
|
||||
$this->backup_mincount = $GLOBALS['egw_info']['server']['backup_mincount'];
|
||||
$this->backup_files = $GLOBALS['egw_info']['server']['backup_files'];
|
||||
$this->charset = $GLOBALS['egw']->translation->charset();
|
||||
|
||||
$this->api_version = $GLOBALS['egw_info']['apps']['phpgwapi']['version'];
|
||||
}
|
||||
// Set a default value if not set.
|
||||
if (!isset($this->backup_mincount))
|
||||
{
|
||||
$this->backup_mincount = 0; // Disabled if not set
|
||||
}
|
||||
if (!isset($this->backup_files))
|
||||
{
|
||||
$this->backup_files = false; // Disabled if not set
|
||||
}
|
||||
|
||||
if (!is_dir($this->backup_dir) && is_writable(dirname($this->backup_dir)))
|
||||
{
|
||||
mkdir($this->backup_dir);
|
||||
@ -137,34 +187,146 @@ class db_backup
|
||||
*
|
||||
* @param $name=false string/boolean filename to use, or false for the default one
|
||||
* @param $reading=false opening for reading ('rb') or writing ('wb')
|
||||
* @return string/resource error-msg of file-handle
|
||||
* @return string/resource/zip error-msg of file-handle
|
||||
*/
|
||||
function fopen_backup($name=false,$reading=false)
|
||||
{
|
||||
//echo "function fopen_backup($name,$reading)<br>"; // !
|
||||
if (!$name)
|
||||
{
|
||||
//echo '-> !$name<br>'; // !
|
||||
if (!$this->backup_dir || !is_writable($this->backup_dir))
|
||||
{
|
||||
//echo ' -> !$this->backup_dir || !is_writable($this->backup_dir)<br>'; // !
|
||||
return lang("backupdir '%1' is not writeable by the webserver",$this->backup_dir);
|
||||
}
|
||||
$name = $this->backup_dir.'/db_backup-'.date('YmdHi');
|
||||
}
|
||||
else // remove the extension, to use the correct wrapper based on the extension
|
||||
{
|
||||
//echo '-> else<br>'; // !
|
||||
$name = preg_replace('/\.(bz2|gz)$/i','',$name);
|
||||
}
|
||||
$mode = $reading ? 'rb' : 'wb';
|
||||
|
||||
if (!($f = @fopen($file = "compress.bzip2://$name.bz2",$mode)) &&
|
||||
!($f = @fopen($file = "compress.zlib://$name.gz",$mode)) &&
|
||||
!($f = @fopen($file = "zlib:$name.gz",$mode)) && // php < 4.3
|
||||
!($f = @fopen($file = $name,$mode)))
|
||||
list( , $type) = explode('.', basename($name));
|
||||
if($type == 'zip' && $reading && $this->backup_files)
|
||||
{
|
||||
$lang_mode = $reading ? lang('reading') : lang('writing');
|
||||
return lang("Cant open '%1' for %2",$name,$lang_mode);
|
||||
//echo '-> $type == "zip" && $reading<br>'; // !
|
||||
if(!class_exists('ZipArchive', false))
|
||||
{
|
||||
$this->backup_files = false;
|
||||
//echo ' -> (new ZipArchive) == NULL<br>'; // !
|
||||
return lang("Cant open $name, needs ZipArchive")."<br>";
|
||||
}
|
||||
if(!($f = fopen($name, $mode)))
|
||||
{
|
||||
//echo ' -> !($f = fopen($name, $mode))<br>'; // !
|
||||
$lang_mode = $reading ? lang("reading") : lang("writing");
|
||||
return lang("Cant open '%1' for %2", $name, $lang_mode)."<br>";
|
||||
}
|
||||
return $f;
|
||||
}
|
||||
if(class_exists('ZipArchive', false) && !$reading && $this->backup_files)
|
||||
{
|
||||
//echo '-> (new ZipArchive) != NULL && !$reading; '.$name.'<br>'; // !
|
||||
if(!($f = fopen($name, $mode)))
|
||||
{
|
||||
//echo ' -> !($f = fopen($name, $mode))<br>'; // !
|
||||
$lang_mode = $reading ? lang("reading") : lang("writing");
|
||||
return lang("Cant open '%1' for %2", $name, $lang_mode)."<br>";
|
||||
}
|
||||
return $f;
|
||||
}
|
||||
if(!($f = fopen("compress.bzip2://$name.bz2", $mode)))
|
||||
{
|
||||
//echo '-> !($f = fopen("compress.bzip2://$name.bz2", $mode))<br>'; // !
|
||||
$lang_mode = $reading ? lang("reading") : lang("writing");
|
||||
return lang("Cant open '%1' for %2", $name, $lang_mode)."<br>";
|
||||
}
|
||||
return $f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove old backups, leaving at least
|
||||
* backup_mincount backup files in place. Only backup files with
|
||||
* the regular name scheme are taken into account.
|
||||
*
|
||||
* @param files_return Fills a given array of file names to display (if given).
|
||||
*/
|
||||
function housekeeping(&$files_return = false)
|
||||
{
|
||||
/* Stop housekeeping in case it is disabled. */
|
||||
if ($this->backup_mincount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* Search the backup directory for matching files. */
|
||||
$handle = @opendir($this->backup_dir);
|
||||
$files = array();
|
||||
while($handle && ($file = readdir($handle)))
|
||||
{
|
||||
/* Filter for only the files with the regular name (un-renamed).
|
||||
* Leave special backup files (renamed) in place.
|
||||
* Note that this also excludes "." and "..".
|
||||
*/
|
||||
if (preg_match("/^db_backup-[0-9]{12}(\.bz2|\.gz|\.zip|)$/",$file))
|
||||
{
|
||||
$files[filectime($this->backup_dir.'/'.$file)] = $file;
|
||||
}
|
||||
}
|
||||
if ($handle) closedir($handle);
|
||||
|
||||
/* Sort the files by ctime. */
|
||||
krsort($files);
|
||||
$count = 0;
|
||||
foreach($files as $ctime => $file)
|
||||
{
|
||||
if ($count >= $this->backup_mincount)//
|
||||
{
|
||||
$ret = unlink($this->backup_dir.'/'.$file);
|
||||
if (($ret) && (is_array($files_return)))
|
||||
{
|
||||
array_push($files_return, $file);
|
||||
}
|
||||
}
|
||||
$count ++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the housekeeping configuration in the database and update the local variables.
|
||||
*
|
||||
* @param mincount Minimum number of backups to keep.
|
||||
*/
|
||||
function saveConfig($config_values)
|
||||
{
|
||||
if (!is_array($config_values))
|
||||
{
|
||||
error_log(__METHOD__." unable to save backup config values, wrong type of parameter passed.");
|
||||
return false;
|
||||
}
|
||||
//_debug_array($config_values);
|
||||
$minCount = $config_values['backup_mincount'];
|
||||
$backupFiles = (int)$config_values['backup_files'];
|
||||
/* minCount */
|
||||
$this->db->insert(
|
||||
self::TABLE,
|
||||
array(
|
||||
'config_value' => $minCount,
|
||||
),
|
||||
array(
|
||||
'config_app' => 'phpgwapi',
|
||||
'config_name' => 'backup_mincount',
|
||||
),
|
||||
__LINE__,
|
||||
__FILE__);
|
||||
/* backup files flag */
|
||||
$this->db->insert(self::TABLE,array('config_value' => $backupFiles),array('config_app' => 'phpgwapi','config_name' => 'backup_files'),__LINE__,__FILE__);
|
||||
$this->backup_mincount = $minCount;
|
||||
$this->backup_files = (bool)$backupFiles;
|
||||
// Update session cache
|
||||
$GLOBALS['egw']->invalidate_session_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup all data in the form of a (compressed) csv file
|
||||
@ -172,7 +334,7 @@ class db_backup
|
||||
* @param resource $f file opened with fopen for reading
|
||||
* @param boolean $convert_to_system_charset=false convert the restored data to the selected system-charset
|
||||
*/
|
||||
function restore($f,$convert_to_system_charset=false)
|
||||
function restore($f,$convert_to_system_charset=false,$filename)
|
||||
{
|
||||
@set_time_limit(0);
|
||||
ini_set('auto_detect_line_endings',true);
|
||||
@ -189,7 +351,37 @@ class db_backup
|
||||
}
|
||||
$this->schema_proc->DropTable($table);
|
||||
}
|
||||
// it could be an old backup
|
||||
list( , $type) = explode('.', basename($filename));
|
||||
$dir = $this->files_dir; // $GLOBALS['egw_info']['server']['files_dir'];
|
||||
// we may have to clean up old backup - left overs
|
||||
if (is_dir($dir.'/database_backup'))
|
||||
{
|
||||
remove_dir_content($dir.'/database_backup/');
|
||||
rmdir($dir.'/database_backup');
|
||||
}
|
||||
|
||||
$list = array();
|
||||
$name = "";
|
||||
$zip = NULL;
|
||||
$_f = NULL;
|
||||
if($type == 'zip')
|
||||
{
|
||||
$zip = new ZipArchive;
|
||||
if(($zip->open($filename)) !== TRUE)
|
||||
{
|
||||
return "Cant open '$filename' for reading<br>";
|
||||
}
|
||||
$this->remove_dir_content($dir); // removes the files-dir
|
||||
$zip->extractTo($dir);
|
||||
$_f = $f;
|
||||
$list = $this->get_file_list($dir.'/database_backup/');
|
||||
$name = $dir.'/database_backup/'.basename($list[0]);
|
||||
if(!($f = fopen($name, 'rb')))
|
||||
{
|
||||
return "Cant open $name for reading<br>";
|
||||
}
|
||||
}
|
||||
$table = False;
|
||||
$n = 0;
|
||||
while(!feof($f))
|
||||
@ -273,6 +465,11 @@ class db_backup
|
||||
echo 'data=<pre>'.print_r($data,true)."</pre>\n";
|
||||
$import = false;
|
||||
}
|
||||
if (in_array($table,$this->exclude_tables))
|
||||
{
|
||||
echo '<p><b>'.lang("Table %1 is excluded from backup and restore. Data will not be restored.",$table)."</b></p>\n";
|
||||
$import = false; // dont restore data of excluded tables
|
||||
}
|
||||
if ($import) {
|
||||
if (count($data) == count($cols))
|
||||
{
|
||||
@ -312,9 +509,36 @@ class db_backup
|
||||
'config_name' => 'system_charset',
|
||||
),__LINE__,__FILE__);
|
||||
}
|
||||
// zip?
|
||||
if($type == 'zip')
|
||||
{
|
||||
fclose($f);
|
||||
$f = $save_f;
|
||||
unlink($name);
|
||||
rmdir($dir.'/database_backup');
|
||||
}
|
||||
$this->db->transaction_commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a dir, no matter whether it is empty or full
|
||||
*
|
||||
* @param strin $dir
|
||||
*/
|
||||
function remove_dir_content($dir)
|
||||
{
|
||||
$list = scandir($dir);
|
||||
while($file = $list[0])
|
||||
{
|
||||
if(is_dir($file) && $file != '.' && $file != '..')
|
||||
$this->remove_dir_content($dir.'/'.$file);
|
||||
if(is_file($file) && $file != '.' && $file != '..')
|
||||
unlink($dir.'/'.$file);
|
||||
array_shift($list);
|
||||
}
|
||||
//rmdir($dir); // dont remove own dir
|
||||
}
|
||||
|
||||
/**
|
||||
* Split one line of a csv file into an array and does all unescaping
|
||||
*/
|
||||
@ -391,8 +615,35 @@ class db_backup
|
||||
*/
|
||||
function backup($f)
|
||||
{
|
||||
//echo "function backup($f)<br>"; // !
|
||||
@set_time_limit(0);
|
||||
$dir = $this->files_dir; // $GLOBALS['egw_info']['server']['files_dir'];
|
||||
// we may have to clean up old backup - left overs
|
||||
if (is_dir($dir.'/database_backup'))
|
||||
{
|
||||
remove_dir_content($dir.'/database_backup/');
|
||||
rmdir($dir.'/database_backup');
|
||||
}
|
||||
|
||||
$file_list = $this->get_file_list($dir);
|
||||
$name = $this->backup_dir.'/db_backup-'.date('YmdHi');
|
||||
$filename = $name.'.zip';
|
||||
$zippresent = false;
|
||||
if(class_exists('ZipArchive') && $this->backup_files)
|
||||
{
|
||||
$zip = new ZipArchive;
|
||||
if(is_object($zip))
|
||||
{
|
||||
$zippresent = true;
|
||||
//echo '-> is_object($zip); '.$filename.'<br>'; // !
|
||||
$res = $zip->open($filename, ZIPARCHIVE::CREATE);
|
||||
if($res !== TRUE)
|
||||
{
|
||||
//echo ' -> !$res<br>'; // !
|
||||
return "Cant open '$filename'<br>";
|
||||
}
|
||||
}
|
||||
}
|
||||
fwrite($f,"eGroupWare backup from ".date('Y-m-d H:i:s')."\n\n");
|
||||
|
||||
fwrite($f,"version: $this->api_version\n\n");
|
||||
@ -422,7 +673,7 @@ class db_backup
|
||||
|
||||
$first_row = true;
|
||||
$this->db->select($table,'*',false,__LINE__,__FILE__);
|
||||
while(($row = $this->db->row(true)))
|
||||
while($row = $this->db->row(true))
|
||||
{
|
||||
if ($first_row)
|
||||
{
|
||||
@ -433,9 +684,77 @@ class db_backup
|
||||
fwrite($f,implode(',',$row)."\n");
|
||||
}
|
||||
}
|
||||
// save files
|
||||
if(!$zippresent) // save without files (why ever it works only right without '!'...)
|
||||
{
|
||||
echo '<center>'."No file backup, needs ZipArchive or disabled<br>".'</center>';
|
||||
fclose($f);
|
||||
if (file_exists($name)) unlink($name);
|
||||
return TRUE;
|
||||
}
|
||||
//echo $name.'<br>';
|
||||
$zip->addFile($name, 'database_backup/'.basename($name));
|
||||
$count = 1;
|
||||
foreach($file_list as $num => $file)
|
||||
{
|
||||
//echo substr($file,strlen($dir)+1).'<br>';
|
||||
//echo $file.'<br>';
|
||||
$zip->addFile($file,substr($file,strlen($dir)+1));//,substr($file);
|
||||
if(($count++) == 100) { // the file descriptor limit
|
||||
$zip->close();
|
||||
if($zip = new ZipArchive()) {
|
||||
$zip->open($filename);
|
||||
$count =0;
|
||||
}
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
fclose($f);
|
||||
unlink($name);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets a list of all files on $f
|
||||
*
|
||||
* @param string file $f
|
||||
* [@param int $cnt]
|
||||
* [@param string $path_name]
|
||||
*
|
||||
* @return array (list of files)
|
||||
*/
|
||||
function get_file_list($f, $cnt = 0, $path_name = "")
|
||||
{
|
||||
//chdir($f);
|
||||
//echo "Processing $f <br>";
|
||||
if ($path_name =='') $path_name = $f;
|
||||
$tlist = scandir($f);
|
||||
$list = array();
|
||||
$i = $cnt;
|
||||
while($file = $tlist[0]) // remove all '.' and '..' and transfer to $list
|
||||
{
|
||||
if($file == '.' || $file == '..')
|
||||
{
|
||||
array_shift($tlist);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_dir($f.'/'.$file))
|
||||
{
|
||||
$nlist = $this->get_file_list($f.'/'.$file, $i);
|
||||
$list += $nlist;
|
||||
$i += count($nlist);
|
||||
array_shift($tlist);
|
||||
}
|
||||
else
|
||||
{
|
||||
$list[$i++] = $path_name.'/'.array_shift($tlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup all schemas in the form of a setup/tables_current.inc.php file
|
||||
*
|
||||
|
@ -36,14 +36,15 @@ if ($_POST['download'])
|
||||
{
|
||||
list($file) = each($_POST['download']);
|
||||
$file = $db_backup->backup_dir.'/'.basename($file); // basename to now allow to change the dir
|
||||
|
||||
ob_end_clean();
|
||||
$browser = CreateObject('phpgwapi.browser');
|
||||
$browser->content_header(basename($file));
|
||||
fpassthru($f = fopen($file,'rb'));
|
||||
$f = fopen($file,'rb');
|
||||
fpassthru($f);
|
||||
fclose($f);
|
||||
exit;
|
||||
}
|
||||
$setup_tpl = CreateObject('phpgwapi.Template',$tpl_root);
|
||||
$setup_tpl = CreateObject('phpgwapi.Template',$tpl_root);
|
||||
$setup_tpl->set_file(array(
|
||||
'T_head' => 'head.tpl',
|
||||
'T_footer' => 'footer.tpl',
|
||||
@ -70,6 +71,35 @@ else
|
||||
$GLOBALS['egw']->common->phpgw_header();
|
||||
parse_navbar();
|
||||
}
|
||||
// save backup housekeeping settings
|
||||
if ($_POST['save_backup_settings'])
|
||||
{
|
||||
$matches = array();
|
||||
preg_match('/^[1-9][0-9]*$/', $_POST['backup_mincount'], $matches);
|
||||
$minCount = $matches[0];
|
||||
$filesBackup =false;
|
||||
if ($_POST['backup_files']==='backup_files') $filesBackup = true;
|
||||
if (empty($minCount))
|
||||
{
|
||||
$setup_tpl->set_var('error_msg',htmlspecialchars(lang("'%1' must be integer", lang("backup min count"))));
|
||||
}
|
||||
else
|
||||
{
|
||||
$configValues = array(
|
||||
'backup_mincount'=>$minCount,
|
||||
'backup_files' =>$filesBackup,
|
||||
);
|
||||
$db_backup->saveConfig($configValues);
|
||||
|
||||
$cleaned_files = array();
|
||||
/* Remove old backups. */
|
||||
$db_backup->housekeeping(&$cleaned_files);
|
||||
foreach ($cleaned_files as $file)
|
||||
{
|
||||
echo '<div align="center">'.lang('entry has been deleted sucessfully').': '.$file."</div>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
// create a backup now
|
||||
if($_POST['backup'])
|
||||
{
|
||||
@ -77,8 +107,17 @@ if($_POST['backup'])
|
||||
{
|
||||
echo '<p align="center">'.lang('backup started, this might take a few minutes ...')."</p>\n".str_repeat(' ',4096);
|
||||
$db_backup->backup($f);
|
||||
if(is_resource($f))
|
||||
fclose($f);
|
||||
$setup_tpl->set_var('error_msg',lang('backup finished'));
|
||||
|
||||
/* Remove old backups. */
|
||||
$cleaned_files = array();
|
||||
$db_backup->housekeeping(&$cleaned_files);
|
||||
foreach ($cleaned_files as $file)
|
||||
{
|
||||
echo '<div align="center">'.lang('entry has been deleted sucessfully').': '.$file."</div>\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -88,6 +127,9 @@ if($_POST['backup'])
|
||||
$setup_tpl->set_var('backup_now_button','<input type="submit" name="backup" title="'.htmlspecialchars(lang("back's up your DB now, this might take a few minutes")).'" value="'.htmlspecialchars(lang('backup now')).'" />');
|
||||
$setup_tpl->set_var('upload','<input type="file" name="uploaded" /> '.
|
||||
'<input type="submit" name="upload" value="'.htmlspecialchars(lang('upload backup')).'" title="'.htmlspecialchars(lang("uploads a backup to the backup-dir, from where you can restore it")).'" />');
|
||||
$setup_tpl->set_var('backup_mincount','<input type="text" name="backup_mincount" value="'.$db_backup->backup_mincount.'" size="3" maxlength="3"/>');
|
||||
$setup_tpl->set_var('backup_files','<input type="checkbox" name="backup_files" value="backup_files"'.((bool)$db_backup->backup_files ? 'checked':'').'/>');
|
||||
$setup_tpl->set_var('backup_save_settings','<input type="submit" name="save_backup_settings" value="'.htmlspecialchars(lang('save')).'" />');
|
||||
|
||||
if ($_POST['upload'] && is_array($_FILES['uploaded']) && !$_FILES['uploaded']['error'] &&
|
||||
is_uploaded_file($_FILES['uploaded']['tmp_name']))
|
||||
@ -116,6 +158,9 @@ if ($_POST['rename'])
|
||||
$new_name = $_POST['new_name'][$file];
|
||||
if (!empty($new_name))
|
||||
{
|
||||
list($ending) = array_reverse(explode('.', $file));
|
||||
list($new_ending, $has_ending) = array_reverse(explode('.', $new_name));
|
||||
if(!$has_ending || $new_ending != $ending) $new_name .= '.'.$ending;
|
||||
$file = $db_backup->backup_dir.'/'.basename($file); // basename to not allow to change the dir
|
||||
$ext = preg_match('/(\.gz|\.bz2)+$/i',$file,$matches) ? $matches[1] : '';
|
||||
$new_file = $db_backup->backup_dir.'/'.preg_replace('/(\.gz|\.bz2)+$/i','',basename($new_name)).$ext;
|
||||
@ -131,8 +176,7 @@ if ($_POST['restore'])
|
||||
if (is_resource($f = $db_backup->fopen_backup($file,true)))
|
||||
{
|
||||
echo '<p align="center">'.lang('restore started, this might take a few minutes ...')."</p>\n".str_repeat(' ',4096);
|
||||
$db_backup->restore($f);
|
||||
fclose($f);
|
||||
$db_backup->restore($f, FALSE, $file);
|
||||
$setup_tpl->set_var('error_msg',lang("backup '%1' restored",$file));
|
||||
}
|
||||
else
|
||||
@ -214,6 +258,10 @@ $setup_tpl->set_var(array(
|
||||
'lang_next_run' => lang('next run'),
|
||||
'lang_actions' => lang('actions'),
|
||||
'lang_backup_sets' => lang('backup sets'),
|
||||
'lang_backup_cleanup' => lang('backup housekeeping'),
|
||||
'lang_backup_mincount' => lang('min backup count'),
|
||||
'lang_backup_files_info' => lang('backup files (needs ZipArchive)'),
|
||||
'lang_backup_files' => lang('check to backup and restore the files directory (may use a lot of space, make sure to configure housekeeping accordingly)'),
|
||||
'lang_filename' => lang('filename'),
|
||||
'lang_date' => lang('created'),
|
||||
'lang_size' => lang('size'),
|
||||
|
@ -351,6 +351,8 @@ class setup_cmd_config extends setup_cmd
|
||||
// some extra defaults for non-cli operation
|
||||
$defaults['files_dir'] = '/var/lib/egroupware/$domain/files';
|
||||
$defaults['backup_dir'] = '/var/lib/egroupware/$domain/backup';
|
||||
$defaults['backup_mincount'] = 0;
|
||||
$defaults['backup_files'] = false;
|
||||
$defaults['temp_dir'] = '/tmp';
|
||||
$defaults['webserver_url'] = '/egroupware';
|
||||
$defaults['smtp_server'] = $defaults['mail_server'] = 'localhost';
|
||||
|
@ -389,6 +389,24 @@ class setup_detection
|
||||
),__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
if (isset($config['backup_mincount']))
|
||||
{
|
||||
$GLOBALS['egw_setup']->db->insert($GLOBALS['egw_setup']->config_table,array(
|
||||
'config_value' => $config['backup_mincount'],
|
||||
),array(
|
||||
'config_app' => 'phpgwapi',
|
||||
'config_name' => 'backup_mincount',
|
||||
),__LINE__,__FILE__);
|
||||
}
|
||||
if (isset($config['backup_files']))
|
||||
{
|
||||
$GLOBALS['egw_setup']->db->insert($GLOBALS['egw_setup']->config_table,array(
|
||||
'config_value' => (int)$config['backup_files'],
|
||||
),array(
|
||||
'config_app' => 'phpgwapi',
|
||||
'config_name' => 'backup_files',
|
||||
),__LINE__,__FILE__);
|
||||
};
|
||||
if (!$this->check_dir($config['backup_dir'],$error_msg,true))
|
||||
{
|
||||
$config_errors[] = lang("Your backup directory '%1' %2",$config['backup_dir'],$error_msg);
|
||||
|
@ -10,6 +10,7 @@
|
||||
%1, %2 or %3 the configuration file. setup de %1, %2 oder %3 der Konfigurationsdatei.
|
||||
'%1' is no valid domain name! setup de '%1' ist kein gültiger Domainname!
|
||||
'%1' is not allowed as %2. arguments of option %3 !!! setup de '%1' ist nicht erlaubt als %2. Parameter für die Option %3 !!!
|
||||
'%1' must be integer setup de %1 muß ein Integer-Wert sein.
|
||||
(searching accounts and changing passwords) setup de Benutzerkonten suchen und Passwörter ändern)
|
||||
*** do not update your database via setup, as the update might be interrupted by the max_execution_time, which leaves your db in an unrecoverable state (your data is lost) !!! setup de *** Updaten Sie NICHT Ihre Datenbank via Setup, da das Update von der max_execution_time (max. Ausführungszeit für Skripte) unterbrochen werden kann. Ihre Datenbank ist dann in einem nicht mehr wiederherstellbaren Zustand (Ihre Daten sind VERLOREN)!!!
|
||||
*** you have to do the changes manualy in your php.ini (usualy in /etc on linux) in order to get egw fully working !!! setup de *** Sie müssen die Änderungen manuell in Ihrer php.ini Datei (üblicherweise in /etc unter Linux) durchführen, um eGroupWare vollständig/fehlerfrei ausführen zu können!!!
|
||||
@ -88,7 +89,10 @@ backup '%1' renamed to '%2' setup de Datensicherung '%1' nach '%2' umbenannt
|
||||
backup '%1' restored setup de Datensicherung '%1' zurückgesichert
|
||||
backup and restore setup de Datensicherung und Wiederherstellung
|
||||
backup failed setup de Datensicherung fehlgeschlagen
|
||||
backup files (needs ziparchive) setup de Datensicherung der eGroupware Dateiumgebung (files Verzeichnis) (benötigt die PHP Bibliothek ZipArchive)
|
||||
backup finished setup de Datensicherung beendet
|
||||
backup housekeeping setup de Backups mit Standard-Namen können automatisch aufgeräumt werden. Umbenannte Backup-Dateien werden nie aufgeräumt werden.
|
||||
backup min count setup de Min. Anzahl der Backups
|
||||
backup now setup de jetzt sichern
|
||||
backup sets setup de Datensicherungen
|
||||
backup skipped! setup de Datensicherung ausgelassen!
|
||||
@ -122,6 +126,7 @@ charsets used by the different languages setup de Zeichensätze die von den vers
|
||||
check can only be performed, if called via a webserver, as the user-id/-name of the webserver is not known. setup de Dieser Test kann nur durchgeführt werden, wenn der Aufruf über den Webserver erfolgt, da Benutzer-Id und -name des Webservers nicht bekannt sind.
|
||||
check installation setup de Installation überprüfen
|
||||
check ip address of all sessions setup de IP Adresse bei allen Sessions überprüfen
|
||||
check to backup and restore the files directory (may use a lot of space, make sure to configure housekeeping accordingly) setup de anhaken, um das Backup und Restore der Dateiumgebung (Datei-Verzeichnis) zu aktivieren. (diese Option kann grosse Mengen an Festplatten-Speicherpatz verbrauchen; stellen Sie sicher dass das Housekeeping entsprechend konfiguriert ist.)
|
||||
checking extension %1 is loaded or loadable setup de Überprüfe ob die Erweiterung %1 geladen oder ladbar ist
|
||||
checking file-permissions of %1 for %2 %3: %4 setup de Überprüfe Datei Zugriffsrechte von %1 für %2 %3: %4
|
||||
checking for gd support... setup de Überprüfe die GD Unterstützung...
|
||||
@ -181,6 +186,7 @@ database setup de Datenbank
|
||||
database instance (egw domain) setup de Datenbankinstanz (eGW Domain)
|
||||
database is version %1 and up to date. setup de Datenbank ist Version %1 und aktuell.
|
||||
database successfully converted from '%1' to '%2' setup de Datenbank erfolgreich von "%1" nach "%2" konvertiert
|
||||
datebase %1 droped. setup de Datenbank %1 gelöscht.
|
||||
datetime port.<br />if using port 13, please set firewall rules appropriately before submitting this page.<br />(port: 13 / host: 129.6.15.28) setup de Port für Datum/Zeitabfragen<br />Wenn der Port 13 verwendet wird, bitte VOR dem Absenden die Firewallregeln dementsprechend setzen.<br />(Port 13/Host: 129.6.15.28)
|
||||
day setup de Tag
|
||||
day of week<br />(0-6, 0=sunday) setup de Wochentag<br />(0-6, 0=Sonntag)
|
||||
@ -255,6 +261,7 @@ enter your http proxy server setup de HTTP-Proxy-Server
|
||||
enter your http proxy server password setup de Passwort des HTTP-Proxy-Servers
|
||||
enter your http proxy server port setup de Port des HTTP-Proxy-Servers
|
||||
enter your http proxy server username setup de Benutzername des HTTP-Proxy-Servers
|
||||
error dropping user! setup de Fehler beim Löschen des Benutzers!
|
||||
error in admin-creation !!! setup de Fehler beim Anlegen des Admin-Kontos !!!
|
||||
error in group-creation !!! setup de Fehler beim Anlegen der Gruppen !!!
|
||||
export has been completed! setup de Export ist abgeschlossen!
|
||||
@ -365,6 +372,7 @@ mcrypt mode (default cbc) setup de MCrypt-Modus (Vorgabe CBC)
|
||||
mcrypt settings (requires mcrypt php extension) setup de MCrypt-Einstellungen (benötigt die mcrypt Erweiterung von PHP)
|
||||
memory_limit is set to less than %1: some applications of egroupware need more than the recommend 8m, expect occasional failures setup de memory_limit (maximale Speicher für ein Skript) ist auf weniger als %1 gesetzt: einige eGroupWare Anwendungen benötigen mehr als die empfohlenen 8M. Sie müssen mit gelegentlichen Fehlern rechnen.
|
||||
migration between egroupware account repositories setup de Migration zwischen versch. Orten zur Speicherung von eGroupWare Benutzern
|
||||
min backup count setup de Min. Anzahl gehaltener Backups (null: alle / kein Limit)
|
||||
minimum account id (e.g. 500 or 100, etc.) setup de Minimum für Benutzer-ID (z.B. 500 oder 100)
|
||||
minute setup de Minute
|
||||
missing or uncomplete mailserver configuration setup de Fehlende oder nicht komplette Mailserver Konfiguration
|
||||
|
@ -10,6 +10,7 @@
|
||||
%1, %2 or %3 the configuration file. setup en %1, %2 or %3 the configuration file.
|
||||
'%1' is no valid domain name! setup en '%1' is no valid domain name!
|
||||
'%1' is not allowed as %2. arguments of option %3 !!! setup en '%1' is not allowed as %2. arguments of option %3 !!!
|
||||
'%1' must be integer setup en %1 must be an integer value.
|
||||
(searching accounts and changing passwords) setup en (searching accounts and changing passwords)
|
||||
*** do not update your database via setup, as the update might be interrupted by the max_execution_time, which leaves your db in an unrecoverable state (your data is lost) !!! setup en *** Do NOT update your database via setup, as the update might be interrupted by the max_execution_time, which leaves your DB in an unrecoverable state (your data is lost) !!!
|
||||
*** you have to do the changes manualy in your php.ini (usualy in /etc on linux) in order to get egw fully working !!! setup en *** You have to do the changes manualy in your php.ini (usualy in /etc on linux) in order to get eGW fully working !!!
|
||||
@ -88,7 +89,10 @@ backup '%1' renamed to '%2' setup en backup '%1' renamed to '%2'
|
||||
backup '%1' restored setup en backup '%1' restored
|
||||
backup and restore setup en backup and restore
|
||||
backup failed setup en Backup failed
|
||||
backup files (needs ziparchive) setup en backup files (needs ZipArchive)
|
||||
backup finished setup en backup finished
|
||||
backup housekeeping setup en Backups with a standard name can be cleaned up automatically. Rename backup files to exclude them from cleanup.
|
||||
backup min count setup en Minumum number of backups
|
||||
backup now setup en backup now
|
||||
backup sets setup en backup sets
|
||||
backup skipped! setup en Backup skipped!
|
||||
@ -122,6 +126,7 @@ charsets used by the different languages setup en charsets used by the different
|
||||
check can only be performed, if called via a webserver, as the user-id/-name of the webserver is not known. setup en Check can only be performed, if called via a webserver, as the user-id/-name of the webserver is not known.
|
||||
check installation setup en Check installation
|
||||
check ip address of all sessions setup en check ip address of all sessions
|
||||
check to backup and restore the files directory (may use a lot of space, make sure to configure housekeeping accordingly) setup en check to backup and restore the files directory (may use a lot of space, make sure to configure housekeeping accordingly)
|
||||
checking extension %1 is loaded or loadable setup en Checking extension %1 is loaded or loadable
|
||||
checking file-permissions of %1 for %2 %3: %4 setup en Checking file-permissions of %1 for %2 %3: %4
|
||||
checking for gd support... setup en Checking for GD support...
|
||||
@ -181,6 +186,7 @@ database setup en Database
|
||||
database instance (egw domain) setup en Database instance (eGW domain)
|
||||
database is version %1 and up to date. setup en database is version %1 and up to date.
|
||||
database successfully converted from '%1' to '%2' setup en Database successfully converted from '%1' to '%2'
|
||||
datebase %1 droped. setup en Datebase %1 droped.
|
||||
datetime port.<br />if using port 13, please set firewall rules appropriately before submitting this page.<br />(port: 13 / host: 129.6.15.28) setup en Datetime port.<br />If using port 13, please set firewall rules appropriately before submitting this page.<br />(Port: 13 / Host: 129.6.15.28)
|
||||
day setup en day
|
||||
day of week<br />(0-6, 0=sunday) setup en day of week<br />(0-6, 0=sunday)
|
||||
@ -253,6 +259,7 @@ enter your http proxy server setup en Enter your HTTP proxy server
|
||||
enter your http proxy server password setup en Enter your HTTP proxy server password
|
||||
enter your http proxy server port setup en Enter your HTTP proxy server port
|
||||
enter your http proxy server username setup en Enter your HTTP proxy server username
|
||||
error dropping user! setup en Error dropping User!
|
||||
error in admin-creation !!! setup en Error in admin-creation !!!
|
||||
error in group-creation !!! setup en Error in group-creation !!!
|
||||
export has been completed! setup en Export has been completed!
|
||||
@ -363,6 +370,7 @@ mcrypt mode (default cbc) setup en Mcrypt mode (default CBC)
|
||||
mcrypt settings (requires mcrypt php extension) setup en Mcrypt Settings (requires mcrypt PHP extension)
|
||||
memory_limit is set to less than %1: some applications of egroupware need more than the recommend 8m, expect occasional failures setup en memory_limit is set to less than %1: some applications of eGroupWare need more than the recommend 8M, expect occasional failures
|
||||
migration between egroupware account repositories setup en Migration between eGroupWare account repositories
|
||||
min backup count setup en Number of backups to keep at least (zero: all / no limit)
|
||||
minimum account id (e.g. 500 or 100, etc.) setup en Minimum account id (e.g. 500 or 100, etc.)
|
||||
minute setup en minute
|
||||
missing or uncomplete mailserver configuration setup en Missing or uncomplete mailserver configuration
|
||||
|
@ -59,6 +59,27 @@
|
||||
{upload}
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#e6e6ee">
|
||||
<td>
|
||||
{lang_backup_cleanup}
|
||||
</td>
|
||||
<td align="right">
|
||||
{lang_backup_mincount} {backup_mincount}
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#e6e6e6">
|
||||
<td>
|
||||
{lang_backup_files_info}
|
||||
</td>
|
||||
<td align="right">
|
||||
{lang_backup_files} {backup_files}
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#e6e6ee">
|
||||
<td colspan="2" align="right">
|
||||
{backup_save_settings}
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#e6e6e6">
|
||||
<td colspan="2">
|
||||
<table style="border: 1px solid black; border-collapse: collapse;" border="1" width="100%">
|
||||
|
Loading…
Reference in New Issue
Block a user