<?php  // MySql Database Restore Utility. Written By MrTwig (www.mrtwig.net) 

//#####################################################################################
//### Note to user: This is where you might want to set some variables permanently. ###
//#####################################################################################

$uservar_mysql_hostname    "";        
$uservar_mysql_username    "";
$uservar_mysql_password    "";
$uservar_mysql_database    "";
$uservar_mysql_filename    "";
$uservar_update_seconds    5;        

//######################################################################################
//### Note to user: Do not edit below, unless you know what you're doing, mmmkay..   ###
//######################################################################################


// find and/or set user variables
    
isset($_POST["mysql_hostname"])    ? $mysql_hostname    $_POST["mysql_hostname"]    : $mysql_hostname    $uservar_mysql_hostname;
    isset(
$_POST["mysql_username"])    ? $mysql_username    $_POST["mysql_username"]    : $mysql_username    $uservar_mysql_username;
    isset(
$_POST["mysql_password"])    ? $mysql_password    $_POST["mysql_password"]    : $mysql_password    $uservar_mysql_password;
    isset(
$_POST["mysql_database"])    ? $mysql_database    $_POST["mysql_database"]    : $mysql_database    $uservar_mysql_database;
    isset(
$_POST["fname"])            ? $fname            $_POST["fname"]            : $fname            $uservar_mysql_filename;

// Check db connection, change color & disable fields if (isset && true).
    
$db = @mysql_connect($mysql_hostname$mysql_username$mysql_password);
    
$db $db_set "readonly style=\"color:green;\"" $db_set false;

// Set chosen database if any.
    
$mysql_database_set = @mysql_select_db $mysql_database$db);
    
// Check if entered backup file exists & Get/set filesize of backup file
    
if(is_file($fname)){
        isset(
$_POST["fsize"]) ? $fsize $_POST["fsize"] : $fsize = @filesize($fname);
        
$fname_set " style=\"color:green;\"";
    }
    else{
        
$fname ="File not found!";
        
$fname_set=false;
    }
        
// Set other variables
    
$home $_SERVER["PHP_SELF"];

    isset(
$_POST["count_drop_database"])    ? $count_drop_database        $_POST["count_drop_database"]        : $count_drop_database        0;
    isset(
$_POST["count_create_database"])    ? $count_create_database    $_POST["count_create_database"]    : $count_create_database    0;
    isset(
$_POST["count_drop_table"])        ? $count_drop_table            $_POST["count_drop_table"]        : $count_drop_table            0;
    isset(
$_POST["count_create_table"])        ? $count_create_table        $_POST["count_create_table"]        : $count_create_table        0;
    isset(
$_POST["count_insert_into"])        ? $count_insert_into        $_POST["count_insert_into"]        : $count_insert_into        0;
    isset(
$_POST["count_update_table"])        ? $count_update_table        $_POST["count_update_table"]        : $count_update_table        0;
    isset(
$_POST["numofquerys"])            ? $numofquerys                $_POST["numofquerys"]                : $numofquerys                0;
    isset(
$_POST["errornum"])                ? $errornum                    $_POST["errornum"]                : $errornum                    0;
    isset(
$_POST["errorlog"])                ? $errorlog stripslashes(      $_POST["errorlog"])                : $errorlog                    ="";
    isset(
$_POST["use"])                    ? $use                        $_POST["use"]                        : $use                        "single";
    isset(
$_POST["time"])                    ? $time                        $_POST["time"]                    : $time                        0;

    
$max_execution_time ini_get('max_execution_time');
    if(
$uservar_update_seconds $max_execution_time){
        
ini_set('max_execution_time'$uservar_update_seconds+10) or  $uservar_update_seconds round($max_execution_time*9/10);
    }
// Start execution time calculator
    
function microtime_float(){
       list(
$usec$sec) = explode(" "microtime());
       return ((float)
$usec + (float)$sec);
    } 
    
$time_start microtime_float();

// Define xhtml code

