Provide a solution for backup when mysqldump is not available.

This commit is contained in:
Laurent Destailleur
2012-06-14 22:32:40 +02:00
parent ee9ad80c55
commit c39dadea14
2 changed files with 528 additions and 266 deletions

View File

@@ -1,5 +1,5 @@
<?php <?php
/* Copyright (C) 2006-2011 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2006-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -19,41 +19,87 @@
* \file htdocs/admin/tools/dolibarr_export.php * \file htdocs/admin/tools/dolibarr_export.php
* \ingroup core * \ingroup core
* \brief Page to export database * \brief Page to export database
* \version $Id: dolibarr_export.php,v 1.40 2011/08/03 00:45:43 eldy Exp $
*/ */
require("../../main.inc.php"); require("../../main.inc.php");
require_once(DOL_DOCUMENT_ROOT."/lib/admin.lib.php");
require_once(DOL_DOCUMENT_ROOT."/lib/files.lib.php");
require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php"); require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php");
include_once $dolibarr_main_document_root."/lib/databases/".$conf->db->type.".lib.php";
$langs->load("admin"); $langs->load("admin");
if (! $user->admin) $action=GETPOST('action');
accessforbidden();
$sortfield = GETPOST("sortfield");
$sortorder = GETPOST("sortorder");
$page = GETPOST("page");
if (! $sortorder) $sortorder="DESC";
if (! $sortfield) $sortfield="date";
if ($page < 0) { $page = 0; }
$limit = $conf->liste_limit;
$offset = $limit * $page;
if (! $user->admin) accessforbidden();
$html=new Form($db);
$formfile = new FormFile($db); /*
* Actions
*/
if ($action == 'delete')
{
dol_delete_file($conf->admin->dir_output.'/backup/'.GETPOST('urlfile'),1);
$action='';
}
/* /*
* View * View
*/ */
llxHeader('','','EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad'); $form=new Form($db);
$formfile = new FormFile($db);
$label=$db->label;
$help_url='EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad';
llxHeader('','',$help_url);
?> ?>
<script type="text/javascript" language="javascript"> <script type="text/javascript">
jQuery(document).ready(function() { jQuery(document).ready(function() {
jQuery("#mysql_options").hide();
jQuery("#postgresql_options").hide();
function hideoptions () {
jQuery("#mysql_options").hide();
jQuery("#mysql_options_nobin").hide();
jQuery("#postgresql_options").hide();
}
hideoptions();
jQuery("#radio_dump_mysql").click(function() { jQuery("#radio_dump_mysql").click(function() {
hideoptions();
jQuery("#mysql_options").show(); jQuery("#mysql_options").show();
}); });
jQuery("#radio_dump_mysql_nobin").click(function() {
hideoptions();
jQuery("#mysql_options_nobin").show();
});
jQuery("#radio_dump_postgresql").click(function() { jQuery("#radio_dump_postgresql").click(function() {
hideoptions();
jQuery("#postgresql_options").show(); jQuery("#postgresql_options").show();
}); });
jQuery("#select_sql_compat").click(function() {
if (jQuery("#select_sql_compat").val() == 'POSTGRESQL')
{
jQuery("#checkbox_dump_disable-add-locks").attr('checked',true);
};
});
<?php
if ($label == 'MySQL') print 'jQuery("#radio_dump_mysql").click();';
if ($label == 'PostgreSQL') print 'jQuery("#radio_dump_postgresql").click();';
?>
}); });
</script> </script>
<?php <?php
@@ -81,7 +127,7 @@ if ($_GET["msg"])
name="token" value="<?php echo $_SESSION['newtoken']; ?>" /> <input name="token" value="<?php echo $_SESSION['newtoken']; ?>" /> <input
type="hidden" name="export_type" value="server" /> type="hidden" name="export_type" value="server" />
<fieldset id="fieldsetexport"><!-- LDR --> <fieldset id="fieldsetexport">
<?php print '<legend>'.$langs->trans("DatabaseName").' : <b>'.$dolibarr_main_db_name.'</b></legend>'; ?> <?php print '<legend>'.$langs->trans("DatabaseName").' : <b>'.$dolibarr_main_db_name.'</b></legend>'; ?>
<table> <table>
<tr> <tr>
@@ -90,15 +136,19 @@ if ($_GET["msg"])
<div id="div_container_exportoptions"> <div id="div_container_exportoptions">
<fieldset id="exportoptions"><legend><?php echo $langs->trans("ExportMethod"); ?></legend> <fieldset id="exportoptions"><legend><?php echo $langs->trans("ExportMethod"); ?></legend>
<?php <?php
if ($db->label == 'MySQL') if ($label == 'MySQL')
{ {
?> ?>
<div class="formelementrow"><input type="radio" name="what" value="mysql" id="radio_dump_mysql" /> <div class="formelementrow"><input type="radio" name="what" value="mysql" id="radio_dump_mysql" />
<label for="radio_dump_mysql">MySQL Dump (mysqldump)</label> <label for="radio_dump_mysql">MySQL Dump (mysqldump)</label>
</div> </div>
<br>
<div class="formelementrow"><input type="radio" name="what" value="mysqlnobin" id="radio_dump_mysql_nobin" />
<label for="radio_dump_mysql">MySQL Dump (php) <?php print img_warning('Backup can\'t be guaranted with this method. Prefer previous one'); ?></label>
</div>
<?php <?php
} }
else if ($db->label == 'PostgreSQL') else if ($label == 'PostgreSQL')
{ {
?> ?>
<div class="formelementrow"><input type="radio" name="what" value="postgresql" id="radio_dump_postgresql" /> <div class="formelementrow"><input type="radio" name="what" value="postgresql" id="radio_dump_postgresql" />
@@ -108,7 +158,7 @@ if ($_GET["msg"])
} }
else else
{ {
print 'No method available with database '.$db->label; print 'No method available with database '.$label;
} }
?> ?>
</fieldset> </fieldset>
@@ -120,7 +170,7 @@ if ($_GET["msg"])
<div id="div_container_sub_exportoptions"> <div id="div_container_sub_exportoptions">
<?php <?php
if ($db->label == 'MySQL') if ($label == 'MySQL')
{ {
?> <!-- Fieldset mysqldump --> ?> <!-- Fieldset mysqldump -->
<fieldset id="mysql_options"><legend><?php echo $langs->trans("MySqlExportParameters"); ?></legend> <fieldset id="mysql_options"><legend><?php echo $langs->trans("MySqlExportParameters"); ?></legend>
@@ -181,13 +231,17 @@ if ($_GET["msg"])
id="checkbox_sql_data" checked="checked" /> <label for="checkbox_sql_data"> id="checkbox_sql_data" checked="checked" /> <label for="checkbox_sql_data">
<?php echo $langs->trans("Datas"); ?></label> </legend> <input <?php echo $langs->trans("Datas"); ?></label> </legend> <input
type="checkbox" name="showcolumns" value="yes" type="checkbox" name="showcolumns" value="yes"
id="checkbox_dump_showcolumns" /> <label id="checkbox_dump_showcolumns" checked="checked" /> <label
for="checkbox_dump_showcolumns"> <?php echo $langs->trans("NameColumn"); ?></label><br> for="checkbox_dump_showcolumns"> <?php echo $langs->trans("NameColumn"); ?></label><br>
<input type="checkbox" name="extended_ins" value="yes" <input type="checkbox" name="extended_ins" value="yes"
id="checkbox_dump_extended_ins" /> <label id="checkbox_dump_extended_ins" checked="checked" /> <label
for="checkbox_dump_extended_ins"> <?php echo $langs->trans("ExtendedInsert"); ?></label><br> for="checkbox_dump_extended_ins"> <?php echo $langs->trans("ExtendedInsert"); ?></label><br>
<input type="checkbox" name="disable-add-locks" value="no"
id="checkbox_dump_disable-add-locks" /> <label
for="checkbox_dump_disable-add-locks"> <?php echo $langs->trans("NoLockBeforeInsert"); ?></label><br>
<input type="checkbox" name="delayed" value="yes" <input type="checkbox" name="delayed" value="yes"
id="checkbox_dump_delayed" /> <label for="checkbox_dump_delayed"> <?php echo $langs->trans("DelayedInsert"); ?></label><br> id="checkbox_dump_delayed" /> <label for="checkbox_dump_delayed"> <?php echo $langs->trans("DelayedInsert"); ?></label><br>
@@ -198,12 +252,16 @@ if ($_GET["msg"])
id="checkbox_hexforbinary" checked="checked" /> <label id="checkbox_hexforbinary" checked="checked" /> <label
for="checkbox_hexforbinary"> <?php echo $langs->trans("EncodeBinariesInHexa"); ?></label><br> for="checkbox_hexforbinary"> <?php echo $langs->trans("EncodeBinariesInHexa"); ?></label><br>
<input type="checkbox" name="charset_utf8" value="yes"
id="checkbox_charset_utf8" checked="checked" disabled="disabled" /> <label
for="checkbox_charset_utf8"> <?php echo $langs->trans("UTF8"); ?></label><br>
</fieldset> </fieldset>
</fieldset> </fieldset>
<?php <?php
} }
if ($db->label == 'PostgreSQL') if ($label == 'PostgreSQL')
{ {
?> <!-- Fieldset pg_dump --> ?> <!-- Fieldset pg_dump -->
<fieldset id="postgresql_options"><legend><?php echo $langs->trans("PostgreSqlExportParameters"); ?></legend> <fieldset id="postgresql_options"><legend><?php echo $langs->trans("PostgreSqlExportParameters"); ?></legend>
@@ -244,7 +302,7 @@ if ($_GET["msg"])
id="checkbox_sql_data" checked="checked" /> <label for="checkbox_sql_data"> id="checkbox_sql_data" checked="checked" /> <label for="checkbox_sql_data">
<?php echo $langs->trans("Datas"); ?></label> </legend> <input <?php echo $langs->trans("Datas"); ?></label> </legend> <input
type="checkbox" name="showcolumns" value="yes" type="checkbox" name="showcolumns" value="yes"
id="checkbox_dump_showcolumns" /> <label id="checkbox_dump_showcolumns" checked="checked" /> <label
for="checkbox_dump_showcolumns"> <?php echo $langs->trans("NameColumn"); ?></label><br> for="checkbox_dump_showcolumns"> <?php echo $langs->trans("NameColumn"); ?></label><br>
</fieldset> </fieldset>
@@ -267,8 +325,8 @@ if ($_GET["msg"])
id="filename_template" id="filename_template"
value="<?php value="<?php
$prefix='dump'; $prefix='dump';
if ($db->label == 'MySQL') $prefix='mysqldump'; if ($label == 'MySQL') $prefix='mysqldump';
if ($db->label == 'PostgreSQL') $prefix='pg_dump'; if ($label == 'PostgreSQL') $prefix='pg_dump';
$file=$prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.strftime("%Y%m%d%H%M").'.sql'; $file=$prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.strftime("%Y%m%d%H%M").'.sql';
echo $file; echo $file;
?>" /> <br> ?>" /> <br>
@@ -278,13 +336,13 @@ echo $file;
// Define compressions array // Define compressions array
$compression=array( $compression=array(
'none' => array('function' => '', 'id' => 'radio_compression_none', 'label' => $langs->trans("None")), 'none' => array('function' => '', 'id' => 'radio_compression_none', 'label' => $langs->trans("None")),
// 'zip' => array('function' => 'zip_open', 'id' => 'radio_compression_zip', 'label' => $langs->trans("Zip")), Not open source 'gz' => array('function' => 'gzopen', 'id' => 'radio_compression_gzip', 'label' => $langs->trans("Gzip")),
'gz' => array('function' => 'gzopen', 'id' => 'radio_compression_gzip', 'label' => $langs->trans("Gzip")),
); );
if ($db->label == 'MySQL') if ($label == 'MySQL')
{ {
$compression['bz']=array('function' => 'bzopen', 'id' => 'radio_compression_bzip', 'label' => $langs->trans("Bzip2")); // $compression['zip']= array('function' => 'dol_compress', 'id' => 'radio_compression_zip', 'label' => $langs->trans("FormatZip")); // Not open source format. Must implement dol_compress function
$compression['bz'] = array('function' => 'bzopen', 'id' => 'radio_compression_bzip', 'label' => $langs->trans("Bzip2"));
} }
@@ -298,12 +356,12 @@ foreach($compression as $key => $val)
{ {
if (! $val['function'] || function_exists($val['function'])) // Enabled export format if (! $val['function'] || function_exists($val['function'])) // Enabled export format
{ {
print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'" checked="true">'; print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'" checked="checked">';
print ' <label for="'.$val['id'].'">'.$val['label'].'</label>'; print ' <label for="'.$val['id'].'">'.$val['label'].'</label>';
} }
else // Disabled export format else // Disabled export format
{ {
print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'" disabled="true">'; print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'" disabled="disabled">';
print ' <label for="'.$val['id'].'">'.$val['label'].'</label>'; print ' <label for="'.$val['id'].'">'.$val['label'].'</label>';
print ' ('.$langs->trans("NotAvailable").')'; print ' ('.$langs->trans("NotAvailable").')';
} }
@@ -316,20 +374,22 @@ print "\n";
?></fieldset> ?></fieldset>
<center><input type="submit" class="button" <div align="center"><input type="submit" class="button"
value="<?php echo $langs->trans("GenerateBackup") ?>" id="buttonGo" /><br> value="<?php echo $langs->trans("GenerateBackup") ?>" id="buttonGo" /><br>
<br> <br>
</center> </div>
</form> </form>
<?php <?php
$result=$formfile->show_documents('systemtools','backup',$conf->admin->dir_output.'/backup',$_SERVER['PHP_SELF'],0,1,'',1,0,0,54,0,'',$langs->trans("PreviousDumpFiles")); $filearray=dol_dir_list($conf->admin->dir_output.'/backup','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1);
//if ($result) print '<br><br>'; $result=$formfile->list_of_documents($filearray,null,'systemtools','',1,'backup/',1,0,$langs->trans("NoBackupFileAvailable"),0,$langs->trans("PreviousDumpFiles"));
print '<br>';
llxFooter();
$db->close(); $db->close();
llxFooter('$Date: 2011/08/03 00:45:43 $ - $Revision: 1.40 $');
?> ?>

View File

@@ -1,285 +1,332 @@
<?php <?php
/* Copyright (C) 2006-2010 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2006-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* \file htdocs/admin/tools/export.php * \file htdocs/admin/tools/export.php
* \brief Page to export a database into a dump file * \brief Page to export a database into a dump file
* \version $Id: export.php,v 1.45 2011/08/03 00:45:43 eldy Exp $
*/ */
require("../../main.inc.php"); require("../../main.inc.php");
require_once(DOL_DOCUMENT_ROOT."/lib/admin.lib.php"); require_once(DOL_DOCUMENT_ROOT."/lib/admin.lib.php");
require_once(DOL_DOCUMENT_ROOT."/lib/files.lib.php"); require_once(DOL_DOCUMENT_ROOT."/lib/files.lib.php");
require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php"); require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php");
include_once $dolibarr_main_document_root."/lib/databases/".$conf->db->type.".lib.php";
$what=$_REQUEST["what"];
$export_type=$_REQUEST["export_type"];
$file=isset($_POST['filename_template']) ? $_POST['filename_template'] : '';
$langs->load("admin"); $langs->load("admin");
if (! $user->admin) $action=GETPOST('action','alpha');
accessforbidden(); $what=GETPOST('what','alpha');
$export_type=GETPOST('export_type','alpha');
$file=GETPOST('filename_template','alpha');
$sortfield = GETPOST('sortfield','alpha');
$sortorder = GETPOST('sortorder','alpha');
$page = GETPOST("page");
if (! $sortorder) $sortorder="DESC";
if (! $sortfield) $sortfield="date";
if ($page < 0) { $page = 0; }
$limit = $conf->liste_limit;
$offset = $limit * $page;
if (! $user->admin) accessforbidden();
if ($file && ! $what) if ($file && ! $what)
{ {
//print DOL_URL_ROOT.'/dolibarr_export.php'; //print DOL_URL_ROOT.'/dolibarr_export.php';
header("Location: ".DOL_URL_ROOT.'/admin/tools/dolibarr_export.php?msg='.urlencode($langs->trans("ErrorFieldRequired",$langs->transnoentities("ExportMethod")))); header("Location: ".DOL_URL_ROOT.'/admin/tools/dolibarr_export.php?msg='.urlencode($langs->trans("ErrorFieldRequired",$langs->transnoentities("ExportMethod"))));
/* exit;
print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("ExportMethod")).'</div>';
print '<br>';
*/
exit;
} }
/*
* Actions
*/
if ($action == 'delete')
{
dol_delete_file($conf->admin->dir_output.'/backup/'.GETPOST('urlfile'),1);
$action='';
}
/* /*
* View * View
*/ */
llxHeader('','','EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad'); // Increase limit of time. Works only if we are not in safe mode
$html=new Form($db);
$formfile = new FormFile($db);
print_fiche_titre($langs->trans("Backup"),'','setup');
$ExecTimeLimit=600; $ExecTimeLimit=600;
if (!empty($ExecTimeLimit)) { if (!empty($ExecTimeLimit))
// Cette page peut etre longue. On augmente le delai autorise. {
// Ne fonctionne que si on est pas en safe_mode.
$err=error_reporting(); $err=error_reporting();
error_reporting(0); // Disable all errors error_reporting(0); // Disable all errors
//error_reporting(E_ALL); //error_reporting(E_ALL);
@set_time_limit($ExecTimeLimit); // Need more than 240 on Windows 7/64 @set_time_limit($ExecTimeLimit); // Need more than 240 on Windows 7/64
error_reporting($err); error_reporting($err);
} }
if (!empty($MemoryLimit)) { if (!empty($MemoryLimit))
{
@ini_set('memory_limit', $MemoryLimit); @ini_set('memory_limit', $MemoryLimit);
} }
$form=new Form($db);
$formfile = new FormFile($db);
$help_url='EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad';
llxHeader('','',$help_url);
print_fiche_titre($langs->trans("Backup"),'','setup');
// Start with empty buffer // Start with empty buffer
$dump_buffer = ''; $dump_buffer = '';
$dump_buffer_len = 0; $dump_buffer_len = 0;
// We send fake headers to avoid browser timeout when buffering // We will send fake headers to avoid browser timeout when buffering
$time_start = time(); $time_start = time();
// MYSQL // MYSQL
if ($what == 'mysql') if ($what == 'mysql')
{ {
$cmddump=$_POST["mysqldump"]; $cmddump=GETPOST("mysqldump"); // Do not sanitize here with 'alpha', will be sanitize later by escapeshellarg
if ($cmddump) if ($cmddump)
{ {
dolibarr_set_const($db, 'SYSTEMTOOLS_MYSQLDUMP', $cmddump,'chaine',0,'',$conf->entity); dolibarr_set_const($db, 'SYSTEMTOOLS_MYSQLDUMP', $cmddump,'chaine',0,'',$conf->entity);
} }
$outputdir = $conf->admin->dir_output.'/backup'; $outputdir = $conf->admin->dir_output.'/backup';
$outputfile = $outputdir.'/'.$file; $outputfile = $outputdir.'/'.$file;
// for compression format, we add extension // for compression format, we add extension
$compression=isset($_POST['compression']) ? $_POST['compression'] : 'none'; $compression=GETPOST('compression') ? GETPOST('compression','alpha') : 'none';
if ($compression == 'gz') $outputfile.='.gz'; if ($compression == 'gz') $outputfile.='.gz';
if ($compression == 'bz') $outputfile.='.bz2'; if ($compression == 'bz') $outputfile.='.bz2';
$outputerror = $outputfile.'.err'; $outputerror = $outputfile.'.err';
dol_mkdir($conf->admin->dir_output.'/backup'); dol_mkdir($conf->admin->dir_output.'/backup');
// Parameteres execution // Parameteres execution
$command=$cmddump; $command=$cmddump;
if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command
//$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
$param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host; $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host;
$param.=" -u ".$dolibarr_main_db_user; $param.=" -u ".$dolibarr_main_db_user;
if (! empty($dolibarr_main_db_port)) $param.=" -P ".$dolibarr_main_db_port; if (! empty($dolibarr_main_db_port)) $param.=" -P ".$dolibarr_main_db_port;
if (! $_POST["use_transaction"]) $param.=" -l --single-transaction"; if (! GETPOST("use_transaction")) $param.=" -l --single-transaction";
if ($_POST["disable_fk"]) $param.=" -K"; if (GETPOST("disable_fk")) $param.=" -K";
if ($_POST["sql_compat"] && $_POST["sql_compat"] != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat","alpha")); if (GETPOST("sql_compat") && GETPOST("sql_compat") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat","alpha"));
if ($_POST["drop_database"]) $param.=" --add-drop-database"; if (GETPOST("drop_database")) $param.=" --add-drop-database";
if ($_POST["sql_structure"]) if (GETPOST("sql_structure"))
{ {
if ($_POST["drop"]) $param.=" --add-drop-table"; if (GETPOST("drop")) $param.=" --add-drop-table";
} }
else else
{ {
$param.=" -t"; $param.=" -t";
} }
if ($_POST["sql_data"]) if (GETPOST("disable-add-locks")) $param.=" --add-locks=FALSE";
{ if (GETPOST("sql_data"))
$param.=" --tables"; {
if ($_POST["showcolumns"]) $param.=" -c"; $param.=" --tables";
if ($_POST["extended_ins"]) $param.=" -e"; if (GETPOST("showcolumns")) $param.=" -c";
if ($_POST["delayed"]) $param.=" --delayed-insert"; if (GETPOST("extended_ins")) $param.=" -e";
if ($_POST["sql_ignore"]) $param.=" --insert-ignore"; else $param.=" --skip-extended-insert";
if ($_POST["hexforbinary"]) $param.=" --hex-blob"; if (GETPOST("delayed")) $param.=" --delayed-insert";
} if (GETPOST("sql_ignore")) $param.=" --insert-ignore";
else if (GETPOST("hexforbinary")) $param.=" --hex-blob";
{ }
$param.=" -d"; else
} {
$paramcrypted=$param; $param.=" -d"; // No row information (no data)
$paramclear=$param; }
if (! empty($dolibarr_main_db_pass)) $param.=" --default-character-set=utf8"; // We always save output into utf8 charset
{ $paramcrypted=$param;
$paramcrypted.=" -p".preg_replace('/./i','*',$dolibarr_main_db_pass); $paramclear=$param;
$paramclear.=" -p".$dolibarr_main_db_pass; if (! empty($dolibarr_main_db_pass))
} {
$paramcrypted.=' -p"'.preg_replace('/./i','*',$dolibarr_main_db_pass).'"';
$paramclear.=' -p"'.str_replace('"','\"',$dolibarr_main_db_pass).'"';
}
print '<b>'.$langs->trans("RunCommandSummary").':</b><br>'."\n"; print '<b>'.$langs->trans("RunCommandSummary").':</b><br>'."\n";
print '<textarea rows="'.ROWS_2.'" cols="120">'.$command." ".$paramcrypted.'</textarea><br>'."\n"; print '<textarea rows="'.ROWS_2.'" cols="120">'.$command." ".$paramcrypted.'</textarea><br>'."\n";
print '<br>';
//print $paramclear;
print '<br>'; // Now run command and show result
print '<b>'.$langs->trans("BackupResult").':</b> ';
$errormsg='';
// Now run command and show result $result=dol_mkdir($outputdir);
print '<b>'.$langs->trans("BackupResult").':</b> ';
$errormsg=''; // Debut appel methode execution
$fullcommandcrypted=$command." ".$paramcrypted." 2>&1";
$fullcommandclear=$command." ".$paramclear." 2>&1";
if ($compression == 'none') $handle = fopen($outputfile, 'w');
if ($compression == 'gz') $handle = gzopen($outputfile, 'w');
if ($compression == 'bz') $handle = bzopen($outputfile, 'w');
$result=dol_mkdir($outputdir); if ($handle)
{
// Debut appel methode execution $ok=0;
$fullcommandcrypted=$command." ".$paramcrypted." 2>&1"; dol_syslog("Run command ".$fullcommandcrypted);
$fullcommandclear=$command." ".$paramclear." 2>&1"; $handlein = popen($fullcommandclear, 'r');
if ($compression == 'none') $handle = fopen($outputfile, 'w'); while (!feof($handlein))
if ($compression == 'gz') $handle = gzopen($outputfile, 'w'); {
if ($compression == 'bz') $handle = bzopen($outputfile, 'w'); $read = fgets($handlein);
fwrite($handle,$read);
if ($handle)
{
$ok=0;
dol_syslog("Run command ".$fullcommandcrypted);
$handlein = popen($fullcommandclear, 'r');
while (!feof($handlein))
{
$read = fgets($handlein);
fwrite($handle,$read);
if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1; if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1;
elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1; elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1;
} }
pclose($handlein); pclose($handlein);
if ($compression == 'none') fclose($handle); if ($compression == 'none') fclose($handle);
if ($compression == 'gz') gzclose($handle); if ($compression == 'gz') gzclose($handle);
if ($compression == 'bz') bzclose($handle); if ($compression == 'bz') bzclose($handle);
if (! empty($conf->global->MAIN_UMASK)) if (! empty($conf->global->MAIN_UMASK))
@chmod($outputfile, octdec($conf->global->MAIN_UMASK)); @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
} }
else else
{ {
$langs->load("errors"); $langs->load("errors");
dol_syslog("Failed to open file ".$outputfile,LOG_ERR); dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
$errormsg=$langs->trans("ErrorFailedToWriteInDir"); $errormsg=$langs->trans("ErrorFailedToWriteInDir");
} }
// Get errorstring
if ($compression == 'none') $handle = fopen($outputfile, 'r'); // Get errorstring
if ($compression == 'gz') $handle = gzopen($outputfile, 'r'); if ($compression == 'none') $handle = fopen($outputfile, 'r');
if ($compression == 'bz') $handle = bzopen($outputfile, 'r'); if ($compression == 'gz') $handle = gzopen($outputfile, 'r');
if ($handle) if ($compression == 'bz') $handle = bzopen($outputfile, 'r');
{ if ($handle)
// Get 2048 first chars of error message. {
$errormsg = fgets($handle,2048); // Get 2048 first chars of error message.
// Close file $errormsg = fgets($handle,2048);
if ($compression == 'none') fclose($handle); // Close file
if ($compression == 'gz') gzclose($handle); if ($compression == 'none') fclose($handle);
if ($compression == 'bz') bzclose($handle); if ($compression == 'gz') gzclose($handle);
if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg=''; // Pas erreur if ($compression == 'bz') bzclose($handle);
else if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg=''; // Pas erreur
{ else
// Renommer fichier sortie en fichier erreur {
//print "$outputfile -> $outputerror"; // Renommer fichier sortie en fichier erreur
@dol_delete_file($outputerror,1); //print "$outputfile -> $outputerror";
@rename($outputfile,$outputerror); @dol_delete_file($outputerror,1);
// Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide @rename($outputfile,$outputerror);
if (! $errormsg) $errormsg=$langs->trans("ErrorFailedToRunExternalCommand"); // Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide
} if (! $errormsg)
} {
// Fin execution commande $langs->load("errors");
$errormsg=$langs->trans("ErrorFailedToRunExternalCommand");
}
}
}
// Fin execution commande
}
if ($what == 'mysqlnobin')
{
$outputdir = $conf->admin->dir_output.'/backup';
$outputfile = $outputdir.'/'.$file;
$outputfiletemp = $outputfile.'-TMP.sql';
// for compression format, we add extension
$compression=GETPOST('compression') ? GETPOST('compression','alpha') : 'none';
if ($compression == 'gz') $outputfile.='.gz';
if ($compression == 'bz') $outputfile.='.bz2';
$outputerror = $outputfile.'.err';
dol_mkdir($conf->admin->dir_output.'/backup');
if ($compression == 'gz' or $compression == 'bz')
{
backup_tables($outputfiletemp);
dol_compress_file($outputfiletemp, $outputfile, $compression);
unlink($outputfiletemp);
}
else
{
backup_tables($outputfile);
}
} }
// POSTGRESQL // POSTGRESQL
if ($what == 'postgresql') if ($what == 'postgresql')
{ {
$cmddump=$_POST["postgresqldump"]; $cmddump=GETPOST("postgresqldump"); // Do not sanitize here with 'alpha', will be sanitize later by escapeshellarg
if ($cmddump) if ($cmddump)
{ {
dolibarr_set_const($db, 'SYSTEMTOOLS_POSTGRESQLDUMP', $cmddump,'chaine',0,'',$conf->entity); dolibarr_set_const($db, 'SYSTEMTOOLS_POSTGRESQLDUMP', $cmddump,'chaine',0,'',$conf->entity);
} }
$outputdir = $conf->admin->dir_output.'/backup'; $outputdir = $conf->admin->dir_output.'/backup';
$outputfile = $outputdir.'/'.$file; $outputfile = $outputdir.'/'.$file;
// for compression format, we add extension // for compression format, we add extension
$compression=isset($_POST['compression']) ? $_POST['compression'] : 'none'; $compression=GETPOST('compression') ? GETPOST('compression','alpha') : 'none';
if ($compression == 'gz') $outputfile.='.gz'; if ($compression == 'gz') $outputfile.='.gz';
if ($compression == 'bz') $outputfile.='.bz2'; if ($compression == 'bz') $outputfile.='.bz2';
$outputerror = $outputfile.'.err'; $outputerror = $outputfile.'.err';
dol_mkdir($conf->admin->dir_output.'/backup'); dol_mkdir($conf->admin->dir_output.'/backup');
// Parameteres execution // Parameteres execution
$command=$cmddump; $command=$cmddump;
if (preg_match("/\s/",$command)) $command=$command=escapeshellarg($command); // Use quotes on command if (preg_match("/\s/",$command)) $command=$command=escapeshellarg($command); // Use quotes on command
//$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
$param=" --no-tablespaces --inserts -h ".$dolibarr_main_db_host; $param=" --no-tablespaces --inserts -h ".$dolibarr_main_db_host;
$param.=" -U ".$dolibarr_main_db_user; $param.=" -U ".$dolibarr_main_db_user;
if (! empty($dolibarr_main_db_port)) $param.=" -p ".$dolibarr_main_db_port; if (! empty($dolibarr_main_db_port)) $param.=" -p ".$dolibarr_main_db_port;
if ($_POST["sql_compat"] && $_POST["sql_compat"] == 'ANSI') $param.=" --disable-dollar-quoting"; if (GETPOST("sql_compat") && GETPOST("sql_compat") == 'ANSI') $param.=" --disable-dollar-quoting";
if ($_POST["drop_database"]) $param.=" -c -C"; if (GETPOST("drop_database")) $param.=" -c -C";
if ($_POST["sql_structure"]) if (GETPOST("sql_structure"))
{ {
if ($_POST["drop"]) $param.=" --add-drop-table"; if (GETPOST("drop")) $param.=" --add-drop-table";
if (empty($_POST["sql_data"])) $param.=" -s"; if (! GETPOST("sql_data")) $param.=" -s";
} }
if ($_POST["sql_data"]) if (GETPOST("sql_data"))
{ {
if (empty($_POST["sql_structure"])) $param.=" -a"; if (! GETPOST("sql_structure")) $param.=" -a";
if ($_POST["showcolumns"]) $param.=" -c"; if (GETPOST("showcolumns")) $param.=" -c";
} }
$param.=' -f "'.$outputfile.'"'; $param.=' -f "'.$outputfile.'"';
//if ($compression == 'none') //if ($compression == 'none')
if ($compression == 'gz') $param.=' -Z 9'; if ($compression == 'gz') $param.=' -Z 9';
//if ($compression == 'bz') //if ($compression == 'bz')
$paramcrypted=$param; $paramcrypted=$param;
$paramclear=$param; $paramclear=$param;
if (! empty($dolibarr_main_db_pass)) /*if (! empty($dolibarr_main_db_pass))
{ {
//$paramcrypted.=" -W".preg_replace('/./i','*',$dolibarr_main_db_pass); $paramcrypted.=" -W".preg_replace('/./i','*',$dolibarr_main_db_pass);
//$paramclear.=" -W".$dolibarr_main_db_pass; $paramclear.=" -W".$dolibarr_main_db_pass;
} }*/
$paramcrypted.=" -w ".$dolibarr_main_db_name; $paramcrypted.=" -w ".$dolibarr_main_db_name;
$paramclear.=" -w ".$dolibarr_main_db_name; $paramclear.=" -w ".$dolibarr_main_db_name;
print $langs->trans("RunCommandSummaryToLaunch").':<br>'."\n"; print $langs->trans("RunCommandSummaryToLaunch").':<br>'."\n";
print '<textarea rows="'.ROWS_3.'" cols="120">'.$command." ".$paramcrypted.'</textarea><br>'."\n"; print '<textarea rows="'.ROWS_3.'" cols="120">'.$command." ".$paramcrypted.'</textarea><br>'."\n";
print '<br>'; print '<br>';
// Now show to ask to run command // Now show to ask to run command
print $langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user); print $langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user);
print '<br>'; print '<br>';
print '<br>'; print '<br>';
$what=''; $what='';
} }
@@ -288,34 +335,189 @@ if ($what == 'postgresql')
// Si on a demande une generation // Si on a demande une generation
if ($what) if ($what)
{ {
if ($errormsg) if ($errormsg)
{ {
print '<div class="error">'.$langs->trans("Error")." : ".$errormsg.'</div>'; print '<div class="error">'.$langs->trans("Error")." : ".$errormsg.'</div>';
// print '<a href="'.DOL_URL_ROOT.$relativepatherr.'">'.$langs->trans("DownloadErrorFile").'</a><br>'; // print '<a href="'.DOL_URL_ROOT.$relativepatherr.'">'.$langs->trans("DownloadErrorFile").'</a><br>';
print '<br>'; print '<br>';
print '<br>'; print '<br>';
} }
else else
{ {
print '<div class="ok">'; print '<div class="ok">';
print $langs->trans("BackupFileSuccessfullyCreated").'.<br>'; print $langs->trans("BackupFileSuccessfullyCreated").'.<br>';
print $langs->trans("YouCanDownloadBackupFile"); print $langs->trans("YouCanDownloadBackupFile");
print '</div>'; print '</div>';
print '<br>'; print '<br>';
} }
} }
$result=$formfile->show_documents('systemtools','backup',$conf->admin->dir_output.'/backup',$_SERVER['PHP_SELF'],0,1,'',1,0,0,54,0,'',$langs->trans("PreviousDumpFiles")); $filearray=dol_dir_list($conf->admin->dir_output.'/backup','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1);
$result=$formfile->list_of_documents($filearray,null,'systemtools','',1,'backup/',1,0,($langs->trans("NoBackupFileAvailable").'<br>'.$langs->trans("ToBuildBackupFileClickHere",DOL_URL_ROOT.'/admin/tools/dolibarr_export.php')),0,$langs->trans("PreviousDumpFiles"));
if ($result == 0)
{
print $langs->trans("NoBackupFileAvailable").'<br>';
print $langs->trans("ToBuildBackupFileClickHere",DOL_URL_ROOT.'/admin/tools/dolibarr_export.php').'<br>';
}
print '<br>'; print '<br>';
$time_end = time(); $time_end = time();
llxFooter('$Date: 2011/08/03 00:45:43 $ - $Revision: 1.45 $'); llxFooter();
$db->close();
// MYSQL NO BINARIES (only php)
/** Backup the db OR just a table without mysqldump binary (does not require any exec permission)
* Author: David Walsh (http://davidwalsh.name/backup-mysql-database-php)
* Updated and enhanced by Stephen Larroque (lrq3000) and by the many commentators from the blog
*
* @param string $outputfile Output file name
* @param string $tables Table name or '*' for all
* @return int <0 if KO, >0 if OK
*/
function backup_tables($outputfile, $tables='*')
{
global $db, $langs;
global $errormsg;
// Set to UTF-8
$db->query('SET NAMES utf8');
$db->query('SET CHARACTER SET utf8');
//get all of the tables
if ($tables == '*')
{
$tables = array();
$result = $db->query('SHOW FULL TABLES WHERE Table_type = \'BASE TABLE\'');
while($row = $db->fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
//cycle through
$handle = fopen($outputfile, 'w+');
if (fwrite($handle, '') === FALSE)
{
$langs->load("errors");
dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
$errormsg=$langs->trans("ErrorFailedToWriteInDir");
return -1;
}
// Print headers and global mysql config vars
$sqlhead = '';
$sqlhead .= "-- ".$db->label." dump via php
--
-- Host: ".$db->db->host_info." Database: ".$db->database_name."
-- ------------------------------------------------------
-- Server version ".$db->db->server_info."
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
";
fwrite($handle, $sqlhead);
// Process each table and print their definition + their datas
foreach($tables as $table)
{
// Saving the table structure
fwrite($handle, "--\n-- Table structure for table `".$table."`\n--\n\n");
fwrite($handle,"DROP TABLE IF EXISTS `".$table."`;\n");
fwrite($handle,"/*!40101 SET @saved_cs_client = @@character_set_client */;\n");
fwrite($handle,"/*!40101 SET character_set_client = utf8 */;\n");
$resqldrop=$db->query('SHOW CREATE TABLE '.$table);
$row2 = $db->fetch_row($resqldrop);
fwrite($handle,$row2[1].";\n");
fwrite($handle,"/*!40101 SET character_set_client = @saved_cs_client */;\n\n");
// Dumping the data (locking the table and disabling the keys check while doing the process)
fwrite($handle, "--\n-- Dumping data for table `".$table."`\n--\n\n");
fwrite($handle, "LOCK TABLES `".$table."` WRITE;\n");
fwrite($handle, "/*!40000 ALTER TABLE `".$table."` DISABLE KEYS */;\n");
$sql='SELECT * FROM '.$table;
$result = $db->query($sql);
$num_fields = $db->num_rows($result);
while($row = $db->fetch_row($result)) {
// For each row of data we print a line of INSERT
fwrite($handle,'INSERT INTO `'.$table.'` VALUES (');
$columns = count($row);
$rowsarr = array();
for($j=0; $j<$columns; $j++) {
// Processing each columns of the row to ensure that we correctly save the value (eg: add quotes for string - in fact we add quotes for everything, it's easier)
if ($row[$j] == null and !is_string($row[$j])) {
// IMPORTANT: if the field is NULL we set it NULL
$row[$j] = 'NULL';
} elseif(is_string($row[$j]) and $row[$j] == '') {
// if it's an empty string, we set it as an empty string
$row[$j] = "''";
} elseif(is_numeric($row[$j])) {
// if it's a number, we return it as-is
$row[$j] = $row[$j];
} else { // else for all other cases we escape the value and put quotes around
$row[$j] = addslashes($row[$j]);
$row[$j] = preg_replace("#\n#", "\\n", $row[$j]);
$row[$j] = "'".$row[$j]."'";
}
}
fwrite($handle,implode(',', $row).");\n");
}
fwrite($handle, "/*!40000 ALTER TABLE `".$table."` ENABLE KEYS */;\n"); // Enabling back the keys/index checking
fwrite($handle, "UNLOCK TABLES;\n"); // Unlocking the tables
fwrite($handle,"\n\n\n");
}
/* Backup Procedure structure*/
/*
$result = $db->query('SHOW PROCEDURE STATUS');
if ($db->num_rows($result) > 0)
{
while ($row = $db->fetch_row($result)) { $procedures[] = $row[1]; }
foreach($procedures as $proc)
{
fwrite($handle,"DELIMITER $$\n\n");
fwrite($handle,"DROP PROCEDURE IF EXISTS '$name'.'$proc'$$\n");
$resqlcreateproc=$db->query("SHOW CREATE PROCEDURE '$proc'");
$row2 = $db->fetch_row($resqlcreateproc);
fwrite($handle,"\n".$row2[2]."$$\n\n");
fwrite($handle,"DELIMITER ;\n\n");
}
}
*/
/* Backup Procedure structure*/
// Write the footer (restore the previous database settings)
$sqlfooter='';
$sqlfooter.="
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on ".date('Y-m-d G-i-s');
fwrite($handle, $sqlfooter);
fclose($handle);
return 1;
}
?> ?>