<?

/*
 * This file is part of the 'Science Fair In A Box' project
 * SFIAB Website: http://www.sfiab.ca
 *
 * Copyright (C) 2008 James Grant <james@lightbox.org>
 *
 * 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 the Free Software Foundation, version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
?>
<?
require ('../common.inc.php');
require_once ('../user.inc.php');
user_auth_required('committee', 'config');

// make sure backup/restore folder exists, and htaccess it to deny access
if (!file_exists('../data/backuprestore'))
	mkdir('../data/backuprestore');
if (!file_exists('../data/backuprestore/.htaccess'))
	file_put_contents('../data/backuprestore/.htaccess', "Order Deny,Allow\r\nDeny From All\r\n");

if (get_value_from_array($_GET, 'action') == 'backup') {
	$ts = time();
	$dump = '#SFIAB SQL BACKUP: ' . date('r', $ts) . "\n";
	$dump .= '#SFIAB VERSION: ' . $config['version'] . "\n";
	$dump .= '#SFIAB DB VERSION: ' . $config['DBVERSION'] . "\n";
	$dump .= '#SFIAB FAIR NAME: ' . $config['fairname'] . "\n";
	$dump .= "#-------------------------------------------------\n";

	$tableq = $pdo->prepare("SHOW TABLES FROM `$DBNAME`");
	$tableq->execute();
	while ($tr = $tableq->fetch(PDO::FETCH_NUM)) {
		$table = $tr[0];
		$dump .= "#TABLE: $table\n";
		$columnq = $pdo->prepare("SHOW COLUMNS FROM `$table`");
		$columnq->execute();
		$str = "INSERT INTO `$table` (";
		unset($fields);
		$fields = array();
		while ($cr = $columnq->fetch(PDO::FETCH_OBJ)) {
			$str .= '`' . $cr->Field . '`,';
			$fields[] = $cr->Field;
		}
		$str = substr($str, 0, -1);
		$str .= ') VALUES (';

		$dataq = $pdo->prepare("SELECT * FROM `$table` ORDER BY `{$fields[0]}`");
		$dataq->execute();
		while ($data = $dataq->fetch(PDO::FETCH_OBJ)) {
			$insertstr = $str;
			foreach ($fields AS $field) {
				if (is_null($data->$field))
					$insertstr .= 'NULL,';
				else {
					$escaped = str_replace('\\', '\\\\', $data->$field);
					$escaped = str_replace("'", "''", $escaped);
					$escaped = str_replace("\n", '\n', $escaped);
					$escaped = str_replace("\r", '\r', $escaped);
					$insertstr .= "'" . $escaped . "',";
				}
			}
			$insertstr = substr($insertstr, 0, -1);
			$insertstr .= ');';

			$dump .= $insertstr . "\n";
		}
	}
	header('Content-Type: text/sql');
	header('Content-Disposition: attachment; filename=sfiab_backup_' . date('Y-m-d-H-i-s', $ts) . '.sql');
	header('Content-Length: ' . strlen($dump));
	// Make IE with SSL work
	header('Pragma: public');
	echo $dump;
} else if (get_value_from_array($_POST, 'action') == 'restore') {
	echo send_header('Database Backup/Restore',
		array('Committee Main' => 'committee_main.php',
			'SFIAB Configuration' => 'config/index.php'),
		'backup_restore');
	echo i18n('Processing file: %1', array($_FILES['restore']['name'])) . "<br />\n";
	echo "<br />\n";
	do {
		// hmm just some random filename
		$tmpfilename = md5(rand() . time() . $_FILES['restore']['name']);
	} while (file_exists("../data/backuprestore/$tmpfilename"));

	move_uploaded_file($_FILES['restore']['tmp_name'], "../data/backuprestore/$tmpfilename");

	$fp = fopen("../data/backuprestore/$tmpfilename", 'r');

	for ($x = 0; $x < 4; $x++) {
		$line = fgets($fp, 1024);
		$hdr[$x] = split(':', trim($line), 2);
	}
	fclose($fp);

	if (trim($hdr[0][0]) == '#SFIAB SQL BACKUP') {
		echo "<table class=\"tableview\">\n";
		$now = date('r');
		echo '<tr><th>' . i18n('Information') . '</th><th>' . i18n('Restore File') . '</th><th>' . i18n('Live System') . "</th></tr>\n";
		if (trim($hdr[0][1]) < trim($now))
			$cl = 'happy';
		else {
			$cl = 'error';
			$err = true;
		}
		echo "<tr class=\"$cl\"><td>" . i18n('Date/Time') . '</td><td>' . $hdr[0][1] . "</td><td>$now</td></tr>\n";
		if (version_compare(trim($hdr[1][1]), $config['version']) == 0)
			$cl = 'happy';
		else {
			$cl = 'error';
			$err = true;
		}
		echo "<tr class=\"$cl\"><td>" . i18n('SFIAB Version') . '</td><td>' . $hdr[1][1] . '</td><td>' . $config['version'] . "</td></tr>\n";
		if (version_compare(trim($hdr[2][1]), $config['DBVERSION']) == 0)
			$cl = 'happy';
		else {
			$cl = 'error';
			$err = true;
		}
		echo "<tr class=\"$cl\"><td>" . i18n('Database Version') . '</td><td>' . $hdr[2][1] . '</td><td>' . $config['DBVERSION'] . "</td></tr>\n";
		if (trim($hdr[3][1]) == $config['fairname'])
			$cl = 'happy';
		else {
			$cl = 'error';
			$err = true;
		}
		echo "<tr class=\"$cl\"><td>" . i18n('Fair Name') . '</td><td>' . $hdr[3][1] . '</td><td>' . $config['fairname'] . "</td></tr>\n";
		echo "</table>\n";
		echo "<br />\n";
		if ($err) {
			echo error(i18n('Warning, there are discrepencies between the restore file and your current live system. Proceed at your own risk!'));
		}

		echo "<form method=\"post\" action=\"backuprestore.php\">\n";
		echo "<input type=\"hidden\" name=\"action\" value=\"restoreproceed\">\n";
		echo '<input type="hidden" name="filename" value="' . $_FILES['restore']['name'] . "\">\n";
		echo "<input type=\"hidden\" name=\"realfilename\" value=\"$tmpfilename\">\n";
		echo '<input type="submit" value="' . i18n('Proceed with Database Restore') . '">';
		echo "</form>\n";
		echo "<br />\n";
		echo '<a href="backuprestore.php">';
		echo i18n('If you are not going to proceed, please click here to clean up the temporary files which may contain confidential information!');
		echo "</a>\n";
	} else {
		echo error(i18n('This file is NOT a SFIAB SQL BACKUP file'));
		echo i18n('Only backups created with the SFIAB Backup Creator can be used to restore from.');
		echo "<br />\n";
	}

	send_footer();
} else if (get_value_from_array($_POST, 'action') == 'restoreproceed') {
	echo send_header('Database Backup/Restore',
		array('Committee Main' => 'committee_main.php',
			'SFIAB Configuration' => 'config/index.php'),
		'backup_restore');

	// make sure the filename's good before we used it
	if (mb_ereg('^[a-z0-9]{32}$', $_POST['realfilename']) && file_exists('../data/backuprestore/' . $_POST['realfilename'])) {
		$filename = $_POST['realfilename'];
		echo i18n('Proceeding with database restore from %1', array($_POST['filename'])) . '...';
		$lines = file("../data/backuprestore/$filename");
		$err = false;
		echo '<pre>';
		foreach ($lines AS $line) {
			$line = trim($line);
			if (mb_ereg('^#TABLE: (.*)', $line, $args)) {
				// empty out the table
				$sql = 'TRUNCATE TABLE `' . $args[1] . '`';
				//			echo $sql."\n";

				$stmt = $pdo->prepare($sql);
				$stmt->execute();
			} else if (mb_ereg('^#', $line)) {
				// just skip it
			} else {
				// insert the new data

				$stmt = $pdo->prepare($line);
				$stmt->execute();
				if ($pdo->errorInfo()) {
					echo $line . "\n";
					echo $pdo->errorInfo() . "\n";
					$err = true;
				}
			}
		}
		echo '</pre>';
		if ($err) {
			echo error(i18n('An error occured while importing the restore database'));
		} else
			echo happy(i18n('Database successfully restored'));

		unlink("../data/backuprestore/$filename");
	} else
		echo error(i18n('Invalid filename'));

	send_footer();
} else if (get_value_from_array($_POST, 'action') == 'clean_judges') {
	// select all judges
	$query = $pdo->prepare('SELECT * FROM users WHERE types LIKE "judge"');
	$query->execute();
	show_pdo_errors_if_any($pdo);

	// Go through each judge and test:
	while ($judge = $query->fetch(PDO::FETCH_ASSOC)) {
		// if they are deleted
		if ($judge['deleted'] == 'yes') {
			// Make types an array if it isn't already. Allows user_purge function to work properly
			if (!is_array($judge['types'])) {
				$judge['types'] = array($judge['types']);
			}

			user_purge($judge, 'judge');
		} else {
			// Find max year of judge
			$max_year_query = $pdo->prepare('SELECT year FROM users WHERE uid = ' . $judge['uid'] . ' ORDER BY year DESC limit 1');
			$max_year_query->execute();
			$judge_max_year = $max_year_query->fetch(PDO::FETCH_ASSOC);
			// Grab old judge info.
			// Old judge info consists of all entries in the database that are not the most recent for the specific judge
			$deletable = $pdo->prepare('SELECT * FROM users WHERE uid =' . $judge['uid'] . ' AND year NOT LIKE ' . $judge_max_year['year']);
			$deletable->execute();
			// and if they have old data from previous fair years
			if ($deletable->rowCount() > 0) {
				// delete old data one by one
				while ($old_judge_data = $deletable->fetch(PDO::FETCH_ASSOC)) {
					if (!isset($old_judge_data['type']) && !is_array($old_judge_data['type'])) {
						$old_judge_data['types'] = array($old_judge_data['types']);
					}
					user_purge($old_judge_data, 'judge');
				}
			}
		}
	}

	echo send_header('Database Backup/Restore',
		array('Committee Main' => 'committee_main.php',
			'SFIAB Configuration' => 'config/index.php'),
		'backup_restore');

	$stmt = $pdo->prepare('OPTIMIZE TABLE users, users_judge');
	$stmt->execute();

	if ($pdo->errorInfo()[0] == 0) {
		echo happy(i18n('Old judge data purged.'));
	} else {
		error(i18n($pdo->errorInfo()[0]));
	}
} else if (get_value_from_array($_POST, 'action') == 'clean_parents') {
	$query_parents = $pdo->prepare('SELECT * FROM users WHERE types LIKE "parent" AND year !=' . $config['FAIRYEAR']);
	$query_parents->execute();
	while ($parent = $query_parents->fetch(PDO::FETCH_ASSOC)) {
		if (!is_array($parent['types'])) {
			$parent['types'] = array($parent['types']);
		}

		user_purge($parent, 'parent');
	}

	echo send_header('Database Backup/Restore',
		array('Committee Main' => 'committee_main.php',
			'SFIAB Configuration' => 'config/index.php'),
		'backup_restore');

	$stmt = $pdo->prepare('OPTIMIZE TABLE users, users_parent');
	$stmt->execute();

	if ($pdo->errorInfo()[0] == 0) {
		echo happy(i18n('Old parent data purged.'));
	} else {
		error(i18n($pdo->errorInfo()[0]));
	}
} else {
	echo send_header('Database Backup/Restore',
		array('Committee Main' => 'committee_main.php',
			'SFIAB Configuration' => 'config/index.php'),
		'backup_restore');

	// we try to remove temp files every time we load this page, who knows, maybe they navigated away
	// last time instead of clicking the link to come back here
	$dh = opendir('../data/backuprestore');
	$removed = false;
	while ($fn = readdir($dh)) {
		if (mb_ereg('[a-z0-9]{32}', $fn)) {
			unlink("../data/backuprestore/$fn");
			$removed = true;
		}
	}
	closedir($dh);

	if ($removed) {
		echo happy(i18n('Temporary files successfully removed'));
	}

	echo '<h3>' . i18n('Backup Database') . "</h3>\n";
	echo '<a href="backuprestore.php?action=backup">' . i18n('Create Database Backup File') . "</a><br />\n";
	echo "<br /><br />\n";
	echo "<hr />\n";

	echo '<h3>' . i18n('Restore Database') . "</h3>\n";
	echo error(i18n('WARNING: Importing a backup will completely DESTROY all data currently in the database and replace it with what is in the backup file'));
	echo "<form method=\"post\" action=\"backuprestore.php\" enctype=\"multipart/form-data\">\n";
	echo "<input type=\"hidden\" name=\"action\" value=\"restore\">\n";
	echo "<input type=\"file\" name=\"restore\">\n";
	echo '<input type="submit" value="' . i18n('Upload Restore File') . "\">\n";
	echo "</form>\n";

	echo '<br>';
	echo '<h3>' . i18n('Clean Database') . "</h3>\n";
	echo error(i18n('WARNING: Cleaning the database COMPLETELY DELETES old data on users'));

	echo '<font size = 4 color="red"> RECOMMENDED: Backup database before using the below buttons</font><br><br>';

	echo "<font color=\"red\"> Remove Old Judge Data <ul>  <li> All information about who has judged in past fairs will be lost
\t                                                       <li> All deleted judges will be purged from the system </ul></font>";

	echo "<br><font color=\"red\"> Remove Old Emergency Contact / Parent Data<ul> <li> All parent information or other emergency contact information from all previous fair years will be purged from the system
\t                               \t\t\t\t\t\t\t\t\t\t\t\t<li> It will no longer be possible to email any emergency contacts from previous fair years once the button is clicked </ul></font><br>";
	echo '<table>';
	echo '<tr><td style = "width: 46%">';
	echo "<form method=\"post\" action=\"backuprestore.php\" enctype=\"multipart/form-data\">\n";
	echo "<input type=\"hidden\" name=\"action\" value=\"clean_judges\">\n";
	echo '<input type="submit" onClick="return confirmClick(\'Are you sure you wish to purge old judge data?\')" value="' . i18n('Remove Old Judge Data') . "\">\n";
	echo '</form>';
	echo '</td><td>';

	echo "<form method=\"post\" action=\"backuprestore.php\" enctype=\"multipart/form-data\">\n";
	echo "<input type=\"hidden\" name=\"action\" value=\"clean_parents\">\n";
	echo '<input type="submit" onClick="return confirmClick(\'Are you sure you wish to purge old parent data?\')" value="' . i18n('Remove Old Emergency Contact / Parent Data') . "\">\n";
	echo '</form>';

	send_footer();
}

?>