skip view when backup (#5102)
[openemr.git] / interface / main / backup.php
blob72545683439d41cb3bfdc62c2558c296f7957da6
1 <?php
3 /**
4 * This script creates a backup tarball, emr_backup.tar, and sends
5 * it to the user's browser for download. The tarball includes:
7 * an OpenEMR database dump (openemr.sql.gz)
8 * the OpenEMR web directory (openemr.tar.gz)
10 * The OpenEMR web directory is important because it includes config-
11 * uration files, patient documents, and possible customizations, and
12 * also because the database structure is dependent on the installed
13 * OpenEMR version.
15 * This script depends on execution of some external programs:
16 * mysqldump & pg_dump. It has been tested with Debian and Ubuntu
17 * Linux and with Windows XP.
19 * DO NOT PRESUME THAT IT WORKS FOR YOU until you have successfully
20 * tested a restore!
22 * @package OpenEMR
23 * @link http://www.open-emr.org
24 * @author Rod Roark <rod@sunsetsystems.com>
25 * @author Bill Cernansky (www.mi-squared.com)
26 * @author Brady Miller <brady.g.miller@gmail.com>
27 * @author Stephen Waite <stephen.waite@cmsvt.com>
28 * @copyright Copyright (c) 2008-2014, 2016, 2021 Rod Roark <rod@sunsetsystems.com>
29 * @copyright Copyright (c) 2018 Brady Miller <brady.g.miller@gmail.com>
30 * @copyright Copyright (c) 2019 Stephen Waite <stephen.waite@cmsvt.com>
31 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
34 set_time_limit(0);
35 require_once("../globals.php");
36 require_once("$srcdir/layout.inc.php");
37 require_once("$srcdir/patient.inc");
39 use OpenEMR\Common\Acl\AclMain;
40 use OpenEMR\Common\Csrf\CsrfUtils;
41 use OpenEMR\Common\Logging\EventAuditLogger;
42 use OpenEMR\Core\Header;
44 if (!empty($_POST)) {
45 if (!CsrfUtils::verifyCsrfToken($_POST["csrf_token_form"])) {
46 CsrfUtils::csrfNotVerified();
50 if (!extension_loaded('zlib')) {
51 die('Abort ' . basename(__FILE__) . ' : Missing zlib extensions');
54 if (!function_exists('gzopen') && function_exists('gzopen64')) {
55 function gzopen($filename, $mode, $use_include_path = 0)
57 return gzopen64($filename, $mode, $use_include_path);
61 if (!AclMain::aclCheckCore('admin', 'super')) {
62 die(xlt('Not authorized'));
65 // When automatically including lists used in selected layouts, these lists are not included.
66 $excluded_lists = array(
67 'allergy_issue_list',
68 'boolean',
69 'education_level',
70 'ethrace',
71 'Gender',
72 'genhivhist',
73 'occupations',
74 'Relation_to_Client',
75 'sex',
76 'Sexual_Orientation',
77 'yesno',
80 $BTN_TEXT_CREATE = xl('Create Backup');
81 $BTN_TEXT_EXPORT = xl('Export Configuration');
82 $BTN_TEXT_IMPORT = xl('Import Configuration');
83 $BTN_TEXT_LOG = xl('Backup/Delete Log Data');
84 // ViSolve: Create Log Backup button
85 $BTN_TEXT_CREATE_EVENTLOG = xl('Create Eventlog Backup');
87 $form_step = isset($_POST['form_step']) ? trim($_POST['form_step']) : '0';
88 $form_status = isset($_POST['form_status' ]) ? trim($_POST['form_status' ]) : '';
90 if (!empty($_POST['form_export'])) {
91 $form_step = 101;
94 if (!empty($_POST['form_import'])) {
95 $form_step = 201;
98 //ViSolve: Assign Unique Number for the Log Creation
99 if (!empty($_POST['form_backup'])) {
100 $form_step = 301;
103 if (!empty($_POST['form_logarchive'])) {
104 $form_step = 401;
107 // When true the current form will submit itself after a brief pause.
108 $auto_continue = false;
110 # set up main paths
111 $backup_file_prefix = "emr_backup";
112 $backup_file_suffix = ".tar";
113 $TMP_BASE = $GLOBALS['temporary_files_dir'] . "/openemr_web_backup";
114 $BACKUP_DIR = $TMP_BASE . "/emr_backup";
115 $TAR_FILE_PATH = $TMP_BASE . DIRECTORY_SEPARATOR . $backup_file_prefix . $backup_file_suffix;
116 $EXPORT_FILE = $GLOBALS['temporary_files_dir'] . "/openemr_config.sql";
117 $MYSQL_PATH = $GLOBALS['mysql_bin_dir'];
118 $PERL_PATH = $GLOBALS['perl_bin_dir'];
120 if ($form_step == 6) {
121 header("Pragma: public");
122 header("Expires: 0");
123 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
124 header("Content-Type: application/force-download");
125 header("Content-Length: " . filesize($TAR_FILE_PATH));
126 header("Content-Disposition: attachment; filename=" . basename($TAR_FILE_PATH));
127 header("Content-Description: File Transfer");
129 if (is_file($TAR_FILE_PATH)) {
130 $chunkSize = 1024 * 1024;
131 $handle = fopen($TAR_FILE_PATH, 'rb');
132 while (!feof($handle)) {
133 $buffer = fread($handle, $chunkSize);
134 echo $buffer;
135 ob_flush();
136 flush();
138 fclose($handle);
139 } else {
140 obliterate_dir($BACKUP_DIR);
141 $dieMsg = xlt("Backup Failed missing generated file");
142 die($dieMsg);
144 unlink($TAR_FILE_PATH);
145 obliterate_dir($BACKUP_DIR);
146 exit(0);
149 if ($form_step == 104) {
150 header("Pragma: public");
151 header("Expires: 0");
152 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
153 header("Content-Type: application/force-download");
154 header("Content-Length: " . filesize($EXPORT_FILE));
155 header("Content-Disposition: attachment; filename=" . basename($EXPORT_FILE));
156 header("Content-Description: File Transfer");
157 readfile($EXPORT_FILE);
158 unlink($EXPORT_FILE);
159 exit(0);
162 // CSV export of lists.
164 if ($form_step == 102.1) {
165 if (is_array($_POST['form_sel_lists'] ?? '')) {
166 header("Pragma: public");
167 header("Expires: 0");
168 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
169 header("Content-Type: application/force-download; charset=utf-8");
170 header("Content-Disposition: attachment; filename=lists.csv");
171 header("Content-Description: File Transfer");
172 // Prepend a BOM (Byte Order Mark) header to mark the data as UTF-8. See:
173 // http://stackoverflow.com/questions/155097/microsoft-excel-mangles-diacritics-in-csv-files
174 // http://crashcoursing.blogspot.com/2011/05/exporting-csv-with-special-characters.html
175 echo "\xEF\xBB\xBF";
176 // CSV headers:
177 echo csvEscape(xl('List')) . ',';
178 echo csvEscape(xl('ID')) . ',';
179 echo csvEscape(xl('Title')) . ',';
180 echo csvEscape(xl('Translated')) . ',';
181 echo csvEscape(xl('Order')) . ',';
182 echo csvEscape(xl('Default')) . ',';
183 echo csvEscape(xl('Active')) . ',';
184 echo csvEscape(xl('Global ID')) . ',';
185 echo csvEscape(xl('Notes')) . ',';
186 echo csvEscape(xl('Codes')) . '';
187 echo "\n";
188 foreach ($_POST['form_sel_lists'] as $listid) {
189 $res = sqlStatement(
190 "SELECT * FROM list_options WHERE list_id = ? ORDER BY seq, title",
191 array($listid)
193 while ($row = sqlFetchArray($res)) {
194 $xtitle = xl_list_label($row['title']);
195 if ($xtitle === $row['title']) {
196 $xtitle = '';
198 echo csvEscape($row['list_id']) . ',';
199 echo csvEscape($row['option_id']) . ',';
200 echo csvEscape($row['title']) . ',';
201 echo csvEscape($xtitle) . ',';
202 echo csvEscape($row['seq']) . ',';
203 echo csvEscape($row['is_default']) . ',';
204 echo csvEscape($row['activity']) . ',';
205 echo csvEscape($row['mapping']) . ',';
206 echo csvEscape($row['notes']) . ',';
207 echo csvEscape($row['codes']) . '';
208 echo "\n";
212 exit(0);
215 // CSV export of layouts.
217 if ($form_step == 102.2) {
218 if (is_array($_POST['form_sel_layouts'] ?? '')) {
219 header("Pragma: public");
220 header("Expires: 0");
221 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
222 header("Content-Type: application/force-download; charset=utf-8");
223 header("Content-Disposition: attachment; filename=layouts.csv");
224 header("Content-Description: File Transfer");
225 // Prepend a BOM (Byte Order Mark) header to mark the data as UTF-8. See:
226 // http://stackoverflow.com/questions/155097/microsoft-excel-mangles-diacritics-in-csv-files
227 // http://crashcoursing.blogspot.com/2011/05/exporting-csv-with-special-characters.html
228 echo "\xEF\xBB\xBF";
229 // CSV headers:
230 echo csvEscape(xl('Form')) . ',';
231 echo csvEscape(xl('Order')) . ',';
232 echo csvEscape(xl('Source')) . ',';
233 echo csvEscape(xl('Group')) . ',';
234 echo csvEscape(xl('ID')) . ',';
235 echo csvEscape(xl('Label')) . ',';
236 echo csvEscape(xl('Translated')) . ',';
237 echo csvEscape(xl('UOR')) . ',';
238 echo csvEscape(xl('Type')) . ',';
239 echo csvEscape(xl('Width')) . ',';
240 echo csvEscape(xl('Height')) . ',';
241 echo csvEscape(xl('Max')) . ',';
242 echo csvEscape(xl('List')) . ',';
243 echo csvEscape(xl('Label Cols')) . ',';
244 echo csvEscape(xl('Data Cols')) . ',';
245 echo csvEscape(xl('Options')) . ',';
246 echo csvEscape(xl('Description')) . ',';
247 echo csvEscape(xl('Translated')) . ',';
248 echo csvEscape(xl('Conditions')) . '';
249 echo "\n";
250 foreach ($_POST['form_sel_layouts'] as $layoutid) {
251 $res = sqlStatement(
252 "SELECT l.*, p.grp_title FROM layout_options AS l " .
253 "JOIN layout_group_properties AS p ON p.grp_form_id = l.form_id AND " .
254 "p.grp_group_id = l.group_id AND p.grp_activity = 1 " .
255 "WHERE l.form_id = ? ORDER BY l.group_id, l.seq, l.title",
256 array($layoutid)
258 while ($row = sqlFetchArray($res)) {
259 $xtitle = xl_layout_label($row['title']);
260 if ($xtitle === $row['title']) {
261 $xtitle = '';
263 $xdesc = $row['description'];
264 if (substr($xdesc, 0, 1) != '<') {
265 $xdesc = xl_layout_label($xdesc);
267 if ($xdesc === $row['description']) {
268 $xdesc = '';
270 echo csvEscape($row['form_id' ]) . ',';
271 echo csvEscape($row['seq' ]) . ',';
272 echo csvEscape($sources[$row['source']]) . ',';
273 echo csvEscape($row['grp_title' ]) . ',';
274 echo csvEscape($row['field_id' ]) . ',';
275 echo csvEscape($row['title' ]) . ',';
276 echo csvEscape($xtitle) . ',';
277 echo csvEscape($UOR[$row['uor']]) . ',';
278 echo csvEscape($datatypes[$row['data_type']]) . ',';
279 echo csvEscape($row['fld_length' ]) . ',';
280 echo csvEscape($row['fld_rows' ]) . ',';
281 echo csvEscape($row['max_length' ]) . ',';
282 echo csvEscape($row['list_id' ]) . ',';
283 echo csvEscape($row['titlecols' ]) . ',';
284 echo csvEscape($row['datacols' ]) . ',';
285 echo csvEscape($row['edit_options']) . ',';
286 echo csvEscape($row['description' ]) . ',';
287 echo csvEscape($xdesc) . ',';
288 echo csvEscape($row['conditions' ]) . '';
289 echo "\n";
293 exit(0);
296 // CSV export of old log entries.
298 if ($form_step == 402) {
299 if (!empty($_POST['form_end_date'])) {
300 $end_date = DateToYYYYMMDD($_POST['form_end_date']);
301 // This is the "filename" for the Content-Disposition header.
302 $filename = "log_archive_{$end_date}.csv";
304 $outfile = tempnam($GLOBALS['temporary_files_dir'], 'OET');
305 if ($outfile === false) {
306 die("tempnam('" . text($GLOBALS['temporary_files_dir']) . "','OET') failed.\n");
308 $hout = fopen($outfile, "w");
309 $wcount = 0;
311 // Prepend a BOM (Byte Order Mark) header to mark the data as UTF-8. See:
312 // http://stackoverflow.com/questions/155097/microsoft-excel-mangles-diacritics-in-csv-files
313 // http://crashcoursing.blogspot.com/2011/05/exporting-csv-with-special-characters.html
314 $out = "\xEF\xBB\xBF";
315 // CSV headers:
316 $out .= csvEscape(xl('id')) . ',';
317 $out .= csvEscape(xl('date')) . ',';
318 $out .= csvEscape(xl('event')) . ',';
319 $out .= csvEscape(xl('user')) . ',';
320 $out .= csvEscape(xl('groupname')) . ',';
321 $out .= csvEscape(xl('comments')) . ',';
322 $out .= csvEscape(xl('user_notes')) . ',';
323 $out .= csvEscape(xl('patient_id')) . ',';
324 $out .= csvEscape(xl('success')) . ',';
325 $out .= csvEscape(xl('checksum')) . ',';
326 $out .= csvEscape(xl('crt_user')) . '';
327 $out .= "\n";
328 fwrite($hout, $out);
330 // Somewhere there's a memory leak in the ADODB stuff. We do multiple selects to
331 // work around this.
332 $lastid = 0;
333 while (true) {
334 $res = sqlStatementNoLog(
335 "SELECT * FROM `log` WHERE `date` <= ? AND `id` > ? ORDER BY `id` LIMIT 50000",
336 array("$end_date 23:59:59", $lastid)
338 if (!sqlNumRows($res)) {
339 break;
341 while ($row = sqlFetchArray($res)) {
342 $out = csvEscape($row['id' ]) . ',' .
343 csvEscape($row['date' ]) . ',' .
344 csvEscape($row['event' ]) . ',' .
345 csvEscape($row['user' ]) . ',' .
346 csvEscape($row['groupname' ]) . ',' .
347 csvEscape($row['comments' ]) . ',' .
348 csvEscape($row['user_notes']) . ',' .
349 csvEscape($row['patient_id']) . ',' .
350 csvEscape($row['success' ]) . ',' .
351 csvEscape($row['checksum' ]) . ',' .
352 csvEscape($row['crt_user' ]) . '' .
353 "\n";
354 if (!fwrite($hout, $out)) {
355 die("fwrite() failed!");
357 $lastid = $row['id'];
361 fclose($hout);
363 // Do compression if requested (it is!)
364 if (true) {
365 $zip = new ZipArchive();
366 $zippedoutfile = tempnam($GLOBALS['temporary_files_dir'], 'OEZ');
367 if ($zippedoutfile === false) {
368 die("tempnam('" . text($GLOBALS['temporary_files_dir']) . "','OEZ') failed.\n");
370 if ($zip->open($zippedoutfile, ZIPARCHIVE::OVERWRITE) !== true) {
371 die(xlt('Cannot create file') . " '$zipname'\n");
373 if (!$zip->addFile($outfile, $filename)) {
374 die(xlt('Cannot add to archive') . " '$zipname'\n");
376 $zip->close();
377 $filename .= '.zip';
378 unlink($outfile);
379 $outfile = $zippedoutfile;
382 header("Pragma: public");
383 header("Expires: 0");
384 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
385 header("Content-Type: application/force-download; charset=utf-8");
386 header("Content-Disposition: attachment; filename=$filename");
387 header("Content-Description: File Transfer");
388 header("Content-Length: " . filesize($outfile));
389 readfile($outfile);
390 unlink($outfile);
391 } else {
392 die(xlt("End date is missing!"));
394 exit(0);
398 <html>
400 <head>
401 <?php Header::setupHeader(['datetime-picker']); ?>
402 <title><?php echo xlt('Backup'); ?></title>
404 <script>
406 $(function () {
407 $('.datepicker').datetimepicker({
408 <?php $datetimepicker_timepicker = false; ?>
409 <?php $datetimepicker_showseconds = false; ?>
410 <?php $datetimepicker_formatInput = true; ?>
411 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
412 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
416 // Called from export page or log archive page to specify what it will do.
417 // 102 = SQL export of selected tables, lists and layouts
418 // 102.1 = Download selected lists as CSV
419 // 102.2 = download selected layouts as CSV
420 // 402 = CSV export of log archive
421 // 405 = Delete from the log
423 function export_submit(step) {
424 var f = document.forms[0];
425 f.form_step.value = step;
426 top.restoreSession();
427 f.submit();
430 </script>
432 </head>
434 <body class="body_top">
435 <center>
436 &nbsp;<br />
437 <form method='post' action='backup.php' enctype='multipart/form-data' onsubmit='return top.restoreSession()'>
438 <input type="hidden" name="csrf_token_form" value="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
440 <table<?php echo ($form_step != 101) ? " style='width:50em'" : ""; ?>>
441 <tr>
442 <td>
444 <?php
445 $cmd = '';
446 $mysql_cmd = $MYSQL_PATH . DIRECTORY_SEPARATOR . 'mysql';
447 $mysql_dump_cmd = $mysql_cmd . 'dump';
448 $mysql_ssl = '';
449 if (file_exists($GLOBALS['OE_SITE_DIR'] . "/documents/certificates/mysql-ca")) {
450 // Support for mysql SSL encryption
451 $mysql_ssl = " --ssl-ca=" . escapeshellarg($GLOBALS['OE_SITE_DIR'] . "/documents/certificates/mysql-ca") . " ";
452 if (
453 file_exists($GLOBALS['OE_SITE_DIR'] . "/documents/certificates/mysql-key") &&
454 file_exists($GLOBALS['OE_SITE_DIR'] . "/documents/certificates/mysql-cert")
456 // Support for mysql SSL client based cert authentication
457 $mysql_ssl .= "--ssl-cert=" . escapeshellarg($GLOBALS['OE_SITE_DIR'] . "/documents/certificates/mysql-cert") . " ";
458 $mysql_ssl .= "--ssl-key=" . escapeshellarg($GLOBALS['OE_SITE_DIR'] . "/documents/certificates/mysql-key") . " ";
462 $file_to_compress = ''; // if named, this iteration's file will be gzipped after it is created
463 $eventlog = 0; // Eventlog Flag
465 if ($form_step == 0) {
466 echo "<table>\n";
467 echo " <tr>\n";
468 echo " <td><input class='btn btn-secondary' type='submit' name='form_create' value='" . attr($BTN_TEXT_CREATE) . "' /></td>\n";
469 echo " <td>" . xlt('Create and download a full backup') . "</td>\n";
470 echo " </tr>\n";
471 // The config import/export feature is optional.
472 if (!empty($GLOBALS['configuration_import_export'])) {
473 echo " <tr>\n";
474 echo " <td><input class='btn btn-secondary' type='submit' name='form_export' value='" . attr($BTN_TEXT_EXPORT) . "' /></td>\n";
475 echo " <td>" . xlt('Download configuration data') . "</td>\n";
476 echo " </tr>\n";
477 echo " <tr>\n";
478 echo " <td><input class='btn btn-secondary' type='submit' name='form_import' value='" . attr($BTN_TEXT_IMPORT) . "' /></td>\n";
479 echo " <td>" . xlt('Upload configuration data') . "</td>\n";
480 echo " </tr>\n";
481 echo " <tr>\n";
482 echo " <td><input class='btn btn-secondary' type='submit' name='form_logarchive' value='" . attr($BTN_TEXT_LOG) . "' /></td>\n";
483 echo " <td>" . xlt('Download and/or delete log data') . "</td>\n";
484 echo " </tr>\n";
487 // ViSolve : Add ' Create Log table backup Button'
488 echo " <tr>\n";
489 echo " <td><input class='btn btn-secondary' type='submit' name='form_backup' value='" . attr($BTN_TEXT_CREATE_EVENTLOG) . "' /></td>\n";
490 echo " <td>" . xlt('Create Eventlog Backup') . "</td>\n";
491 echo " </tr>\n";
492 echo " <tr>\n";
493 echo " <td></td><td class='text'>" . xlt('Note that the Eventlog Backup is currently set to save in the following folder') . ": " . text($GLOBALS['backup_log_dir']) . " . " . xlt('Recommend setting the Path for Event Log Backup in Globals settings in the Miscellaneous section to something other than your tmp/temp directory.') . " " . xlt('Please refer to') . ' README-Log-Backup.txt ' . xlt('file in the Documentation directory to learn how to automate the process of creating log backups') . ".</td>\n";
494 echo " </tr>\n";
495 echo "</table>\n";
498 if ($form_step == 1) {
499 $form_status .= xla('Dumping OpenEMR database') . "...<br />";
500 echo nl2br($form_status);
501 if (file_exists($TAR_FILE_PATH)) {
502 if (! unlink($TAR_FILE_PATH)) {
503 die(xlt("Couldn't remove old backup file:") . " " . text($TAR_FILE_PATH));
507 if (! obliterate_dir($TMP_BASE)) {
508 die(xlt("Couldn't remove dir:") . " " . text($TMP_BASE));
511 if (! mkdir($BACKUP_DIR, 0777, true)) {
512 die(xlt("Couldn't create backup dir:") . " " . text($BACKUP_DIR));
515 $file_to_compress = "$BACKUP_DIR/openemr.sql"; // gzip this file after creation
517 if ($GLOBALS['include_de_identification'] == 1) {
518 //include routines during backup when de-identification is enabled
519 $cmd = escapeshellcmd($mysql_dump_cmd) . " -u " . escapeshellarg($sqlconf["login"]) .
520 " -p" . escapeshellarg($sqlconf["pass"]) .
521 " -h " . escapeshellarg($sqlconf["host"]) .
522 " --port=" . escapeshellarg($sqlconf["port"]) .
523 " --routines" .
524 " --ignore-table=" . escapeshellarg($sqlconf["dbase"] . ".onsite_activity_view") .
525 " --hex-blob --opt --quote-names --no-tablespaces -r " . escapeshellarg($file_to_compress) . " $mysql_ssl " .
526 escapeshellarg($sqlconf["dbase"]);
527 } else {
528 $cmd = escapeshellcmd($mysql_dump_cmd) . " -u " . escapeshellarg($sqlconf["login"]) .
529 " -p" . escapeshellarg($sqlconf["pass"]) .
530 " -h " . escapeshellarg($sqlconf["host"]) .
531 " --port=" . escapeshellarg($sqlconf["port"]) .
532 " --ignore-table=" . escapeshellarg($sqlconf["dbase"] . ".onsite_activity_view") .
533 " --hex-blob --opt --quote-names --no-tablespaces -r " . escapeshellarg($file_to_compress) . " $mysql_ssl " .
534 escapeshellarg($sqlconf["dbase"]);
537 $auto_continue = true;
540 if ($form_step == 2) {
541 ++$form_step;
544 if ($form_step == 3) {
545 $form_status .= xla('Dumping OpenEMR web directory tree') . "...<br />";
546 echo nl2br($form_status);
547 $cur_dir = getcwd();
548 chdir($webserver_root);
550 // Select the files and directories to archive. Basically everything
551 // except site-specific data for other sites.
552 $file_list = array();
553 $dh = opendir($webserver_root);
554 if (!$dh) {
555 die("Cannot read directory '" . text($webserver_root) . "'.");
558 while (false !== ($filename = readdir($dh))) {
559 if ($filename == '.' || $filename == '..') {
560 continue;
563 if ($filename == 'sites') {
564 // Omit other sites.
565 $file_list[] = "$filename/" . $_SESSION['site_id'];
566 } else {
567 $file_list[] = $filename;
571 closedir($dh);
573 $arch_file = $BACKUP_DIR . DIRECTORY_SEPARATOR . "openemr.tar.gz";
574 if (!create_tar_archive($arch_file, "gz", $file_list)) {
575 die(xlt("An error occurred while dumping OpenEMR web directory tree"));
578 chdir($cur_dir);
579 $auto_continue = true;
582 if ($form_step == 4) {
583 ++$form_step;
586 if ($form_step == 5) { // create the final compressed tar containing all files
587 $form_status .= xla('Backup file has been created. Will now send download.') . "<br />";
588 echo nl2br($form_status);
589 $cur_dir = getcwd();
590 chdir($BACKUP_DIR);
591 $file_list = array('.');
592 if (!create_tar_archive($TAR_FILE_PATH, '', $file_list)) {
593 die(xlt("Error: Unable to create downloadable archive"));
596 chdir($cur_dir);
597 /* To log the backup event */
598 if ($GLOBALS['audit_events_backup']) {
599 EventAuditLogger::instance()->newEvent("backup", $_SESSION['authUser'], $_SESSION['authProvider'], 0, "Backup is completed");
602 $auto_continue = true;
605 if ($form_step == 101) {
606 echo "<p class='font-weight-bold'>&nbsp;" . xlt('Select the configuration items to export') . ":</p>";
608 echo "<table cellspacing='10' cellpadding='0'>\n<tr>\n<td valign='top' nowrap>\n";
610 echo "<strong>" . xlt('Tables') . "</strong><br />\n";
611 echo "<input type='checkbox' name='form_cb_services' value='1' />\n";
612 echo " " . xlt('Services') . "<br />\n";
613 echo "<input type='checkbox' name='form_cb_products' value='1' />\n";
614 echo " " . xlt('Products') . "<br />\n";
615 echo "<input type='checkbox' name='form_cb_prices' value='1' />\n";
616 echo " " . xlt('Prices') . "<br />\n";
617 echo "<input type='checkbox' name='form_cb_categories' value='1' />\n";
618 echo " " . xlt('Document Categories') . "<br />\n";
619 echo "<input type='checkbox' name='form_cb_feesheet' value='1' />\n";
620 echo " " . xlt('Fee Sheet Options') . "<br />\n";
621 echo "<input type='checkbox' name='form_cb_lab_config' value='1' />\n";
622 echo " " . xlt('Lab Configuration') . "<br />\n";
623 echo "<input type='checkbox' name='form_cb_lang' value='1' />\n";
624 echo " " . xlt('Translations') . "<br />\n";
626 // Multi-select for lists.
627 echo "</td><td valign='top'>\n";
628 echo "<strong>" . xlt('Lists') . "</strong><br />\n";
629 echo "<select class='form-control' multiple name='form_sel_lists[]' size='15'>";
630 $lres = sqlStatement("SELECT option_id, title FROM list_options WHERE " .
631 "list_id = 'lists' AND activity = 1 ORDER BY title, seq");
632 while ($lrow = sqlFetchArray($lres)) {
633 echo "<option value='" . attr($lrow['option_id']) . "'";
634 echo ">" . text(xl_list_label($lrow['title'])) . "</option>\n";
636 echo "</select>\n";
637 echo "<br /><a href='#' onclick='export_submit(102.1)'>" . xlt('Download CSV') . "</a>";
639 // Multi-select for layouts.
640 echo "</td><td valign='top'>\n";
641 echo "<strong>" . xlt('Layouts') . "</strong><br />\n";
642 echo "<select class='form-control' multiple name='form_sel_layouts[]' size='15'>";
643 $lres = sqlStatement("SELECT grp_form_id, grp_title FROM layout_group_properties WHERE " .
644 "grp_group_id = '' AND grp_activity = 1 ORDER BY grp_form_id");
645 while ($lrow = sqlFetchArray($lres)) {
646 $key = $lrow['grp_form_id'];
647 echo "<option value='" . attr($key) . "'";
648 echo ">" . text($key) . ": " . text(xl_layout_label($lrow['grp_title'])) . "</option>\n";
650 echo "</select>\n";
651 echo "<br /><a href='#' onclick='export_submit(102.2)'>" . xlt('Download CSV') . "</a>";
652 echo "</td>\n</tr>\n</table>\n";
654 // Option to auto-export lists referenced by the chosen layouts.
655 echo "&nbsp;<br /><input type='checkbox' name='form_cb_addlists' value='1' />\n";
656 echo " " . xlt('Include all lists referenced in chosen layouts') . "<br />\n";
658 echo "<br /><input class='btn btn-primary' type='submit' onclick='export_submit(102)' value='" . xla('Continue') . "' />\n";
661 if ($form_step == 102) {
662 $tables = '';
663 if (!empty($_POST['form_cb_services' ])) {
664 $tables .= ' codes';
667 if (!empty($_POST['form_cb_products' ])) {
668 $tables .= ' drugs drug_templates';
671 if (!empty($_POST['form_cb_prices' ])) {
672 $tables .= ' prices';
675 if (!empty($_POST['form_cb_categories'])) {
676 $tables .= ' categories categories_seq';
679 if (!empty($_POST['form_cb_feesheet' ])) {
680 $tables .= ' fee_sheet_options';
683 if (!empty($_POST['form_cb_lab_config'])) {
684 $tables .= ' procedure_type procedure_providers procedure_questions';
687 if (!empty($_POST['form_cb_lang' ])) {
688 $tables .= ' lang_languages lang_constants lang_definitions';
691 if ($tables || is_array($_POST['form_sel_lists'] ?? '') || is_array($_POST['form_sel_layouts'] ?? '')) {
692 $form_status .= xla('Creating export file') . "...<br />";
693 echo nl2br($form_status);
694 if (file_exists($EXPORT_FILE)) {
695 if (! unlink($EXPORT_FILE)) {
696 die(xlt("Couldn't remove old export file: ") . text($EXPORT_FILE));
700 // The substitutions below use perl because sed's not usually on windows systems.
701 $perl = $PERL_PATH . DIRECTORY_SEPARATOR . 'perl';
703 # This condition was added because the windows operating system uses different syntax for the shell commands.
704 # The test is if it is the windows operating system.
705 if (IS_WINDOWS) {
706 # This section sets the character_set_client to utf8 in the sql file as part or the import property.
707 # windows will place the quotes in the outputted code if they are there. we removed them here.
708 $cmd = "echo SET character_set_client = utf8; > " . escapeshellarg($EXPORT_FILE) . " & ";
709 } else {
710 $cmd = "echo 'SET character_set_client = utf8;' > " . escapeshellarg($EXPORT_FILE) . ";";
713 if ($tables) {
714 if (IS_WINDOWS) {
715 $cmd .= escapeshellcmd('"' . $mysql_dump_cmd . '"') . " -u " . escapeshellarg($sqlconf["login"]) .
716 " -p" . escapeshellarg($sqlconf["pass"]) .
717 " -h " . escapeshellarg($sqlconf["host"]) .
718 " --port=" . escapeshellarg($sqlconf["port"]) .
719 " --ignore-table=" . escapeshellarg($sqlconf["dbase"] . ".onsite_activity_view") .
720 " --hex-blob --opt --quote-names --skip-comments --no-tablespaces $mysql_ssl " .
721 escapeshellarg($sqlconf["dbase"]) . " $tables";
722 } else {
723 $cmd .= escapeshellcmd($mysql_dump_cmd) . " -u " . escapeshellarg($sqlconf["login"]) .
724 " -p" . escapeshellarg($sqlconf["pass"]) .
725 " -h " . escapeshellarg($sqlconf["host"]) .
726 " --port=" . escapeshellarg($sqlconf["port"]) .
727 " --ignore-table=" . escapeshellarg($sqlconf["dbase"] . ".onsite_activity_view") .
728 " --hex-blob --opt --quote-names --skip-comments --no-tablespaces $mysql_ssl " .
729 escapeshellarg($sqlconf["dbase"]) . " $tables";
731 if (IS_WINDOWS) {
732 # The Perl script differs in windows also.
733 $cmd .= " | " . escapeshellcmd('"' . $perl . '"') . " -pe \"s/ DEFAULT CHARSET=utf8//i; s/ collate[ =][^ ;,]*//i;\"" .
734 " >> " . escapeshellarg($EXPORT_FILE) . " & ";
735 } else {
736 $cmd .= " | " . escapeshellcmd($perl) . " -pe 's/ DEFAULT CHARSET=utf8//i; s/ collate[ =][^ ;,]*//i;'" .
737 " > " . escapeshellarg($EXPORT_FILE) . ";";
741 $dumppfx = escapeshellcmd($mysql_dump_cmd) . " -u " . escapeshellarg($sqlconf["login"]) .
742 " -p" . escapeshellarg($sqlconf["pass"]) .
743 " -h " . escapeshellarg($sqlconf["host"]) .
744 " --port=" . escapeshellarg($sqlconf["port"]) .
745 " --ignore-table=" . escapeshellarg($sqlconf["dbase"] . ".onsite_activity_view") .
746 " --hex-blob --skip-opt --quote-names --no-tablespaces --complete-insert" .
747 " --no-create-info --skip-comments $mysql_ssl";
749 // Individual lists.
750 $form_sel_lists = is_array($_POST['form_sel_lists'] ?? '') ? $_POST['form_sel_lists'] : array();
751 if (!empty($_POST['form_cb_addlists']) && is_array($_POST['form_sel_layouts'] ?? '')) {
752 // Include all lists referenced by the exported layouts.
753 foreach ($_POST['form_sel_layouts'] as $layoutid) {
754 $tmpres = sqlStatement(
755 "SELECT a.list_id FROM layout_options AS a " .
756 "JOIN list_options AS i ON i.list_id = 'lists' AND i.option_id = a.list_id AND " .
757 "i.activity = 1 AND i.option_value = 0 " .
758 "WHERE a.form_id = ? AND a.list_id != '' AND a.uor > 0",
759 array($layoutid)
761 while ($tmprow = sqlFetchArray($tmpres)) {
762 if (!in_array($tmprow['list_id'], $form_sel_lists) && !in_array($tmprow['list_id'], $excluded_lists)) {
763 $form_sel_lists[] = $tmprow['list_id'];
768 if (!empty($form_sel_lists)) {
769 foreach ($form_sel_lists as $listid) {
770 // skip if have backtic(s)
771 if (strpos($listid, '`') !== false) {
772 echo xlt("Skipping illegal list name") . ": " . text($listid) . "<br>";
773 continue;
775 // whitelist the $listid
776 $listid_check = sqlQuery("SELECT `list_id` FROM `list_options` WHERE `list_id` = ? OR `option_id` = ?", [$listid, $listid]);
777 if (empty($listid_check['list_id'])) {
778 echo xlt("Skipping missing list name") . ": " . text($listid) . "<br>";
779 continue;
781 if (IS_WINDOWS) {
782 # windows will place the quotes in the outputted code if they are there. we removed them here.
783 $cmd .= " echo 'DELETE FROM list_options WHERE list_id = \"" . add_escape_custom($listid) . "\";' >> " . escapeshellarg($EXPORT_FILE) . " & ";
784 $cmd .= " echo 'DELETE FROM list_options WHERE list_id = 'lists' AND option_id = \"" . add_escape_custom($listid) . "\";' >> " . escapeshellarg($EXPORT_FILE) . " & ";
785 } else {
786 $cmd .= "echo 'DELETE FROM list_options WHERE list_id = \"" . add_escape_custom($listid) . "\";' >> " . escapeshellarg($EXPORT_FILE) . ";";
787 $cmd .= "echo 'DELETE FROM list_options WHERE list_id = \"lists\" AND option_id = \"" . add_escape_custom($listid) . "\";' >> " . escapeshellarg($EXPORT_FILE) . ";";
789 if (IS_WINDOWS) {
790 # windows uses the & to join statements.
791 $cmd .= $dumppfx . " --where=\"list_id = 'lists' AND option_id = '$listid' OR list_id = '$listid' " .
792 "ORDER BY list_id != 'lists', seq, title\" " .
793 escapeshellarg($sqlconf["dbase"]) . " list_options";
794 $cmd .= " >> " . escapeshellarg($EXPORT_FILE) . " & ";
795 } else {
796 $cmd .= $dumppfx . " --where='list_id = \"lists\" AND option_id = \"" .
797 add_escape_custom($listid) . "\" OR list_id = \"" .
798 add_escape_custom($listid) . "\" " . "ORDER BY list_id != \"lists\", seq, title' " .
799 escapeshellarg($sqlconf["dbase"]) . " list_options";
800 $cmd .= " >> " . escapeshellarg($EXPORT_FILE) . ";";
805 // Individual layouts.
806 if (is_array($_POST['form_sel_layouts'] ?? '')) {
807 $do_history_repair = false;
808 $do_demographics_repair = false;
809 foreach ($_POST['form_sel_layouts'] as $layoutid) {
810 // skip if have backtic(s)
811 if (strpos($layoutid, '`') !== false) {
812 echo xlt("Skipping illegal layout name") . ": " . text($layoutid) . "<br>";
813 continue;
815 // whitelist the $layoutid
816 $layoutid_check_one = sqlQuery("SELECT `form_id` FROM `layout_options` WHERE `form_id` = ?", [$layoutid]);
817 $layoutid_check_two = sqlQuery("SELECT `grp_form_id` FROM `layout_group_properties` WHERE `grp_form_id` = ?", [$layoutid]);
818 if (empty($layoutid_check_one['list_id']) && empty($layoutid_check_two['grp_form_id'])) {
819 echo xlt("Skipping missing layout name") . ": " . text($layoutid) . "<br>";
820 continue;
822 // Beware and keep in mind that Windows requires double quotes around arguments.
823 if (IS_WINDOWS) {
824 # windows will place the quotes in the outputted code if they are there. we removed them here.
825 $cmd .= " echo 'DELETE FROM layout_options WHERE form_id = \"" . add_escape_custom($layoutid) . "\";' >> " . escapeshellarg($EXPORT_FILE) . " & ";
826 } else {
827 $cmd .= "echo 'DELETE FROM layout_options WHERE form_id = \"" . add_escape_custom($layoutid) . "\";' >> " . escapeshellarg($EXPORT_FILE) . ";";
829 if (IS_WINDOWS) {
830 # windows will place the quotes in the outputted code if they are there. we removed them here.
831 $cmd .= "echo 'DELETE FROM layout_group_properties WHERE grp_form_id = \"" . add_escape_custom($layoutid) . "\";' >> " . escapeshellarg($EXPORT_FILE) . " &;";
832 } else {
833 $cmd .= "echo 'DELETE FROM layout_group_properties WHERE grp_form_id = \"" . add_escape_custom($layoutid) . "\";' >> " . escapeshellarg($EXPORT_FILE) . ";";
835 if (IS_WINDOWS) {
836 # windows uses the & to join statements.
837 $cmd .= $dumppfx . ' --where="grp_form_id = \'' . add_escape_custom($layoutid) . "'\" " .
838 escapeshellarg($sqlconf["dbase"]) . " layout_group_properties";
839 $cmd .= " >> " . escapeshellarg($EXPORT_FILE) . " & ";
840 $cmd .= $dumppfx . ' --where="form_id = \'' . add_escape_custom($layoutid) . '\' ORDER BY group_id, seq, title" ' .
841 escapeshellarg($sqlconf["dbase"]) . " layout_options" ;
842 $cmd .= " >> " . escapeshellarg($EXPORT_FILE) . " & ";
843 } else {
844 $cmd .= $dumppfx . " --where='grp_form_id = \"" . add_escape_custom($layoutid) . "\"' " .
845 escapeshellarg($sqlconf["dbase"]) . " layout_group_properties";
846 $cmd .= " >> " . escapeshellarg($EXPORT_FILE) . ";";
847 $cmd .= $dumppfx . " --where='form_id = \"" . add_escape_custom($layoutid) . "\" ORDER BY group_id, seq, title' " .
848 escapeshellarg($sqlconf["dbase"]) . " layout_options" ;
849 $cmd .= " >> " . escapeshellarg($EXPORT_FILE) . ";";
851 // History and demographics exports will get special treatment.
852 if (substr($layoutid, 0, 3) == 'HIS') {
853 $do_history_repair = true;
855 if (substr($layoutid, 0, 3) == 'DEM') {
856 $do_demographics_repair = true;
859 // If any HIS* layouts were exported then also write SQL to add missing history_data columns.
860 if ($do_history_repair) {
861 $cmd .= "echo \"SET sql_mode = '';\" >> $EXPORT_FILE;";
862 $cmd .= "echo \"SET group_concat_max_len = 1000000;\" >> $EXPORT_FILE;";
863 $cmd .= "echo \"SELECT CONCAT(\" >> $EXPORT_FILE;";
864 $cmd .= "echo \"'ALTER TABLE history_data ',\" >> $EXPORT_FILE;";
865 $cmd .= "echo \"COALESCE(GROUP_CONCAT(DISTINCT ' ADD \`', lo.field_id, '\` TEXT NOT NULL' ORDER BY lo.field_id), '')\" >> $EXPORT_FILE;";
866 $cmd .= "echo \")\" >> $EXPORT_FILE;";
867 $cmd .= "echo \"FROM layout_options AS lo WHERE\" >> $EXPORT_FILE;";
868 $cmd .= "echo \"(lo.form_id LIKE 'HIS%' OR lo.source = 'H') AND lo.field_id NOT IN\" >> $EXPORT_FILE;";
869 $cmd .= "echo \"(SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = 'history_data')\" >> $EXPORT_FILE;";
870 $cmd .= "echo \"INTO @sql;\" >> $EXPORT_FILE;";
871 $cmd .= "echo \"PREPARE stmt FROM @sql;\" >> $EXPORT_FILE;";
872 $cmd .= "echo \"EXECUTE stmt;\" >> $EXPORT_FILE;";
874 // If the DEM layout was exported then also write SQL to add missing patient_data columns.
875 if ($do_demographics_repair) {
876 $cmd .= "echo \"SET sql_mode = '';\" >> $EXPORT_FILE;";
877 $cmd .= "echo \"SET group_concat_max_len = 1000000;\" >> $EXPORT_FILE;";
878 $cmd .= "echo \"SELECT CONCAT(\" >> $EXPORT_FILE;";
879 $cmd .= "echo \"'ALTER TABLE patient_data ',\" >> $EXPORT_FILE;";
880 $cmd .= "echo \"COALESCE(GROUP_CONCAT(DISTINCT ' ADD \`', lo.field_id, '\` TEXT NOT NULL' ORDER BY lo.field_id), '')\" >> $EXPORT_FILE;";
881 $cmd .= "echo \")\" >> $EXPORT_FILE;";
882 $cmd .= "echo \"FROM layout_options AS lo WHERE\" >> $EXPORT_FILE;";
883 $cmd .= "echo \"(lo.form_id LIKE 'DEM%' OR lo.source = 'D') AND lo.field_id NOT IN\" >> $EXPORT_FILE;";
884 $cmd .= "echo \"(SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = 'patient_data')\" >> $EXPORT_FILE;";
885 $cmd .= "echo \"INTO @sql;\" >> $EXPORT_FILE;";
886 $cmd .= "echo \"PREPARE stmt FROM @sql;\" >> $EXPORT_FILE;";
887 $cmd .= "echo \"EXECUTE stmt;\" >> $EXPORT_FILE;";
890 } else {
891 echo xlt('No items were selected!');
892 $form_step = -1;
895 $auto_continue = true;
898 if ($form_step == 103) {
899 $form_status .= xla('Done. Will now send download.') . "<br />";
900 echo nl2br($form_status);
901 $auto_continue = true;
904 if ($form_step == 201) {
905 echo xlt('WARNING: This will overwrite configuration information with data from the uploaded file!') . " \n";
906 echo xlt('Use this feature only with newly installed sites, ');
907 echo xlt('otherwise you will destroy references to/from existing data.') . "\n";
908 echo "<br />&nbsp;<br />\n";
909 echo xlt('File to upload') . ":\n";
910 echo "<input type='hidden' name='MAX_FILE_SIZE' value='32000000' />\n";
911 echo "<input type='file' name='userfile' /><br />&nbsp;<br />\n";
912 echo "<input class='btn btn-primary' type='submit' value='" . xla('Continue') . "' />\n";
915 if ($form_step == 202) {
916 // Process uploaded config file.
917 if (is_uploaded_file($_FILES['userfile']['tmp_name'])) {
918 if (move_uploaded_file($_FILES['userfile']['tmp_name'], $EXPORT_FILE)) {
919 $form_status .= xla('Applying') . "...<br />";
920 echo nl2br($form_status);
921 $cmd = escapeshellcmd($mysql_cmd) . " -u " . escapeshellarg($sqlconf["login"]) .
922 " -p" . escapeshellarg($sqlconf["pass"]) .
923 " -h " . escapeshellarg($sqlconf["host"]) .
924 " --port=" . escapeshellarg($sqlconf["port"]) .
925 " $mysql_ssl " .
926 escapeshellarg($sqlconf["dbase"]) .
927 " < " . escapeshellarg($EXPORT_FILE);
928 } else {
929 echo xlt('Internal error accessing uploaded file!');
930 $form_step = -1;
932 } else {
933 echo xlt('Upload failed!');
934 $form_step = -1;
937 $auto_continue = true;
940 if ($form_step == 203) {
941 $form_status .= xla('Done') . ".";
942 echo nl2br($form_status);
945 /// ViSolve : EventLog Backup
946 if ($form_step == 301) {
947 # Get the Current Timestamp, to attach with the log backup file
948 $backuptime = date("Ymd_His");
949 # Eventlog backup directory
950 $BACKUP_EVENTLOG_DIR = $GLOBALS['backup_log_dir'];
952 # Check if Eventlog Backup directory exists, if not create it with Write permission
953 if (!file_exists($BACKUP_EVENTLOG_DIR)) {
954 mkdir($BACKUP_EVENTLOG_DIR);
955 chmod($BACKUP_EVENTLOG_DIR, 0777);
958 # Frame the Eventlog Backup File Name
959 $BACKUP_EVENTLOG_FILE = $BACKUP_EVENTLOG_DIR . '/eventlog_' . $backuptime . '.sql';
960 # Create a new table similar to event table, rename the existing table as backup table, and rename the new table to event log table. Then export the contents of the table into a text file and drop the table.
961 $res = sqlStatement("create table if not exists log_comment_encrypt_new like log_comment_encrypt");
962 $res = sqlStatement("rename table log_comment_encrypt to log_comment_encrypt_backup,log_comment_encrypt_new to log_comment_encrypt");
963 $res = sqlStatement("create table if not exists log_new like log");
964 $res = sqlStatement("rename table log to log_backup,log_new to log");
965 $res = sqlStatement("create table if not exists api_log_new like api_log");
966 $res = sqlStatement("rename table api_log to api_log_backup, api_log_new to api_log");
967 echo "<br />";
968 $cmd = escapeshellcmd($mysql_dump_cmd) . " -u " . escapeshellarg($sqlconf["login"]) .
969 " -p" . escapeshellarg($sqlconf["pass"]) .
970 " -h " . escapeshellarg($sqlconf["host"]) .
971 " --port=" . escapeshellarg($sqlconf["port"]) .
972 " --ignore-table=" . escapeshellarg($sqlconf["dbase"] . ".onsite_activity_view") .
973 " --hex-blob --opt --quote-names --no-tablespaces -r " . escapeshellarg($BACKUP_EVENTLOG_FILE) . " $mysql_ssl " .
974 escapeshellarg($sqlconf["dbase"]) . " --tables log_comment_encrypt_backup log_backup api_log_backup";
975 # Set Eventlog Flag when it is done
976 $eventlog = 1;
977 // 301 If ends here.
980 if ($form_step == 401) {
981 echo "<p><b>&nbsp;" . xlt('Download or Delete Old Log Entries') . ":</b></p>";
982 $tmprow = sqlQuery("SELECT COUNT(*) AS count, MIN(date) AS date FROM log");
983 echo "<p>&nbsp;" . xlt('The log has') . ' ' . $tmprow['count'] . ' ' .
984 xlt('entries with the oldest dated') . ' ' . $tmprow['date'] . ".</p>";
985 // Default end date is end of year 2 years ago, ensuring 1 full year of log remaining.
986 $end_date = (date('Y') - 2) . '-12-31';
987 if (!empty($_POST['form_end_date'])) {
988 $end_date = DateToYYYYMMDD($_POST['form_end_date']);
990 echo "<p>&nbsp;" . xlt('Select an end date. Entries after this date will not be downloaded or deleted.') . " ";
991 echo "<input type='text' class='datepicker' name='form_end_date' id='form_end_date' size='10' " .
992 "value='" . attr(oeFormatShortDate($end_date)) . "' " .
993 "onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)' title='End date yyyy-mm-dd' />";
994 echo "</p>\n";
995 echo "<p><input type='button' onclick='export_submit(402)' value='" . xla('Download Log Entries as Zipped CSV') . "' />&nbsp;\n";
996 echo "<input type='button' onclick='export_submit(405)' value='" . xla('Delete Log Entries') . "' /></p>\n";
999 if ($form_step == 405) {
1000 // Process log delete, then optimize to reclaim the file space.
1001 if (!empty($_POST['form_end_date'])) {
1002 $end_date = DateToYYYYMMDD($_POST['form_end_date']);
1003 sqlStatement(
1004 "DELETE log, lce, al FROM log " .
1005 "LEFT JOIN log_comment_encrypt AS lce ON lce.log_id = log.id " .
1006 "LEFT JOIN api_log AS al ON al.log_id = log.id " .
1007 "WHERE log.date <= ?",
1008 array("$end_date 23:59:59")
1010 sqlStatement("OPTIMIZE TABLE log");
1011 } else {
1012 die(xlt("End date is missing!"));
1014 $form_step = -1;
1015 $auto_continue = true;
1018 ++$form_step;
1021 </td>
1022 </tr>
1023 </table>
1025 <input type='hidden' name='form_step' value='<?php echo attr($form_step); ?>' />
1026 <input type='hidden' name='form_status' value='<?php echo $form_status; ?>' />
1028 </form>
1030 <?php
1031 ob_flush();
1032 flush();
1033 if ($cmd) {
1034 $tmp0 = exec($cmd, $tmp1, $tmp2);
1036 if ($tmp2) {
1037 if ($eventlog == 1) {
1038 // ViSolve : Restore previous state, if backup fails.
1039 $res = sqlStatement("drop table if exists log_comment_encrypt");
1040 $res = sqlStatement("rename table log_comment_encrypt_backup to log_comment_encrypt");
1041 $res = sqlStatement("drop table if exists log");
1042 $res = sqlStatement("rename table log_backup to log");
1043 $res = sqlStatement("drop table if exists api_log");
1044 $res = sqlStatement("rename table api_log_backup to api_log");
1046 //Removed the connection details as it exposes all the database credentials
1048 die("There was an error on the backup");
1051 // ViSolve: If the Eventlog is set, then clear the temporary table -- Start here
1052 if ($eventlog == 1) {
1053 $res = sqlStatement("drop table if exists log_backup");
1054 $res = sqlStatement("drop table if exists log_comment_encrypt_backup");
1055 $res = sqlStatement("drop table if exists api_log_backup");
1056 echo "<br /><b>";
1057 echo xlt('Backup Successfully taken in') . " ";
1058 echo text($BACKUP_EVENTLOG_DIR);
1059 echo "</b>";
1062 // ViSolve: If the Eventlog is set, then clear the temporary table -- Ends here
1065 // If a file was flagged to be gzip-compressed after this cmd, do it.
1066 if ($file_to_compress) {
1067 if (!gz_compress_file($file_to_compress)) {
1068 die(xlt("Error in gzip compression of file: ") . text($file_to_compress));
1073 </center>
1075 <?php if ($auto_continue) { ?>
1076 <script>
1077 setTimeout("document.forms[0].submit();", 500);
1078 </script>
1079 <?php }
1081 // Recursive directory remove (like an O/S insensitive "rm -rf dirname")
1082 function obliterate_dir($dir)
1084 if (!file_exists($dir)) {
1085 return true;
1088 if (!is_dir($dir) || is_link($dir)) {
1089 return unlink($dir);
1092 foreach (scandir($dir) as $item) {
1093 if ($item == '.' || $item == '..') {
1094 continue;
1097 if (!obliterate_dir($dir . DIRECTORY_SEPARATOR . $item)) {
1098 chmod($dir . DIRECTORY_SEPARATOR . $item, 0777);
1099 if (!obliterate_dir($dir . DIRECTORY_SEPARATOR . $item)) {
1100 return false;
1105 return rmdir($dir);
1108 // Create a tar archive given the archive file name, compression method if any, and the
1109 // array of file/directory names to archive
1110 function create_tar_archive($archiveName, $compressMethod, $itemArray)
1112 // Create a tar object using the pear library
1113 $tar = new Archive_Tar($archiveName, $compressMethod);
1114 if ($tar->create($itemArray)) {
1115 return true;
1118 return false;
1121 // Compress a file using gzip. Source file removed, leaving only the compressed
1122 // *.gz file, just like gzip command line would behave.
1123 function gz_compress_file($source)
1125 $dest = $source . '.gz';
1126 $error = false;
1127 if ($fp_in = fopen($source, 'rb')) {
1128 if ($fp_out = gzopen($dest, 'wb')) {
1129 while (!feof($fp_in)) {
1130 gzwrite($fp_out, fread($fp_in, 1024 * 512));
1133 gzclose($fp_out);
1134 fclose($fp_in);
1135 unlink($source);
1136 } else {
1137 $error = true;
1139 } else {
1140 $error = true;
1143 if ($error) {
1144 return false;
1145 } else {
1146 return $dest;
1151 </body>
1152 </html>