<?php

/*
 * @name        JMY CMS
 * @link        https://jmy.su/
 * @copyright   Copyright (C) 2012-2025 JMY LTD
 * @license     LICENSE.txt (see attached file)
 * @version     VERSION.txt (see attached file)
 * @author      Komarov Ivan
 * @edited      Orlov Alexsey
 * @outside     MySQL DB restore class, version 1.0.0
 */

const MSR_VERSION = '1.0.0';
const MSR_STRING = 0;
const MSR_FILE = 1;

class MySQL_Restore
{
    var $server = 'localhost';
    var $port = 3306;
    var $username = 'root';
    var $password = '';
    var $database = '';
    var $characters = '';
    var $link_id = -1;
    var $connected = false;
    var $tables = array();
    var $create_tables = true;
    var $drop_tables = true;
    var $struct_only = false;
    var $locks = true;
    var $comments = true;
    var $backup_dir = '';
    var $fname_format = 'd_m_y__H_i_s';
    var $error = '';
    var $null_values = array('0000-00-00', '00:00:00', '0000-00-00 00:00:00');
    var $queries = array();

    function Execute($param, $mode = MSR_STRING, $is_compressed = false, $split_only = false)
    {
        if ($mode == MSR_FILE) {
            if (!($sql = $this->_ReadFromFile($param, $is_compressed))) {
                $this->error = 'Can\'t read backup file.';
                return false;
            }
        } else {
            $sql = ($is_compressed ? gzuncompress($param) : $param);
        }
        return $this->_Restore($sql, $split_only);
    }

    function _ReadFromFile($fname, $is_compressed)
    {
        $sql = $is_compressed ? gzfile($fname) : file($fname);
        if ($sql === false) return false;
        return implode('', $sql);
    }

    function _Restore($sql, $split_only)
    {
        if (!$this->_Connect()) return false;
        if (!$this->_Decompose($queries, $sql)) return false;
        $errors = '';
        $this->queries = array();
        foreach ($queries as $query) {
            $this->queries[] = $query['query'];
            if (!$split_only) {
                if (!$this->_Query($query['query'])) $errors .= $this->error . '<br /><br />';
            }
        }
        if (!empty($errors)) {
            $this_error = $errors;
            return false;
        }
        return true;
    }

    // The logic from phpMyAdmin source
    function _Connect()
    {
        $value = false;
        if (!$this->connected) {
            if (!$this->server) $this->server = 'localhost';
            $host = $this->server;
            if ($this->port) $host .= ':' . $this->port;
            $this->link_id = mysqli_connect($host, $this->username, $this->password);
        }
        if (!empty($this->link_id) > 0) {
            if (empty($this->database)) {
                $value = true;
            } elseif ($this->link_id !== -1) {
                $value = mysqli_select_db($this->link_id, $this->database);
                $value = mysqli_query($this->link_id, 'SET NAMES ' . $this->characters);
            } else {
                $value = mysql_select_db($this->database);
                $value = mysql_query('SET NAMES ' . $this->characters);
            }
        }
        if (!$value) $this->error = mysql_error();
        return $value;
    }

    function _Decompose(&$ret, $sql)
    {
        $sql = rtrim($sql, "\n\r");
        $sql_len = mb_strlen($sql);
        $char = '';
        $string_start = '';
        $in_string = false;
        $nothing = true;
        $time0 = time();
        for ($i = 0; $i < $sql_len; ++$i) {
            $char = $sql[$i];
            if ($in_string) {
                for (; ;) {
                    $i = strpos($sql, $string_start, $i);
                    if (!$i) {
                        $ret[] = $sql;
                        return true;
                    } elseif ($string_start == '`' || $sql[$i - 1] != '\\') {
                        $string_start = '';
                        $in_string = false;
                        break;
                    } else {
                        $j = 2;
                        $escaped_backslash = false;
                        while ($i - $j > 0 && $sql[$i - $j] == '\\') {
                            $escaped_backslash = !$escaped_backslash;
                            $j++;
                        }
                        if ($escaped_backslash) {
                            $string_start = '';
                            $in_string = false;
                            break;
                        } else {
                            $i++;
                        }
                    }
                }
            } else if (($char == '-' && $sql_len > $i + 2 && $sql[$i + 1] == '-' &&
                    $sql[$i + 2] <= ' ') || $char == '#' ||
                ($char == '/' && $sql_len > $i + 1 && $sql[$i + 1] == '*')
            ) {
                $comm_end = ($char == '/' ? '*/' : "\n");
                $i = strpos($sql, $comm_end, $i);
                if ($i === false) break;
                if ($char == '/') $i++;
            } else if ($char == ';') {
                $ret[] = array('query' => mb_substr($sql, 0, $i), 'empty' => $nothing);
                $nothing = true;
                $sql = ltrim(mb_substr($sql, min($i + 1, $sql_len)));
                $sql_len = mb_strlen($sql);
                if ($sql_len) {
                    $i = -1;
                } else {
                    return true;
                }
            } else if (($char == '"') || ($char == '\'') || ($char == '`')) {
                $in_string = true;
                $nothing = false;
                $string_start = $char;
            } elseif ($nothing) {
                $nothing = false;
            }
            $time1 = time();
            if ($time1 >= $time0 + 30) {
                $time0 = $time1;
                @header('X-pmaPing: Pong');
            }
        }
        if (!empty($sql) && preg_match('@[^[:space:]]+@', $sql)) $ret[] = array('query' => $sql, 'empty' => $nothing);
        return true;
    }

    function _Query($sql)
    {
        $result = $this->link_id !== -1 ? mysqli_query($this->link_id, $sql) : mysql_query($sql);
        if (!$result) $this->error = mysqli_error($this->link_id);
        return $result;
    }
}

?>