$head "<?php xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" >
<head>
    <style>
        LEGEND        { font-variant:small-caps; font-weight:bold; font-size:90%; letter-spacing:1px; margin:0px 5px 5px; padding:0px;}
        FIELDSET    { margin:5px; padding:0px 10px 10px;}    
        LABEL        { font-size:80%; }
        INPUT.box    { padding-left:3px; border:solid 1px #000000; }
        LI            { margin:10px 0px; }
        DIV            { text-align:left; width:500px; margin:auto; padding:3px; border:solid 1px #000000; background-color:#dddddd; }
        DIV.c        { text-align:center; border:0px; padding:3px; background-color:#afc3d3; }
        SPAN.lnk    { font-variant:small-caps; font-weight:bold; font-size:100%; color:#000000;}
    </style>
    <script language=\"JavaScript\">
    <!--
        function formSubmit(){
            document.chunk.submit_button.value='Working, please wait!';
            document.chunk.submit(); 
        }
    //-->
    </script>
</head>
"
;

$bodytag "<body bgcolor=\"#afc3d3\">";

$header "
    <div class=\"c\">
        <div style=\"border:0px; padding-bottom:0px; background-color:#afc3d3;\">
            <table cellpadding=0 cellspacing=0 style=\"width:500px;\">
                <tr>
                    <td style=\"width:400px; padding-left:10px;\">
                        <a href=\"$home\"><span class=\"lnk\">MySql Database Restore Utility</span></a>
                    </td>
                    <td style=\"width:100px;\">"
;
                if(!isset(
$_POST["manual"])){
                    
$header .= "
                        <div style=\"border-bottom:0px; padding:0px; width:100px; text-align:center;\">                            
                            <form method=\"post\" action=\"$home\" style=\" padding:0px; margin:0px; \">
                                <input type=\"hidden\" name=\"manual\" value=\"1\" />
                                <input type=\"submit\" name=\"submit\" value=\"Read manual\" style=\"text-decoration:underline; cursor:hand; border: 0px; font-size:80%; font-face:veranda;   background-color:#dddddd; color:blue;  padding:0px;\" />
                            </form>
                        </div>
                "
;
                }
                else{
                    
$header .= "
                        &nbsp;
                    "
;
                }
                
$header .= 
                
"
                    </td>
                </tr>
            </table>
        </div>
        <div>
"
;
$footer="
        </div>
    </div>
</body>
</html>
"
;

// Write the manual & die, if $manual has been passed by form.
if(isset($_POST["manual"])){
    echo 
$head;
    echo 
$bodytag;
    echo 
$header;
    
?>
            <span style="font-size:80%;">
                <ul>
                    <li>This script takes a MySql database backup file, and runs every SQL query it finds.</li>
                    <li>To avoid having the script time-out due to exceeding the servers <b>max_execution_time</b> setting, and to provide the user with some feedback, this script will stop and restart at a set interval which is always less than max_execution_time. </li>
                    <li>To avoid failiure due to exceeding the set <b>max_memory_usage</b>, the script will do the parsing line by line. This way, no more than one query is ever loaded into memory at any given time. So unless you have querys larger than the servers memory allocation limit (usually 8-16 Mb), it will not fail.</li>
                    <li>Here are the 3 easy steps to backup &amp; restore your database(s).</li>
                        <ol>
                            <li>Create a backup of your database(s) using f.ex: the backup feature in cPanel or phpbb, or the export feature in phpMyAdmin. <br />Choose gzip compression to save time.</li>
                            <li>Upload the backup file and this script to your server.</li>
                            <li><a href="<?php  echo $home?>">Start this script.</a> Fill in the appropriate data and desired settings, and hit the &quot;Restore database&quot; button.</li>
                        </ol>
                    <li>If you wish, you can set default values by editing the source. <br />The variables you will want to set, are located at the top of the file.</li>
                </ul>
            </span>
    <?php 
    
echo $footer;
    die;
}
// Write the front page & die, if no filename has been passed by form.
    
if (!isset($_POST["fname"])) {
        echo 
$head;
        echo 
$bodytag;
        echo 
$header;
        
?>
            <form name="batch" method="post" action="<?php  echo $_SERVER['PHP_SELF']; ?>" onsubmit="document.batch.submit_button.value='Working! Please wait.';">
                <fieldset>
                    <legend>
                        Database connection
                    </legend>
                    <label title="Enter server hostname *required* " for="mysql_hostname">Hostname:</label>
                    <input <?php  echo $db_set;?> type="text" class="box" size="10" name="mysql_hostname" value="<?php  echo $mysql_hostname;?>" />
                    
                    <label title="Enter MySql username *required* " for="mysql_username">Username:</label>
                    <input <?php  echo $db_set;?> type="text" class="box" size="10" name="mysql_username" value="<?php  echo $mysql_username;?>" />
                    <label title="Enter MySql password if any" for="mysql_password">Password:</label>
                    <input <?php  echo $db_set;?> type="password" class="box" size="10" name="mysql_password" value="<?php  echo $mysql_password;?>" />
                </fieldset>
                <fieldset>
                    <legend>Restore What</legend>
                    <label title="Relative path to a file on the same server as this script." for="fname">
                        Backup file path/name (gzip or ascii):
                    </label>
                    <input  <?php  echo $fname_set;?> type="text" class="box" size="35" name="fname" value="<?php echo $fname;?>" onfocus="this.style.color='#000000';" />
                </fieldset>
                <fieldset>
                    <legend>Restore To</legend>    
                    <input type="radio" name="use" id="single" value="single" checked onclick="document.batch.mysql_database.disabled=false;  document.batch.submit_button.value='Restore Database';" />
                    <label title="If single, name of database to restore into " for="single">
                        Choose database to restore into:
                    </label>
                    <select  class="box" name="mysql_database">
                        <option value="not_set" <?php if($mysql_database==""){ echo "selected ";} ?>>..Choose database..</option>
                    <?php 
                        $db_list 
mysql_list_dbs($db);
                        while (
$row mysql_fetch_object($db_list)) {
                            
$db_name $row->Database;
                            
$db_name == $mysql_database $selected="selected"$selected="";
                            echo 
"\t<option value=\"$db_name\" $selected style=\"color:green\">$db_name</option>\n\t\t\t\t\t";
                        }
                        echo 
"</select>\n";
                    
?>
                    <br />
                    <input type="radio" name="use" id="multiple" value="multiple" onclick="document.batch.mysql_database.disabled=true; document.batch.submit_button.value='Restore All Databases'; document.batch.skip_use.checked=false;" />
                    <label title="If multiple, leave it to SQL 'USE' commands." for="multiple">
                        If multiple databases, leave it to SQL "USE" querys in the backup file.
                    </label>                        
                </fieldset>
                <fieldset>
                    <legend>Skip querys</legend>    
                    <input type="checkbox" checked name="skip_drop_database" id="skip_drop_database" />
                    <label title="No 'DROP DATABASE' querys will be performed if checked." for="skip_drop_database">
                        Skip all "DROP DATABASE" querys.
                    </label><br />
                    <input type="checkbox" checked name="skip_create_database" id="skip_create_database" />
                    <label title="No 'CREATE DATABASE' querys will be performed if checked." for="skip_create_database">
                        Skip all "CREATE DATABASE" querys.
                    </label><br />
                    <input type="checkbox" name="skip_use" id="skip_use" onclick="document.batch.use[0].checked=true; document.batch.mysql_database.disabled=false; document.batch.submit_button.value='Restore&nbsp;Database';" />
                    <label title="No 'USE' querys will be performed if checked." for="skip_use">
                        Skip all "USE" querys.
                    </label><br />
                    <input type="checkbox" name="skip_drop_table" id="skip_drop_table"/>
                    <label title="No 'DROP TABLE' querys will be performed if checked." for="skip_drop_table">
                        Skip all "DROP TABLE" querys.
                    </label><br />
                    <input type="checkbox" name="skip_create_table" id="skip_create_table" />
                    <label title="No 'CREATE TABLE' querys will be performed if checked." for="skip_create_table">
                        Skip all "CREATE TABLE" querys.
                    </label><br />
                    <input type="checkbox" name="skip_insert" id="skip_insert" />
                    <label title="No 'INSERT' querys will be performed if checked." for="skip_insert">
                        Skip all "INSERT" querys.
                    </label><br />
                    <input type="checkbox" name="skip_update" id="skip_update" />
                    <label title="No 'UPDATE' querys will be performed if checked." for="skip_update">
                        Skip all "UPDATE" querys.
                    </label><br />
                </fieldset>
                <div class="c" style="background-color:#dddddd; padding: 10px 0px 0px;">
                    <input type="submit" name="submit_button" value="Restore Database" style="border:solid #000000 1px; font-variant:small-caps; font-weight:bold; letter-spacing:1px; background-color:#afc3d3;" />
                </div>
            </form>
        <?php 
        
echo $footer;
        die;
    }

// Check if database and file is ok.
    
if($db_set == false){die("$head$bodytag$header\t\t\tError: Invalid database connection. Check your host ( $mysql_hostname ), username ( $mysql_username )& password.( *hidden* )<br />\n$footer");}
    if(
$mysql_database_set == false){die("$head$bodytag$header\t\t\tError: Could not connect to database ( $mysql_database )<br />\n".mysql_error($db).$footer);}
    if(
$fname_set == false){die("$head$bodytag$header\t\t\tError: Backup file ( $fname ) was not found on server.$footer");}

// Start reading chunks and doing the querys
    
$fp gzopen($fname "r");

// sets cursor to offset passed by form, I.E. Continues where it left off.
    
isset( $_POST["offset"] ) ? $offset $_POST["offset"] : $offset false;
    if(
$offset){gzseek($fp$offset);}
    while (!
gzeof($fp)) {
        
$end_of_file=true;
        if(
gztell($fp)==0){$first_line=1;}
        
$line gzgets($fp);
        
$offset gztell($fp);

    
// Is this line a query or a comment?    
        
$firstsubstr($line0,1);
        if(
$first!="-" && $first!="" && $first!="#" ){
            
$query.=trim($line);

        
// Is this the whole query?  If so, do the query & stats.
            
if(substr($query,-1,1)==";"){

            
// the use thang, update $mysql_database var, or discard query.
                
if(substr($query 13 )    == "DROP DATABASE"){
                     isset(
$skip_drop_database) ? $query=false $count_drop_database++; ;
                }
                if(
substr($query 15 )    == "CREATE DATABASE"){
                     isset(
$skip_create_database) ? $query=false $count_create_database++; ;
                }
                if(
substr($query 10) == "DROP TABLE"){
                     isset(
$skip_drop_table) ? $query=false $count_drop_table++; ;
                }
                if(
substr($query 12 )    == "CREATE TABLE"){
                     isset(
$skip_create_table) ? $query=false $count_create_table++; ;
                }
                if(
substr($query )    == "INSERT"){
                     isset(
$skip_insert) ? $query=false $count_insert++; ;
                }
                if(
substr($query )    == "UPDATE"){
                     isset(
$skip_update) ? $query=false $count_update++; ;
                }
                if(
substr($query )    == "USE"){
                    if(isset(
$skip_use) || $use=="single"){
                        
$query=false;
                    }
                    else if(
$use=="multiple"){
                        
$mysql_database substr($query strlen($query)-);
                    }
                }

                if(
$query){
                    
$result mysql_query($query);
                    if(
$result){$numofquerys++;}
                    else{ 
// Error handling
                        
$errornum++;
                        if(
$errornum<11){
                            
$errorlog .= mysql_errno($db) . ": " mysql_error($db) . "<br>\n";
                        }
                    }
                }
                
$query="";
            }    
        }
        
$time microtime_float() - $time_start;
        if(
$time $uservar_update_seconds || $first_line == 1){
            
$end_of_file=false;
            break;
        }
    }
    
$totaltime round($_POST["time"] + $time);
    
gzclose($fp);

    
$end_of_file == false $onload " onload=\"formSubmit();\">" $onload ">" 
    echo 
"$head <body bgcolor=\"#afc3d3\"$onload $header";
    echo 
"Restoring <b>$fname (".round($fsize/1024/1024 1)."</b> Mb) to database: <b>$mysql_database</b> <br />\n";
    echo 
"Restored <b>$bytecount</b> bytes of <b>$fname</b> <br />\n";
    if( 
$errornum ) {
        echo 
"Unsuccessful querys: <b>$errornum</b> <br />\n";
        echo 
"<div style=\"background-color:b8b8b8\">Error log, showing the first 10 errors: <br />\n<span style=\"font-size:70%; font-weight:bold font-family:veranda;\">$errorlog</span> \n</div>\n";
    }
    echo 
"Querys performed: <b>$numofquerys</b> <br />\n";
    echo 
"DROP DATABASE: <b>$count_drop_database</b> <br />\n";
    echo 
"CREATE DATABASE: <b>$count_create_database</b> <br />\n";
    echo 
"DROP TABLE: <b>$count_drop_table</b> <br />\n";
    echo 
"CREATE TABLE: <b>$count_create_table</b> <br />\n";
    echo 
"INSERT: <b>$count_insert</b> <br />\n";
    echo 
"UPDATE: <b>$count_update</b> <br />\n";
    echo 
"Reload every: <b>$uservar_update_seconds</b> seconds<br />\n";
    echo 
"Total cpu time used: <b>$totaltime</b> seconds<br />\n";    
?>

<span style="text-align:center;">
    <form name="chunk" method="post" action="<?php  echo $_SERVER['PHP_SELF']; ?>">
        <input type="hidden" name="mysql_host"                value="<?php  echo $mysql_host?>" />
        <input type="hidden" name="mysql_username"            value="<?php  echo $mysql_username?>" />
        <input type="hidden" name="mysql_password"            value="<?php  echo $mysql_password?>" />
        <input type="hidden" name="mysql_database"            value="<?php  echo $mysql_database?>" />
        <input type="hidden" name="fname"                    value="<?php  echo $fname?>" />
        <input type="hidden" name="use"                        value="<?php  echo $use?>" />
        <input type="hidden" name="fsize"                    value="<?php  echo $fsize?>" />
        <input type="hidden" name="offset"                    value="<?php  echo $offset?>" />
        <input type="hidden" name="numofquerys"                value="<?php  echo $numofquerys?>" />
        <input type="hidden" name="errornum"                value="<?php  echo $errornum?>" />
        <input type="hidden" name="count_drop_database"        value="<?php  echo $count_drop_database?>" />
        <input type="hidden" name="count_create_database"    value="<?php  echo $count_create_database?>" />
        <input type="hidden" name="count_drop_table"        value="<?php  echo $count_drop_table?>" />
        <input type="hidden" name="count_create_table"        value="<?php  echo $count_create_table?>" />
        <input type="hidden" name="count_insert"            value="<?php  echo $count_insert?>" />
        <input type="hidden" name="count_update"            value="<?php  echo $count_update?>" />
        <input type="hidden" name="time"                    value="<?php  echo $totaltime?>" />
        <input type="hidden" name="errorlog"                value="<?php  echo $errorlog?>" />
<?php 
    
if(isset($_POST["skip_drop_database"] ) ) { 
        echo 
"<input type=\"hidden\" name=\"skip_drop_database\" value=\"on\" />\n";
    } 
    if(isset(
$_POST["skip_create_database"] ) ) { 
        echo 
"<input type=\"hidden\" name=\"skip_create_database\" value=\"on\" />\n";
    } 
    if(isset(
$_POST["skip_use"] ) ) { 
        echo 
"<input type=\"hidden\" name=\"skip_use\" value=\"on\" />\n";
    } 
    if(isset(
$_POST["skip_drop_table"] ) ) { 
        echo 
"<input type=\"hidden\" name=\"skip_drop_table\" value=\"on\" />\n";
    } 
    if(isset(
$_POST["skip_create_table"] ) ) { 
        echo 
"<input type=\"hidden\" name=\"skip_create_table\" value=\"on\" />\n";
    } 
    if(isset(
$_POST["skip_insert"] ) ) { 
        echo 
"<input type=\"hidden\" name=\"skip_insert\" value=\"on\" />\n";
    } 
    if(isset(
$_POST["skip_update"] ) ) { 
        echo 
"<input type=\"hidden\" name=\"skip_update\" value=\"on\" />";
    } 
    if(
$end_of_file==false){
        echo 
"<input type=\"submit\" name=\"submit_button\"    value=\"Do next chunk\" style=\"border:solid #000000 1px; font-variant:small-caps; font-weight:bold; letter-spacing:1px;\" />";
    }
    else{
        
$use=="multiple" $s="s"$s="";
        
$errornum==$bgcolor="green"$bgcolor="red";
        echo 
"<input type=\"button\" name=\"fake\"value=\"Database$s restored with $errornum errors\" style=\"border:solid #000000 1px; font-variant:small-caps; font-weight:bold; letter-spacing:1px; background-color:$bgcolor\" />";
    }
    echo 
"</form></span>$footer";
    
?>