PageRenderTime 67ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/admin/tools/export.php

https://github.com/asterix14/dolibarr
PHP | 508 lines | 334 code | 73 blank | 101 comment | 105 complexity | 92d0e82f05a23c85bc3300655fecfa18 MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2006-2010 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /**
  19. * \file htdocs/admin/tools/export.php
  20. * \brief Page to export a database into a dump file
  21. */
  22. require("../../main.inc.php");
  23. require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
  24. require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
  25. require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php");
  26. $what=$_REQUEST["what"];
  27. $export_type=$_REQUEST["export_type"];
  28. $file=isset($_POST['filename_template']) ? $_POST['filename_template'] : '';
  29. $langs->load("admin");
  30. if (! $user->admin) accessforbidden();
  31. if ($file && ! $what)
  32. {
  33. //print DOL_URL_ROOT.'/dolibarr_export.php';
  34. header("Location: ".DOL_URL_ROOT.'/admin/tools/dolibarr_export.php?msg='.urlencode($langs->trans("ErrorFieldRequired",$langs->transnoentities("ExportMethod"))));
  35. /*
  36. print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("ExportMethod")).'</div>';
  37. print '<br>';
  38. */
  39. exit;
  40. }
  41. /*
  42. * View
  43. */
  44. llxHeader('','','EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad');
  45. $form=new Form($db);
  46. $formfile = new FormFile($db);
  47. print_fiche_titre($langs->trans("Backup"),'','setup');
  48. $ExecTimeLimit=600;
  49. if (!empty($ExecTimeLimit)) {
  50. // Cette page peut etre longue. On augmente le delai autorise.
  51. // Ne fonctionne que si on est pas en safe_mode.
  52. $err=error_reporting();
  53. error_reporting(0); // Disable all errors
  54. //error_reporting(E_ALL);
  55. @set_time_limit($ExecTimeLimit); // Need more than 240 on Windows 7/64
  56. error_reporting($err);
  57. }
  58. if (!empty($MemoryLimit)) {
  59. @ini_set('memory_limit', $MemoryLimit);
  60. }
  61. // Start with empty buffer
  62. $dump_buffer = '';
  63. $dump_buffer_len = 0;
  64. // We send fake headers to avoid browser timeout when buffering
  65. $time_start = time();
  66. // MYSQL
  67. if ($what == 'mysql')
  68. {
  69. $cmddump=$_POST["mysqldump"];
  70. if ($cmddump)
  71. {
  72. dolibarr_set_const($db, 'SYSTEMTOOLS_MYSQLDUMP', $cmddump,'chaine',0,'',$conf->entity);
  73. }
  74. $outputdir = $conf->admin->dir_output.'/backup';
  75. $outputfile = $outputdir.'/'.$file;
  76. // for compression format, we add extension
  77. $compression=isset($_POST['compression']) ? $_POST['compression'] : 'none';
  78. if ($compression == 'gz') $outputfile.='.gz';
  79. if ($compression == 'bz') $outputfile.='.bz2';
  80. $outputerror = $outputfile.'.err';
  81. dol_mkdir($conf->admin->dir_output.'/backup');
  82. // Parameteres execution
  83. $command=$cmddump;
  84. if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command
  85. //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
  86. $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host;
  87. $param.=" -u ".$dolibarr_main_db_user;
  88. if (! empty($dolibarr_main_db_port)) $param.=" -P ".$dolibarr_main_db_port;
  89. if (! $_POST["use_transaction"]) $param.=" -l --single-transaction";
  90. if ($_POST["disable_fk"]) $param.=" -K";
  91. if ($_POST["sql_compat"] && $_POST["sql_compat"] != 'NONE') $param.=" --compatible=".$_POST["sql_compat"];
  92. if ($_POST["drop_database"]) $param.=" --add-drop-database";
  93. if ($_POST["sql_structure"])
  94. {
  95. if ($_POST["drop"]) $param.=" --add-drop-table";
  96. }
  97. else
  98. {
  99. $param.=" -t";
  100. }
  101. if ($_POST["sql_data"])
  102. {
  103. $param.=" --tables";
  104. if ($_POST["showcolumns"]) $param.=" -c";
  105. if ($_POST["extended_ins"]) $param.=" -e";
  106. if ($_POST["delayed"]) $param.=" --delayed-insert";
  107. if ($_POST["sql_ignore"]) $param.=" --insert-ignore";
  108. if ($_POST["hexforbinary"]) $param.=" --hex-blob";
  109. }
  110. else
  111. {
  112. $param.=" -d";
  113. }
  114. $paramcrypted=$param;
  115. $paramclear=$param;
  116. if (! empty($dolibarr_main_db_pass))
  117. {
  118. $paramcrypted.=" -p".preg_replace('/./i','*',$dolibarr_main_db_pass);
  119. $paramclear.=" -p".$dolibarr_main_db_pass;
  120. }
  121. print '<b>'.$langs->trans("RunCommandSummary").':</b><br>'."\n";
  122. print '<textarea rows="'.ROWS_2.'" cols="120">'.$command." ".$paramcrypted.'</textarea><br>'."\n";
  123. print '<br>';
  124. // Now run command and show result
  125. print '<b>'.$langs->trans("BackupResult").':</b> ';
  126. $errormsg='';
  127. $result=dol_mkdir($outputdir);
  128. // Debut appel methode execution
  129. $fullcommandcrypted=$command." ".$paramcrypted." 2>&1";
  130. $fullcommandclear=$command." ".$paramclear." 2>&1";
  131. if ($compression == 'none') $handle = fopen($outputfile, 'w');
  132. if ($compression == 'gz') $handle = gzopen($outputfile, 'w');
  133. if ($compression == 'bz') $handle = bzopen($outputfile, 'w');
  134. if ($handle)
  135. {
  136. $ok=0;
  137. dol_syslog("Run command ".$fullcommandcrypted);
  138. $handlein = popen($fullcommandclear, 'r');
  139. while (!feof($handlein))
  140. {
  141. $read = fgets($handlein);
  142. fwrite($handle,$read);
  143. if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1;
  144. elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1;
  145. }
  146. pclose($handlein);
  147. if ($compression == 'none') fclose($handle);
  148. if ($compression == 'gz') gzclose($handle);
  149. if ($compression == 'bz') bzclose($handle);
  150. if (! empty($conf->global->MAIN_UMASK))
  151. @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
  152. }
  153. else
  154. {
  155. $langs->load("errors");
  156. dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
  157. $errormsg=$langs->trans("ErrorFailedToWriteInDir");
  158. }
  159. // Get errorstring
  160. if ($compression == 'none') $handle = fopen($outputfile, 'r');
  161. if ($compression == 'gz') $handle = gzopen($outputfile, 'r');
  162. if ($compression == 'bz') $handle = bzopen($outputfile, 'r');
  163. if ($handle)
  164. {
  165. // Get 2048 first chars of error message.
  166. $errormsg = fgets($handle,2048);
  167. // Close file
  168. if ($compression == 'none') fclose($handle);
  169. if ($compression == 'gz') gzclose($handle);
  170. if ($compression == 'bz') bzclose($handle);
  171. if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg=''; // Pas erreur
  172. else
  173. {
  174. // Renommer fichier sortie en fichier erreur
  175. //print "$outputfile -> $outputerror";
  176. @dol_delete_file($outputerror,1);
  177. @rename($outputfile,$outputerror);
  178. // Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide
  179. if (! $errormsg)
  180. {
  181. $langs->load("errors");
  182. $errormsg=$langs->trans("ErrorFailedToRunExternalCommand");
  183. }
  184. }
  185. }
  186. // Fin execution commande
  187. }
  188. if ($what == 'mysqlnobin')
  189. {
  190. $outputdir = $conf->admin->dir_output.'/backup';
  191. $outputfile = $outputdir.'/'.$file;
  192. $outputfiletemp = $outputfile.'-TMP.sql';
  193. // for compression format, we add extension
  194. $compression=isset($_POST['compression']) ? $_POST['compression'] : 'none';
  195. if ($compression == 'gz') $outputfile.='.gz';
  196. if ($compression == 'bz') $outputfile.='.bz2';
  197. $outputerror = $outputfile.'.err';
  198. dol_mkdir($conf->admin->dir_output.'/backup');
  199. if ($compression == 'gz' or $compression == 'bz')
  200. {
  201. backup_tables($outputfiletemp);
  202. dol_compress_file($outputfiletemp, $outputfile, $compression);
  203. unlink($outputfiletemp);
  204. }
  205. else
  206. {
  207. backup_tables($outputfile);
  208. }
  209. }
  210. // POSTGRESQL
  211. if ($what == 'postgresql')
  212. {
  213. $cmddump=$_POST["postgresqldump"];
  214. if ($cmddump)
  215. {
  216. dolibarr_set_const($db, 'SYSTEMTOOLS_POSTGRESQLDUMP', $cmddump,'chaine',0,'',$conf->entity);
  217. }
  218. $outputdir = $conf->admin->dir_output.'/backup';
  219. $outputfile = $outputdir.'/'.$file;
  220. // for compression format, we add extension
  221. $compression=isset($_POST['compression']) ? $_POST['compression'] : 'none';
  222. if ($compression == 'gz') $outputfile.='.gz';
  223. if ($compression == 'bz') $outputfile.='.bz2';
  224. $outputerror = $outputfile.'.err';
  225. dol_mkdir($conf->admin->dir_output.'/backup');
  226. // Parameteres execution
  227. $command=$cmddump;
  228. if (preg_match("/\s/",$command)) $command=$command=escapeshellarg($command); // Use quotes on command
  229. //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
  230. $param=" --no-tablespaces --inserts -h ".$dolibarr_main_db_host;
  231. $param.=" -U ".$dolibarr_main_db_user;
  232. if (! empty($dolibarr_main_db_port)) $param.=" -p ".$dolibarr_main_db_port;
  233. if ($_POST["sql_compat"] && $_POST["sql_compat"] == 'ANSI') $param.=" --disable-dollar-quoting";
  234. if ($_POST["drop_database"]) $param.=" -c -C";
  235. if ($_POST["sql_structure"])
  236. {
  237. if ($_POST["drop"]) $param.=" --add-drop-table";
  238. if (empty($_POST["sql_data"])) $param.=" -s";
  239. }
  240. if ($_POST["sql_data"])
  241. {
  242. if (empty($_POST["sql_structure"])) $param.=" -a";
  243. if ($_POST["showcolumns"]) $param.=" -c";
  244. }
  245. $param.=' -f "'.$outputfile.'"';
  246. //if ($compression == 'none')
  247. if ($compression == 'gz') $param.=' -Z 9';
  248. //if ($compression == 'bz')
  249. $paramcrypted=$param;
  250. $paramclear=$param;
  251. /*if (! empty($dolibarr_main_db_pass))
  252. {
  253. $paramcrypted.=" -W".preg_replace('/./i','*',$dolibarr_main_db_pass);
  254. $paramclear.=" -W".$dolibarr_main_db_pass;
  255. }*/
  256. $paramcrypted.=" -w ".$dolibarr_main_db_name;
  257. $paramclear.=" -w ".$dolibarr_main_db_name;
  258. print $langs->trans("RunCommandSummaryToLaunch").':<br>'."\n";
  259. print '<textarea rows="'.ROWS_3.'" cols="120">'.$command." ".$paramcrypted.'</textarea><br>'."\n";
  260. print '<br>';
  261. // Now show to ask to run command
  262. print $langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user);
  263. print '<br>';
  264. print '<br>';
  265. $what='';
  266. }
  267. // Si on a demande une generation
  268. if ($what)
  269. {
  270. if ($errormsg)
  271. {
  272. print '<div class="error">'.$langs->trans("Error")." : ".$errormsg.'</div>';
  273. // print '<a href="'.DOL_URL_ROOT.$relativepatherr.'">'.$langs->trans("DownloadErrorFile").'</a><br>';
  274. print '<br>';
  275. print '<br>';
  276. }
  277. else
  278. {
  279. print '<div class="ok">';
  280. print $langs->trans("BackupFileSuccessfullyCreated").'.<br>';
  281. print $langs->trans("YouCanDownloadBackupFile");
  282. print '</div>';
  283. print '<br>';
  284. }
  285. }
  286. $result=$formfile->show_documents('systemtools','backup',$conf->admin->dir_output.'/backup',$_SERVER['PHP_SELF'],0,1,'',1,0,0,54,0,'',$langs->trans("PreviousDumpFiles"));
  287. if ($result == 0)
  288. {
  289. print $langs->trans("NoBackupFileAvailable").'<br>';
  290. print $langs->trans("ToBuildBackupFileClickHere",DOL_URL_ROOT.'/admin/tools/dolibarr_export.php').'<br>';
  291. }
  292. print '<br>';
  293. $time_end = time();
  294. llxFooter();
  295. $db->close();
  296. // MYSQL NO BINARIES (only php)
  297. /** Backup the db OR just a table without mysqldump binary (does not require any exec permission)
  298. * Author: David Walsh (http://davidwalsh.name/backup-mysql-database-php)
  299. * Updated and enhanced by Stephen Larroque (lrq3000) and by the many commentators from the blog
  300. *
  301. * @param string $outputfile Output file name
  302. * @param string $tables Table name or '*' for all
  303. * @return int <0 if KO, >0 if OK
  304. */
  305. function backup_tables($outputfile, $tables='*')
  306. {
  307. global $db, $langs;
  308. global $errormsg;
  309. // Set to UTF-8
  310. $db->query('SET NAMES utf8');
  311. $db->query('SET CHARACTER SET utf8');
  312. //get all of the tables
  313. if ($tables == '*')
  314. {
  315. $tables = array();
  316. $result = $db->query('SHOW FULL TABLES WHERE Table_type = \'BASE TABLE\'');
  317. while($row = $db->fetch_row($result))
  318. {
  319. $tables[] = $row[0];
  320. }
  321. }
  322. else
  323. {
  324. $tables = is_array($tables) ? $tables : explode(',',$tables);
  325. }
  326. //cycle through
  327. $handle = fopen($outputfile, 'w+');
  328. if (fwrite($handle, '') === FALSE)
  329. {
  330. $langs->load("errors");
  331. dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
  332. $errormsg=$langs->trans("ErrorFailedToWriteInDir");
  333. return -1;
  334. }
  335. // Print headers and global mysql config vars
  336. $sqlhead = '';
  337. $sqlhead .= "-- ".$db->label." dump via php
  338. --
  339. -- Host: ".$db->db->host_info." Database: ".$db->database_name."
  340. -- ------------------------------------------------------
  341. -- Server version ".$db->db->server_info."
  342. /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
  343. /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
  344. /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
  345. /*!40101 SET NAMES utf8 */;
  346. /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
  347. /*!40103 SET TIME_ZONE='+00:00' */;
  348. /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
  349. /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
  350. /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
  351. /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
  352. ";
  353. fwrite($handle, $sqlhead);
  354. // Process each table and print their definition + their datas
  355. foreach($tables as $table)
  356. {
  357. // Saving the table structure
  358. fwrite($handle, "--\n-- Table structure for table `".$table."`\n--\n\n");
  359. fwrite($handle,"DROP TABLE IF EXISTS `".$table."`;\n");
  360. fwrite($handle,"/*!40101 SET @saved_cs_client = @@character_set_client */;\n");
  361. fwrite($handle,"/*!40101 SET character_set_client = utf8 */;\n");
  362. $resqldrop=$db->query('SHOW CREATE TABLE '.$table);
  363. $row2 = $db->fetch_row($resqldrop);
  364. fwrite($handle,$row2[1].";\n");
  365. fwrite($handle,"/*!40101 SET character_set_client = @saved_cs_client */;\n\n");
  366. // Dumping the data (locking the table and disabling the keys check while doing the process)
  367. fwrite($handle, "--\n-- Dumping data for table `".$table."`\n--\n\n");
  368. fwrite($handle, "LOCK TABLES `".$table."` WRITE;\n");
  369. fwrite($handle, "/*!40000 ALTER TABLE `".$table."` DISABLE KEYS */;\n");
  370. $sql='SELECT * FROM '.$table;
  371. $result = $db->query($sql);
  372. $num_fields = $db->num_rows($result);
  373. while($row = $db->fetch_row($result)) {
  374. // For each row of data we print a line of INSERT
  375. fwrite($handle,'INSERT INTO `'.$table.'` VALUES (');
  376. $columns = count($row);
  377. $rowsarr = array();
  378. for($j=0; $j<$columns; $j++) {
  379. // 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)
  380. if ($row[$j] == null and !is_string($row[$j])) {
  381. // IMPORTANT: if the field is NULL we set it NULL
  382. $row[$j] = 'NULL';
  383. } elseif(is_string($row[$j]) and $row[$j] == '') {
  384. // if it's an empty string, we set it as an empty string
  385. $row[$j] = "''";
  386. } elseif(is_numeric($row[$j])) {
  387. // if it's a number, we return it as-is
  388. $row[$j] = $row[$j];
  389. } else { // else for all other cases we escape the value and put quotes around
  390. $row[$j] = addslashes($row[$j]);
  391. $row[$j] = preg_replace("#\n#", "\\n", $row[$j]);
  392. $row[$j] = "'".$row[$j]."'";
  393. }
  394. }
  395. fwrite($handle,implode(',', $row).");\n");
  396. }
  397. fwrite($handle, "/*!40000 ALTER TABLE `".$table."` ENABLE KEYS */;\n"); // Enabling back the keys/index checking
  398. fwrite($handle, "UNLOCK TABLES;\n"); // Unlocking the tables
  399. fwrite($handle,"\n\n\n");
  400. }
  401. /* Backup Procedure structure*/
  402. /*
  403. $result = $db->query('SHOW PROCEDURE STATUS');
  404. if ($db->num_rows($result) > 0)
  405. {
  406. while ($row = $db->fetch_row($result)) { $procedures[] = $row[1]; }
  407. foreach($procedures as $proc)
  408. {
  409. fwrite($handle,"DELIMITER $$\n\n");
  410. fwrite($handle,"DROP PROCEDURE IF EXISTS '$name'.'$proc'$$\n");
  411. $resqlcreateproc=$db->query("SHOW CREATE PROCEDURE '$proc'");
  412. $row2 = $db->fetch_row($resqlcreateproc);
  413. fwrite($handle,"\n".$row2[2]."$$\n\n");
  414. fwrite($handle,"DELIMITER ;\n\n");
  415. }
  416. }
  417. */
  418. /* Backup Procedure structure*/
  419. // Write the footer (restore the previous database settings)
  420. $sqlfooter='';
  421. $sqlfooter.="
  422. /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
  423. /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
  424. /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
  425. /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
  426. /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
  427. /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
  428. /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
  429. /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
  430. -- Dump completed on ".date('Y-m-d G-i-s');
  431. fwrite($handle, $sqlfooter);
  432. fclose($handle);
  433. return 1;
  434. }
  435. ?>