docker dev update
[openemr.git] / library / classes / Installer.class.php
blobd7d5d62e24d3630d586762244395684d55e27176
1 <?php
2 /* Copyright © 2010 by Andrew Moore */
3 /* Licensing information appears at the end of this file. */
5 class Installer
8 public function __construct($cgi_variables)
10 // Installation variables
11 // For a good explanation of these variables, see documentation in
12 // the contrib/util/installScripts/InstallerAuto.php file.
13 $this->iuser = isset($cgi_variables['iuser']) ? ($cgi_variables['iuser']) : '';
14 $this->iuserpass = isset($cgi_variables['iuserpass']) ? ($cgi_variables['iuserpass']) : '';
15 $this->iuname = isset($cgi_variables['iuname']) ? ($cgi_variables['iuname']) : '';
16 $this->iufname = isset($cgi_variables['iufname']) ? ($cgi_variables['iufname']) : '';
17 $this->igroup = isset($cgi_variables['igroup']) ? ($cgi_variables['igroup']) : '';
18 $this->server = isset($cgi_variables['server']) ? ($cgi_variables['server']) : ''; // mysql server (usually localhost)
19 $this->loginhost = isset($cgi_variables['loginhost']) ? ($cgi_variables['loginhost']) : ''; // php/apache server (usually localhost)
20 $this->port = isset($cgi_variables['port']) ? ($cgi_variables['port']): '';
21 $this->root = isset($cgi_variables['root']) ? ($cgi_variables['root']) : '';
22 $this->rootpass = isset($cgi_variables['rootpass']) ? ($cgi_variables['rootpass']) : '';
23 $this->login = isset($cgi_variables['login']) ? ($cgi_variables['login']) : '';
24 $this->pass = isset($cgi_variables['pass']) ? ($cgi_variables['pass']) : '';
25 $this->dbname = isset($cgi_variables['dbname']) ? ($cgi_variables['dbname']) : '';
26 $this->collate = isset($cgi_variables['collate']) ? ($cgi_variables['collate']) : '';
27 $this->site = isset($cgi_variables['site']) ? ($cgi_variables['site']) : '';
28 $this->source_site_id = isset($cgi_variables['source_site_id']) ? ($cgi_variables['source_site_id']) : '';
29 $this->clone_database = isset($cgi_variables['clone_database']) ? ($cgi_variables['clone_database']) : '';
30 $this->no_root_db_access = isset($cgi_variables['no_root_db_access']) ? ($cgi_variables['no_root_db_access']) : ''; // no root access to database. user/privileges pre-configured
31 $this->development_translations = isset($cgi_variables['development_translations']) ? ($cgi_variables['development_translations']) : '';
32 // Make this true for IPPF.
33 $this->ippf_specific = false;
35 // Record name of sql access file
36 $GLOBALS['OE_SITES_BASE'] = dirname(__FILE__) . '/../../sites';
37 $GLOBALS['OE_SITE_DIR'] = $GLOBALS['OE_SITES_BASE'] . '/' . $this->site;
38 $this->conffile = $GLOBALS['OE_SITE_DIR'] . '/sqlconf.php';
40 // Record names of sql table files
41 $this->main_sql = dirname(__FILE__) . '/../../sql/database.sql';
42 $this->translation_sql = dirname(__FILE__) . '/../../contrib/util/language_translations/currentLanguage_utf8.sql';
43 $this->devel_translation_sql = "http://translations.openemr.io/languageTranslations_utf8.sql";
44 $this->ippf_sql = dirname(__FILE__) . "/../../sql/ippf_layout.sql";
45 $this->icd9 = dirname(__FILE__) . "/../../sql/icd9.sql";
46 $this->cvx = dirname(__FILE__) . "/../../sql/cvx_codes.sql";
47 $this->additional_users = dirname(__FILE__) . "/../../sql/official_additional_users.sql";
49 // Record name of php-gacl installation files
50 $this->gaclSetupScript1 = dirname(__FILE__) . "/../../gacl/setup.php";
51 $this->gaclSetupScript2 = dirname(__FILE__) . "/../../acl_setup.php";
53 // Prepare the dumpfile list
54 $this->initialize_dumpfile_list();
56 // Entities to hold error and debug messages
57 $this->error_message = '';
58 $this->debug_message = '';
60 // Entity to hold sql connection
61 $this->dbh = false;
64 public function login_is_valid()
66 if (($this->login == '') || (! isset($this->login))) {
67 $this->error_message = "login is invalid: '$this->login'";
68 return false;
71 return true;
74 public function char_is_valid($input_text)
76 // to prevent php injection
77 trim($input_text);
78 if ($input_text == '') {
79 return false;
82 if (preg_match('@[\\\\;()<>/\'"]@', $input_text)) {
83 return false;
86 return true;
89 public function databaseNameIsValid($name)
91 if (preg_match('/[^A-Za-z0-9_-]/', $name)) {
92 return false;
94 return true;
97 public function collateNameIsValid($name)
99 if (preg_match('/[^A-Za-z0-9_-]/', $name)) {
100 return false;
102 return true;
105 public function iuser_is_valid()
107 if (strpos($this->iuser, " ")) {
108 $this->error_message = "Initial user is invalid: '$this->iuser'";
109 return false;
112 return true;
115 public function password_is_valid()
117 if ($this->pass == "" || !isset($this->pass)) {
118 $this->error_message = "The password for the new database account is invalid: '$this->pass'";
119 return false;
122 return true;
125 public function user_password_is_valid()
127 if ($this->iuserpass == "" || !isset($this->iuserpass)) {
128 $this->error_message = "The password for the user is invalid: '$this->iuserpass'";
129 return false;
132 return true;
137 public function root_database_connection()
139 $this->dbh = $this->connect_to_database($this->server, $this->root, $this->rootpass, $this->port);
140 if ($this->dbh) {
141 if (! $this->set_sql_strict()) {
142 $this->error_message = 'unable to set strict sql setting';
143 return false;
146 return true;
147 } else {
148 $this->error_message = 'unable to connect to database as root';
149 return false;
153 public function user_database_connection()
155 $this->dbh = $this->connect_to_database($this->server, $this->login, $this->pass, $this->port, $this->dbname);
156 if (! $this->dbh) {
157 $this->error_message = "unable to connect to database as user: '$this->login'";
158 return false;
161 if (! $this->set_sql_strict()) {
162 $this->error_message = 'unable to set strict sql setting';
163 return false;
166 if (! $this->set_collation()) {
167 $this->error_message = 'unable to set sql collation';
168 return false;
171 if (! mysqli_select_db($this->dbh, $this->dbname)) {
172 $this->error_message = "unable to select database: '$this->dbname'";
173 return false;
176 return true;
179 public function create_database()
181 $sql = "create database " . $this->escapeDatabaseName($this->dbname);
182 if ($this->collate) {
183 $sql .= " character set utf8 collate " . $this->escapeCollateName($this->collate);
184 $this->set_collation();
187 return $this->execute_sql($sql);
190 public function drop_database()
192 $sql = "drop database if exists " . $this->escapeDatabaseName($this->dbname);
193 return $this->execute_sql($sql);
196 public function check_database_user()
198 return $this->execute_sql("SELECT user FROM mysql.user WHERE user = '" . $this->escapeSql($this->login) . "' AND host = '" . $this->escapeSql($this->loginhost) . "'");
201 public function create_database_user()
203 $checkUser = $this->check_database_user();
205 if ($checkUser === false) {
206 // there was an error in the check database user query, so return false
207 return false;
208 } else if ($checkUser->num_rows > 0) {
209 // the mysql user already exists, so do not need to create the user, but need to set the password
210 // Note need to try two different methods, first is for newer mysql versions and second is for older mysql versions (if the first method fails)
211 $returnSql = $this->execute_sql("ALTER USER '" . $this->escapeSql($this->login) . "'@'" . $this->escapeSql($this->loginhost) . "' IDENTIFIED BY '" . $this->escapeSql($this->pass) . "'", false);
212 if ($returnSql === false) {
213 error_log("Using older mysql version method to set password for the mysql user");
214 $returnSql = $this->execute_sql("SET PASSWORD FOR '" . $this->escapeSql($this->login) . "'@'" . $this->escapeSql($this->loginhost) . "' = PASSWORD('" . $this->escapeSql($this->pass) . "')");
216 return $returnSql;
217 } else {
218 // the mysql user does not yet exist, so create the user
219 return $this->execute_sql("CREATE USER '" . $this->escapeSql($this->login) . "'@'" . $this->escapeSql($this->loginhost) . "' IDENTIFIED BY '" . $this->escapeSql($this->pass) . "'");
223 public function grant_privileges()
225 return $this->execute_sql("GRANT ALL PRIVILEGES ON " . $this->escapeDatabaseName($this->dbname) . ".* TO '" . $this->escapeSql($this->login) . "'@'" . $this->escapeSql($this->loginhost) . "'");
228 public function disconnect()
230 return mysqli_close($this->dbh);
234 * This method creates any dumpfiles necessary.
235 * This is actually only done if we're cloning an existing site
236 * and we need to dump their database into a file.
237 * @return bool indicating success
239 public function create_dumpfiles()
241 return $this->dumpSourceDatabase();
244 public function load_dumpfiles()
246 $sql_results = ''; // information string which is returned
247 foreach ($this->dumpfiles as $filename => $title) {
248 $sql_results_temp = '';
249 $sql_results_temp = $this->load_file($filename, $title);
250 if ($sql_results_temp == false) {
251 return false;
254 $sql_results .= $sql_results_temp;
257 return $sql_results;
260 public function load_file($filename, $title)
262 $sql_results = ''; // information string which is returned
263 $sql_results .= "Creating $title tables...\n";
264 $fd = fopen($filename, 'r');
265 if ($fd == false) {
266 $this->error_message = "ERROR. Could not open dumpfile '$filename'.\n";
267 return false;
270 $query = "";
271 $line = "";
273 // Settings to drastically speed up installation with InnoDB
274 if (! $this->execute_sql("SET autocommit=0;")) {
275 return false;
278 if (! $this->execute_sql("START TRANSACTION;")) {
279 return false;
282 while (!feof($fd)) {
283 $line = fgets($fd, 1024);
284 $line = rtrim($line);
285 if (substr($line, 0, 2) == "--") { // Kill comments
286 continue;
289 if (substr($line, 0, 1) == "#") { // Kill comments
290 continue;
293 if ($line == "") {
294 continue;
297 $query = $query.$line; // Check for full query
298 $chr = substr($query, strlen($query)-1, 1);
299 if ($chr == ";") { // valid query, execute
300 $query = rtrim($query, ";");
301 if (! $this->execute_sql($query)) {
302 return false;
305 $query = "";
309 // Settings to drastically speed up installation with InnoDB
310 if (! $this->execute_sql("COMMIT;")) {
311 return false;
314 if (! $this->execute_sql("SET autocommit=1;")) {
315 return false;
318 $sql_results .= "OK<br>\n";
319 fclose($fd);
320 return $sql_results;
323 // Please note that the plain sql is used over the Doctrine ORM for
324 // `version` table interactions because it cannot connect due to a
325 // lack of context (this code is ran outside of the OpenEMR context).
326 public function add_version_info()
328 include dirname(__FILE__) . "/../../version.php";
329 if ($this->execute_sql("UPDATE version SET v_major = '" . $this->escapeSql($v_major) . "', v_minor = '" . $this->escapeSql($v_minor) . "', v_patch = '" . $this->escapeSql($v_patch) . "', v_realpatch = '" . $this->escapeSql($v_realpatch) . "', v_tag = '" . $this->escapeSql($v_tag) . "', v_database = '" . $this->escapeSql($v_database) . "', v_acl = '" . $this->escapeSql($v_acl) . "'") == false) {
330 $this->error_message = "ERROR. Unable insert version information into database\n" .
331 "<p>".mysqli_error($this->dbh)." (#".mysqli_errno($this->dbh).")\n";
332 return false;
335 return true;
338 public function add_initial_user()
340 if ($this->execute_sql("INSERT INTO `groups` (id, name, user) VALUES (1,'" . $this->escapeSql($this->igroup) . "','" . $this->escapeSql($this->iuser) . "')") == false) {
341 $this->error_message = "ERROR. Unable to add initial user group\n" .
342 "<p>".mysqli_error($this->dbh)." (#".mysqli_errno($this->dbh).")\n";
343 return false;
346 $password_hash = "NoLongerUsed"; // This is the value to insert into the password column in the "users" table. password details are now being stored in users_secure instead.
347 $salt=oemr_password_salt(); // Uses the functions defined in library/authentication/password_hashing.php
348 $hash=oemr_password_hash($this->iuserpass, $salt);
349 if ($this->execute_sql("INSERT INTO users (id, username, password, authorized, lname, fname, facility_id, calendar, cal_ui) VALUES (1,'" . $this->escapeSql($this->iuser) . "','" . $this->escapeSql($password_hash) . "',1,'" . $this->escapeSql($this->iuname) . "','" . $this->escapeSql($this->iufname) . "',3,1,3)") == false) {
350 $this->error_message = "ERROR. Unable to add initial user\n" .
351 "<p>".mysqli_error($this->dbh)." (#".mysqli_errno($this->dbh).")\n";
352 return false;
355 // Create the new style login credentials with blowfish and salt
356 if ($this->execute_sql("INSERT INTO users_secure (id, username, password, salt) VALUES (1,'" . $this->escapeSql($this->iuser) . "','" . $this->escapeSql($hash) . "','" . $this->escapeSql($salt) . "')") == false) {
357 $this->error_message = "ERROR. Unable to add initial user login credentials\n" .
358 "<p>".mysqli_error($this->dbh)." (#".mysqli_errno($this->dbh).")\n";
359 return false;
362 // Add the official openemr users (services)
363 if ($this->load_file($this->additional_users, "Additional Official Users") == false) {
364 return false;
367 return true;
371 * Create site directory if it is missing.
372 * @global string $GLOBALS['OE_SITE_DIR'] contains the name of the site directory to create
373 * @return name of the site directory or False
375 public function create_site_directory()
377 if (!file_exists($GLOBALS['OE_SITE_DIR'])) {
378 $source_directory = $GLOBALS['OE_SITES_BASE'] . "/" . $this->source_site_id;
379 $destination_directory = $GLOBALS['OE_SITE_DIR'];
380 if (! $this->recurse_copy($source_directory, $destination_directory)) {
381 $this->error_message = "unable to copy directory: '$source_directory' to '$destination_directory'. " . $this->error_message;
382 return false;
386 return true;
389 public function write_configuration_file()
391 @touch($this->conffile); // php bug
392 $fd = @fopen($this->conffile, 'w');
393 if (! $fd) {
394 $this->error_message = 'unable to open configuration file for writing: ' . $this->conffile;
395 return false;
398 $string = '<?php
399 // OpenEMR
400 // MySQL Config
404 $it_died = 0; //fmg: variable keeps running track of any errors
406 fwrite($fd, $string) or $it_died++;
407 fwrite($fd, "\$host\t= '$this->server';\n") or $it_died++;
408 fwrite($fd, "\$port\t= '$this->port';\n") or $it_died++;
409 fwrite($fd, "\$login\t= '$this->login';\n") or $it_died++;
410 fwrite($fd, "\$pass\t= '$this->pass';\n") or $it_died++;
411 fwrite($fd, "\$dbase\t= '$this->dbname';\n\n") or $it_died++;
412 fwrite($fd, "//Added ability to disable\n") or $it_died++;
413 fwrite($fd, "//utf8 encoding - bm 05-2009\n") or $it_died++;
414 fwrite($fd, "global \$disable_utf8_flag;\n") or $it_died++;
415 fwrite($fd, "\$disable_utf8_flag = false;\n") or $it_died++;
417 $string = '
418 $sqlconf = array();
419 global $sqlconf;
420 $sqlconf["host"]= $host;
421 $sqlconf["port"] = $port;
422 $sqlconf["login"] = $login;
423 $sqlconf["pass"] = $pass;
424 $sqlconf["dbase"] = $dbase;
425 //////////////////////////
426 //////////////////////////
427 //////////////////////////
428 //////DO NOT TOUCH THIS///
429 $config = 1; /////////////
430 //////////////////////////
431 //////////////////////////
432 //////////////////////////
435 ?><?php // done just for coloring
437 fwrite($fd, $string) or $it_died++;
438 fclose($fd) or $it_died++;
440 //it's rather irresponsible to not report errors when writing this file.
441 if ($it_died != 0) {
442 $this->error_message = "ERROR. Couldn't write $it_died lines to config file '$this->conffile'.\n";
443 return false;
446 return true;
449 public function insert_globals()
451 function xl($s)
453 return $s;
455 require(dirname(__FILE__) . '/../globals.inc.php');
456 foreach ($GLOBALS_METADATA as $grpname => $grparr) {
457 foreach ($grparr as $fldid => $fldarr) {
458 list($fldname, $fldtype, $flddef, $flddesc) = $fldarr;
459 if (is_array($fldtype) || substr($fldtype, 0, 2) !== 'm_') {
460 $res = $this->execute_sql("SELECT count(*) AS count FROM globals WHERE gl_name = '" . $this->escapeSql($fldid) . "'");
461 $row = mysqli_fetch_array($res, MYSQLI_ASSOC);
462 if (empty($row['count'])) {
463 $this->execute_sql("INSERT INTO globals ( gl_name, gl_index, gl_value ) " .
464 "VALUES ( '" . $this->escapeSql($fldid) . "', '0', '" . $this->escapeSql($flddef) . "' )");
470 return true;
473 public function install_gacl()
475 $install_results_1 = $this->get_require_contents($this->gaclSetupScript1);
476 if (! $install_results_1) {
477 $this->error_message = "install_gacl failed: unable to require gacl script 1";
478 return false;
481 $install_results_2 = $this->get_require_contents($this->gaclSetupScript2);
482 if (! $install_results_2) {
483 $this->error_message = "install_gacl failed: unable to require gacl script 2";
484 return false;
487 $this->debug_message .= $install_results_1 . $install_results_2;
488 return true;
491 public function quick_install()
493 // Validation of OpenEMR user settings
494 // (applicable if not cloning from another database)
495 if (empty($this->clone_database)) {
496 if (! $this->login_is_valid()) {
497 return false;
500 if (! $this->iuser_is_valid()) {
501 return false;
504 if (! $this->user_password_is_valid()) {
505 return false;
509 // Validation of mysql database password
510 if (! $this->password_is_valid()) {
511 return false;
514 if (! $this->no_root_db_access) {
515 // Connect to mysql via root user
516 if (! $this->root_database_connection()) {
517 return false;
520 // Create the dumpfile
521 // (applicable if cloning from another database)
522 if (! empty($this->clone_database)) {
523 if (! $this->create_dumpfiles()) {
524 return false;
528 // Create the site directory
529 // (applicable if mirroring another local site)
530 if (! empty($this->source_site_id)) {
531 if (! $this->create_site_directory()) {
532 return false;
536 $this->disconnect();
537 if (! $this->user_database_connection()) {
538 // Re-connect to mysql via root user
539 if (! $this->root_database_connection()) {
540 return false;
543 // Create the mysql database
544 if (! $this->create_database()) {
545 return false;
548 // Create the mysql user
549 if (! $this->create_database_user()) {
550 return false;
553 // Grant user privileges to the mysql database
554 if (! $this->grant_privileges()) {
555 return false;
559 $this->disconnect();
562 // Connect to mysql via created user
563 if (! $this->user_database_connection()) {
564 return false;
567 // Build the database
568 if (! $this->load_dumpfiles()) {
569 return false;
572 // Write the sql configuration file
573 if (! $this->write_configuration_file()) {
574 return false;
577 // Load the version information, globals settings,
578 // initial user, and set up gacl access controls.
579 // (applicable if not cloning from another database)
580 if (empty($this->clone_database)) {
581 if (! $this->add_version_info()) {
582 return false;
585 if (! $this->insert_globals()) {
586 return false;
589 if (! $this->add_initial_user()) {
590 return false;
593 if (! $this->install_gacl()) {
594 return false;
598 return true;
601 private function escapeSql($sql)
603 return mysqli_real_escape_string($this->dbh, $sql);
606 private function escapeDatabaseName($name)
608 if (preg_match('/[^A-Za-z0-9_-]/', $name)) {
609 error_log("Illegal character(s) in database name");
610 die("Illegal character(s) in database name");
612 return $name;
615 private function escapeCollateName($name)
617 if (preg_match('/[^A-Za-z0-9_-]/', $name)) {
618 error_log("Illegal character(s) in collation name");
619 die("Illegal character(s) in collation name");
621 return $name;
624 private function execute_sql($sql, $showError = true)
626 $this->error_message = '';
627 if (! $this->dbh) {
628 $this->user_database_connection();
631 $results = mysqli_query($this->dbh, $sql);
632 if ($results) {
633 return $results;
634 } else {
635 if ($showError) {
636 $error_mes = mysqli_error($this->dbh);
637 $this->error_message = "unable to execute SQL: '$sql' due to: " . $error_mes;
638 error_log("ERROR IN OPENEMR INSTALL: Unable to execute SQL: " . $sql . " due to: " . $error_mes);
640 return false;
644 private function connect_to_database($server, $user, $password, $port, $dbname = '')
646 if ($server == "localhost") {
647 $dbh = mysqli_connect($server, $user, $password, $dbname);
648 } else {
649 $dbh = mysqli_connect($server, $user, $password, $dbname, $port);
652 return $dbh;
655 private function set_sql_strict()
657 // Turn off STRICT SQL
658 return $this->execute_sql("SET sql_mode = ''");
661 private function set_collation()
663 if ($this->collate) {
664 return $this->execute_sql("SET NAMES 'utf8'");
667 return true;
671 * innitialize $this->dumpfiles, an array of the dumpfiles that will
672 * be loaded into the database, including the correct translation
673 * dumpfile.
674 * The keys are the paths of the dumpfiles, and the values are the titles
675 * @return array
677 private function initialize_dumpfile_list()
679 if ($this->clone_database) {
680 $this->dumpfiles = array( $this->get_backup_filename() => 'clone database' );
681 } else {
682 $dumpfiles = array( $this->main_sql => 'Main' );
683 if (! empty($this->development_translations)) {
684 // Use the online development translation set
685 $dumpfiles[ $this->devel_translation_sql ] = "Online Development Language Translations (utf8)";
686 } else {
687 // Use the local translation set
688 $dumpfiles[ $this->translation_sql ] = "Language Translation (utf8)";
691 if ($this->ippf_specific) {
692 $dumpfiles[ $this->ippf_sql ] = "IPPF Layout";
695 // Load ICD-9 codes if present.
696 if (file_exists($this->icd9)) {
697 $dumpfiles[ $this->icd9 ] = "ICD-9";
700 // Load CVX codes if present
701 if (file_exists($this->cvx)) {
702 $dumpfiles[ $this->cvx ] = "CVX Immunization Codes";
705 $this->dumpfiles = $dumpfiles;
708 return $this->dumpfiles;
711 // http://www.php.net/manual/en/function.include.php
712 private function get_require_contents($filename)
714 if (is_file($filename)) {
715 ob_start();
716 require $filename;
717 $contents = ob_get_contents();
718 ob_end_clean();
719 return $contents;
722 return false;
727 * Directory copy logic borrowed from a user comment at
728 * http://www.php.net/manual/en/function.copy.php
729 * @param string $src name of the directory to copy
730 * @param string $dst name of the destination to copy to
731 * @return bool indicating success
733 private function recurse_copy($src, $dst)
735 $dir = opendir($src);
736 if (! @mkdir($dst)) {
737 $this->error_message = "unable to create directory: '$dst'";
738 return false;
741 while (false !== ($file = readdir($dir))) {
742 if ($file != '.' && $file != '..') {
743 if (is_dir($src . '/' . $file)) {
744 $this->recurse_copy($src . '/' . $file, $dst . '/' . $file);
745 } else {
746 copy($src . '/' . $file, $dst . '/' . $file);
751 closedir($dir);
752 return true;
757 * dump a site's database to a temporary file.
758 * @param string $source_site_id the site_id of the site to dump
759 * @return filename of the backup
761 private function dumpSourceDatabase()
763 global $OE_SITES_BASE;
764 $source_site_id = $this->source_site_id;
766 include("$OE_SITES_BASE/$source_site_id/sqlconf.php");
768 if (empty($config)) {
769 die("Source site $source_site_id has not been set up!");
772 $backup_file = $this->get_backup_filename();
773 $cmd = "mysqldump -u " . escapeshellarg($login) .
774 " -p" . escapeshellarg($pass) .
775 " --opt --skip-extended-insert --quote-names -r $backup_file " .
776 escapeshellarg($dbase);
778 $tmp0 = exec($cmd, $tmp1 = array(), $tmp2);
779 if ($tmp2) {
780 die("Error $tmp2 running \"$cmd\": $tmp0 " . implode(' ', $tmp1));
783 return $backup_file;
787 * @return filename of the source backup database for cloning
789 private function get_backup_filename()
791 if (stristr(PHP_OS, 'WIN')) {
792 $backup_file = 'C:/windows/temp/setup_dump.sql';
793 } else {
794 $backup_file = '/tmp/setup_dump.sql';
797 return $backup_file;
802 This file is free software: you can redistribute it and/or modify it under the
803 terms of the GNU General Public License as publish by the Free Software
804 Foundation.
806 This file is distributed in the hope that it will be useful, but WITHOUT ANY
807 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
808 PARTICULAR PURPOSE. See the GNU Gneral Public License for more details.
810 You should have received a copy of the GNU General Public Licence along with
811 this file. If not see <http://www.gnu.org/licenses/>.