Вход Регистрация
Файл: CMS/core/classes/dump.class.php
Строк: 294
<?php

if (!defined('CMS')) { die('Access Denied!'); }

//error_reporting( E_ALL );
//ini_set( 'display_errors', 1 );
//ini_set( 'html_errors', false );
//ini_set( 'error_log', 'error.log' );

// Максимальное время выполнения скрипта в секундах
// 0 - без ограничений
define('TIME_LIMIT'0);
// Ограничение размера данных доставаемых за одно обращения к БД (в мегабайтах)
// Нужно для ограничения количества памяти пожираемой сервером при дампе очень объемных таблиц
define('LIMIT'1);
// mysql сервер
define('DBHOST''localhost:3306');
// Базы данных, если сервер не разрешает просматривать список баз данных,
// и ничего не показывается после авторизации. Перечислите названия через запятую
define('DBNAMES''');
// Кодировка соединения с MySQL
// auto - автоматический выбор (устанавливается кодировка таблицы), cp1251 - windows-1251, и т.п.
define('CHARSET''auto');
// Кодировка соединения с MySQL при восстановлении
// На случай переноса со старых версий MySQL (до 4.1), у которых не указана кодировка таблиц в дампе
// При добавлении 'forced->', к примеру 'forced->cp1251', кодировка таблиц при восстановлении будет принудительно заменена на cp1251
// Можно также указывать сравнение нужное к примеру 'cp1251_ukrainian_ci' или 'forced->cp1251_ukrainian_ci'
define('RESTORE_CHARSET''cp1251');
// Включить сохранение настроек и последних действий
// Для отключения установить значение 0
define('SC'1);
// Типы таблиц у которых сохраняется только структура, разделенные запятой
define('ONLY_CREATE''MRG_MyISAM,MERGE,HEAP,MEMORY');
// Глобальная статистика
// Для отключения установить значение 0
define('GS'1);

if (!
defined('DS')) define('DS''/');

// Дальше ничего редактировать не нужно

$is_safe_mode ini_get('safe_mode') == '1' 0;
if (!
$is_safe_mode && function_exists('set_time_limit')) set_time_limit(TIME_LIMIT);

header('Expires: Tue, 1 Jul 2003 05:00:00 GMT');
header('Last-Modified: ' gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');

class 
dumper {

    var 
$connect_id;
    var 
$rootpath;
    var 
$stat;

    function 
dumper($rootpath ''$stat true) {

        global 
$config;

        
$this->connect_id = @mysql_connect($config['db_host'], $config['db_user'], $config['db_pass']);

        if( 
$rootpath == '' ) {

            
$rootpath './';
        }

        
$this->rootpath $rootpath;

        
$this->SET['show_stat']       = $stat;
        
$this->SET['last_action']     = 0;
        
$this->SET['last_db_backup']  = '';
        
$this->SET['tables']          = '';
        
$this->SET['comp_method']     = 2;
        
$this->SET['comp_level']      = 9;
        
$this->SET['last_db_restore'] = '';

        
$this->tabs    0;
        
$this->records 0;
        
$this->size    0;
        
$this->comp    0;

        
// Версия MySQL вида 40101
        
preg_match("/^(d+).(d+).(d+)/"mysql_get_server_info(), $m);
        
$this->mysql_version sprintf("%d%02d%02d"$m[1], $m[2], $m[3]);

        
$this->only_create explode(','ONLY_CREATE);
        
$this->forced_charset  false;
        
$this->restore_charset $this->restore_collate '';

        if (
preg_match("/^(forced->)?(([a-z0-9]+)(_w+)?)$/"RESTORE_CHARSET$matches)) {

            
$this->forced_charset  $matches[1] == 'forced->';
            
$this->restore_charset $matches[3];
            
$this->restore_collate = !empty($matches[4]) ? ' COLLATE ' $matches[2] : '';
        }
    }

    function 
backup($tbName ''$dbName ''$dbMethod 1$dbLevel 9) {

        global 
$config;

        if (!
$this->connect_id) {

            die(
'ОШИБКА! Нет соединения с базой данных!');
        }

        if (!
$this->rootpath) {

            die(
'ОШИБКА! Путь к папке не найден!');
        }

        
$this->SET['last_action']     = 0;
        
$this->SET['comp_level']      = !empty($dbLevel) ? intval($dbLevel) : 0;
        
$this->SET['comp_method']     = !empty($dbMethod) ? intval($dbMethod) : 0;
        
$this->SET['last_db_backup']  = !empty($dbName) ? $dbName $config['db_name'];
        
$this->SET['tables_exclude']  = !empty($tbName) ? 0;
        
$this->SET['tables']          = !empty($tbName) ? $tbName '';

        
$this->fn_save();

        if (!empty(
$this->SET['tables'])) {

            
$this->SET['tables'] = explode(','$this->SET['tables']);

            foreach(
$this->SET['tables'] AS $table) {

                
$table preg_replace("/[^w*?^]/"""$table);
                
$pattern = array( "/?/""/*/");
                
$replace = array( "."".*?");
                
$tbls[] = preg_replace($pattern$replace$table);
            }

        }
        else 
$this->SET['tables_exclude'] = 1;

        if (
$this->SET['comp_level'] == 0) { $this->SET['comp_method'] = 0; }

        
$db $this->SET['last_db_backup'];

        if (!
$db) {

            die(
'ОШИБКА! Не указана база данных!');
        }

        
$tables = array();
        
$result mysql_query("SHOW TABLES");
        
$all    0;

        while(
$row mysql_fetch_array($result)) {

            
$status 0;

            if (!empty(
$tbls)) {

                foreach(
$tbls as $table) {

                    
$exclude preg_match("/^^/"$table) ? true false;

                    if (!
$exclude) {

                        if (
preg_match("/^{$table}$/i"$row[0])) { $status 1; }
                        
$all 1;
                    }

                    if (
$exclude && preg_match("/{$table}$/i"$row[0])) { $status = -1; }
                }

            }
            else 
$status 1;

            if (
$status >= $all) { $tables[] = $row[0]; }
        }

        
// Определение размеров таблиц
        
$tabs        count($tables);
        
$result      mysql_query("SHOW TABLE STATUS");
        
$tabinfo     = array();
        
$tab_charset = array();
        
$tab_type    = array();
        
$tabinfo[0]  = 0;
        
$info        '';

        while(
$item mysql_fetch_assoc($result)) {

            if (
in_array($item['Name'], $tables)) {

                
$item['Rows'] = empty($item['Rows']) ? $item['Rows'];
                
$tabinfo[0] += $item['Rows'];
                
$tabinfo[$item['Name']] = $item['Rows'];
                
$this->size += $item['Data_length'];
                
$tabsize[$item['Name']] = round(LIMIT 1048576 / ($item['Avg_row_length'] + 1));
                if (
$item['Rows']) $info .= "|" $item['Rows'];

                if (!empty(
$item['Collation']) && preg_match("/^([a-z0-9]+)_/i"$item['Collation'], $m)) {

                    
$tab_charset[$item['Name']] = $m[1];
                }

                
$tab_type[$item['Name']] = isset($item['Engine']) ? $item['Engine'] : $item['Type'];
            }
        }

        
$show 10 $tabinfo[0] / 50;
        
$info $tabinfo[0] . $info;
        
$nms = !empty($tbName) ? $tbName $db;
        
$name $nms '_' date('Y-m-d_H-i');
        
$fp $this->fn_open($name'w');

        
$this->fn_write($fp"#SKD101|{$db}|{$tabs}|" date("Y.m.d H:i:s") ."|{$info}nn");
        
$t 0;

        
$result mysql_query("SET SQL_QUOTE_SHOW_CREATE = 1");
        
// Кодировка соединения по умолчанию
        
if ($this->mysql_version 40101 && CHARSET != 'auto') {

            
mysql_query("SET NAMES '" CHARSET "'") or trigger_error ('Неудается изменить кодировку соединения.');

            
$last_charset CHARSET;

        }
        else 
$last_charset '';

        foreach(
$tables as $table) {

            
// Выставляем кодировку соединения соответствующую кодировке таблицы
            
if ($this->mysql_version 40101 && $tab_charset[$table] != $last_charset) {

                if (
CHARSET == 'auto') {

                    
mysql_query("SET NAMES '" $tab_charset[$table] . "'") or trigger_error ('Неудается изменить кодировку соединения.');

                    
$last_charset $tab_charset[$table];
                }
                else
                {
                    die(
'Кодировка соединения и таблицы не совпадает: Таблица `'$table .'` -> ' $tab_charset[$table] . ' (соединение '  CHARSET ')');
                }
            }

            
// Создание таблицы
            
$result mysql_query("SHOW CREATE TABLE `{$table}`");
            
$tab mysql_fetch_array($result);
            
$tab preg_replace('/(default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP|DEFAULT CHARSET=w+|COLLATE=w+|character set w+|collate w+)/i''/*!40101 \1 */'$tab);
            
$this->fn_write($fp"DROP TABLE IF EXISTS `{$table}`;n{$tab[1]};nn");

            
// Проверяем нужно ли дампить данные
            
if (in_array($tab_type[$table], $this->only_create)) { continue; }

            
// Опредеделяем типы столбцов
            
$NumericColumn = array();
            
$result mysql_query("SHOW COLUMNS FROM `{$table}`");
            
$field 0;
            while(
$col mysql_fetch_row($result)) {

                
$NumericColumn[$field++] = preg_match("/^(w*int|year)/"$col[1]) ? 0;
            }
            
$fields $field;
            
$from 0;
            
$limit $tabsize[$table];
            
$limit2 round($limit 3);

            if (
$tabinfo[$table] > 0) {

                if (
$tabinfo[$table] > $limit2) {
                    
//echo tpl_s(0, $t / $tabinfo[0]);
                
}

                
$i 0;
                
$this->fn_write($fp"INSERT INTO `{$table}` VALUES");

                while((
$result mysql_query("SELECT * FROM `{$table}` LIMIT {$from}{$limit}")) && ($total mysql_num_rows($result))) {

                    while(
$row mysql_fetch_row($result)) {

                        
$i++; $t++;

                        for(
$k 0$k $fields$k++) {

                             if (
$NumericColumn[$k]) {

                                 
$row[$k] = isset($row[$k]) ? $row[$k] : "NULL";
                             }
                             else
                             {
                                 
$row[$k] = isset($row[$k]) ? "'" mysql_escape_string($row[$k]) . "'" "NULL";
                             }
                        }

                        
$this->fn_write($fp, ($i == "" ",") . "n(" implode(", "$row) . ")");

                    }

                    @
mysql_free_result($result);

                    if (
$total $limit) { break; }

                    
$from += $limit;
                }

                
$this->fn_write($fp";nn");

            }
        }
        
$this->tabs $tabs;
        
$this->records $tabinfo[0];
        
$this->comp $this->SET['comp_method'] * 10 $this->SET['comp_level'];

        
$this->fn_close($fp);

        if (
$this->SET['show_stat']) {

            
$alllines fn_int($tabinfo[0]);
            
$basesize round($this->size 10485762);
            
$filesize round(filesize($this->rootpath $this->filename) / 10485762);

            return <<<HTML
              - Резервная копия БД `{$db}` создана.<br />
              - Размер БД: 
{$basesize} МБ<br />
              - Размер файла: 
{$filesize} МБ<br />
              - Таблиц обработано: 
{$tabs}<br />
              - Строк обработано: 
{$alllines}<br />
HTML;
        }
    }

    function 
restore($flName ''$dbName '') { // Восстановление БД из резервной копии

        
global $config;

        
$this->SET['last_action']     = 1;
        
$this->SET['last_db_restore'] = !empty($dbName) ? $dbName $config['db_name'];
        
$file                         = !empty($flName) ? $flName '';
        
$this->fn_save();
        
$db $this->SET['last_db_restore'];

        if (!
$db) {

            die(
'ОШИБКА! Не указана база данных!');
        }

        
//Подключение к БД
        
mysql_select_db($db) or trigger_error('Не удается выбрать базу данных.<br />' mysql_error(), E_USER_ERROR);

        
// Определение формата файла
        
if(preg_match("/^(.+?).sql(.(bz2|gz))?$/"$file$matches)) {

            if (isset(
$matches[3]) && $matches[3] == 'bz2') {

                
$this->SET['comp_method'] = 2;
            }
            elseif (isset(
$matches[2]) &&$matches[3] == 'gz'){

                
$this->SET['comp_method'] = 1;
            }
            else {

                
$this->SET['comp_method'] = 0;
            }

            
$this->SET['comp_level'] = '';

            if (!
file_exists($this->rootpath$file)) {

                die(
'ОШИБКА! Файл не найден!');
            }

            
$file $matches[1];
        }
        else {

            die(
'ОШИБКА! Не выбран файл!');
        }

        
//echo tpl_l(str_repeat("-", 60));
        
$fp $this->fn_open($file'r'); // Чтение файла
        
$this->file_cache $sql $table $insert '';
        
$is_skd $query_len $execute $q =$t $i $aff_rows 0;
        
$limit  300;
        
$index  4;
        
$tabs   0;
        
$cache  '';
        
$info   = array();

        
// Установка кодировки соединения
        
if ($this->mysql_version 40101 && (CHARSET != 'auto' || $this->forced_charset)) { // Кодировка по умолчанию, если в дампе не указана кодировка

            
mysql_query("SET NAMES '" $this->restore_charset "'") or trigger_error('Неудается изменить кодировку соединения.<br />' mysql_error(), E_USER_ERROR);

            
$cache .= '- Установлена кодировка соединения `' $this->restore_charset '`.';
            
$last_charset $this->restore_charset;
        }
        else 
$last_charset '';

        
$last_showed '';

        while((
$str $this->fn_read_str($fp)) !== false) {

            if (empty(
$str) || preg_match("/^(#|--)/"$str)) {

                if (!
$is_skd && preg_match("/^#SKD101|/"$str)) {

                    
$info explode('|'$str);

                    
//echo tpl_s(0, $t / $info[4]);
                    
$is_skd 1;
                }
                continue;
            }

            
$query_len += strlen($str);

            if (!
$insert && preg_match("/^(INSERT INTO `?([^` ]+)`? .*?VALUES)(.*)$/i"$str$m)) {

                if (
$table != $m[2]) {

                    
$table $m[2];
                    
$tabs++;
                    
$cache .= "<br />- Таблица `{$table}`.";
                    
$last_showed $table;
                    
$i 0;

                    
//if ($is_skd)
                    //echo tpl_s(100 , $t / $info[4]);
                
}
                
$insert $m[1] . ' ';
                
$sql .= $m[3];
                
$index++;
                
$info[$index] = isset($info[$index]) ? $info[$index] : 0;
                
$limit round($info[$index] / 20);
                
$limit $limit 300 300 $limit;

                if (
$info[$index] > $limit){

                    
//echo $cache;
                    //$cache = '';
                    //echo tpl_s(0 / $info[$index], $t / $info[4]);
                
}
            }
            else {

                
$sql .= $str;

                if (
$insert) {

                    
$i++;
                    
$t++;

                    if (
$is_skd && $info[$index] > $limit && $t $limit == 0) {

                        
//echo tpl_s($i / $info[$index], $t / $info[4]);
                    
}
                }
            }

            if (!
$insert && preg_match("/^CREATE TABLE (IF NOT EXISTS )?`?([^` ]+)`?/i"$str$m) && $table != $m[2]) {

                
$table $m[2];
                
$insert '';
                
$tabs++;
                
$is_create true;
                
$i 0;
            }

            if (
$sql) {

                if (
preg_match("/;$/"$str)) {

                    
$sql rtrim($insert $sql";");

                    if (empty(
$insert)) {

                        if (
$this->mysql_version 40101) {

                            
$sql preg_replace("/ENGINEs?=/""TYPE="$sql);
                        }
                        elseif (
preg_match("/CREATE TABLE/i"$sql)){

                            
// Выставляем кодировку соединения
                            
if (preg_match("/(CHARACTER SET|CHARSET)[=s]+(w+)/i"$sql$charset)) {

                                if (!
$this->forced_charset && $charset[2] != $last_charset) {

                                    if (
CHARSET == 'auto') {

                                        
mysql_query("SET NAMES '" $charset[2] . "'") or trigger_error('Неудается изменить кодировку соединения.<br />' $sql '<br />' mysql_error(), E_USER_ERROR);
                                        
$cache .= '- Установлена кодировка соединения `' $charset[2] . '`.';
                                        
$last_charset $charset[2];
                                    }
                                    else {

                                        
$cache .= '- Кодировка соединения и таблицы не совпадает:<br />';
                                        
$cache .= '- Таблица `'$table .'` -> ' $charset[2] . ' (соединение '  $this->restore_charset ')';
                                    }
                                }

                                
// Меняем кодировку если указано форсировать кодировку
                                
if ($this->forced_charset) {

                                    
$sql preg_replace("/(/*!d+s)?((COLLATE)[=s]+)w+(s+*/)?/i"''$sql);
                                    
$sql preg_replace("/((CHARACTER SET|CHARSET)[=s]+)w+/i""\1" $this->restore_charset $this->restore_collate$sql);
                                }
                            }
                            elseif(
CHARSET == 'auto') { // Вставляем кодировку для таблиц, если она не указана и установлена auto кодировка

                                
$sql .= ' DEFAULT CHARSET=' $this->restore_charset $this->restore_collate;

                                if (
$this->restore_charset != $last_charset) {

                                    
mysql_query("SET NAMES '" $this->restore_charset "'") or trigger_error('Неудается изменить кодировку соединения.<br />' $sql '<br />' mysql_error(), E_USER_ERROR);
                                    
$cache .= '- Установлена кодировка соединения `' $this->restore_charset '`.';
                                    
$last_charset $this->restore_charset;
                                }
                            }
                        }

                        if (
$last_showed != $table) {

                            
$cache .= "<br />- Таблица `{$table}`.";
                            
$last_showed $table;
                        }
                    }
                    elseif(
$this->mysql_version 40101 && empty($last_charset)) { // Устанавливаем кодировку на случай если отсутствует CREATE TABLE

                        
mysql_query("SET $this->restore_charset '" $this->restore_charset "'") or trigger_error('Неудается изменить кодировку соединения.<br />' $sql '<br />' mysql_error(), E_USER_ERROR);
                        
$cache .= '- Установлена кодировка соединения `' $this->restore_charset '`.';
                        
$last_charset $this->restore_charset;
                    }
                    
$insert '';
                    
$execute 1;
                }

                if (
$query_len >= 65536 && preg_match("/,$/"$str)) {

                    
$sql rtrim($insert $sql",");
                    
$execute 1;
                }
  
                if (
$execute) {
          
                    
$q++;
                    
mysql_query($sql) or trigger_error('Неправильный запрос.<br />' mysql_error(), E_USER_ERROR);

                    if (
preg_match("/^insert/i"$sql)) {

                        
$aff_rows += mysql_affected_rows();
                    }
                    
$sql '';
                    
$query_len 0;
                    
$execute 0;
                }
            }
        }

        if (
$this->SET['show_stat']) {

            return <<<HTML
                - БД восстановлена из резервной копии.<br />
                
{$cache}<br />
                - Дата создания копии: 
{$info[3]}<br />
                - Запросов к БД: 
{$q}<br />
                - Таблиц создано: 
{$tabs}<br />
                - Строк добавлено: 
{$aff_rows}<br />
HTML;
        }

        
$this->fn_close($fp);
    }

    function 
db_select() {

        if (
DBNAMES != '') {

            
$items explode(','trim(DBNAMES));

            foreach(
$items as $item) {

                if (
mysql_select_db($item)) {

                    
$tables mysql_query("SHOW TABLES");

                    if (
$tables) {

                        
$tabs mysql_num_rows($tables);
                        
$dbs[$item] = "{$item} ({$tabs})";
                    }
                }
            }
        }
        else
        {
            
$result mysql_query("SHOW DATABASES");
            
$dbs = array();
            while(
$item mysql_fetch_array($result)) {

                if (
mysql_select_db($item[0])) {

                    
$tables mysql_query("SHOW TABLES");

                     if (
$tables) {

                         
$tabs mysql_num_rows($tables);
                         
$dbs[$item[0]] = "{$item[0]} ({$tabs})";
                     }
                }
            }
        }

        return 
$dbs;
    }

    function 
file_select() {

        
$files = array('' => ' ');

        if (
is_dir($this->rootpath) && $handle opendir($this->rootpath)) {

            while (
false !== ($file readdir($handle))) {

                if (
preg_match("/^.+?.sql(.(gz|bz2))?$/"$file)) {

                    
$files[$file] = $file;
                }
            }

            
closedir($handle);
        }

        
ksort($files);
        return 
$files;
    }

    function 
fn_open($name$mode) {

        if (
$this->SET['comp_method'] == 2) {

            
$this->filename "{$name}.sql.bz2";
            return 
bzopen($this->rootpath $this->filename"{$mode}b{$this->SET['comp_level']}");
        }
        elseif (
$this->SET['comp_method'] == 1) {

            
$this->filename "{$name}.sql.gz";
            return 
gzopen($this->rootpath $this->filename"{$mode}b{$this->SET['comp_level']}");
        }
        else
        {
            
$this->filename "{$name}.sql";
            return 
fopen($this->rootpath $this->filename"{$mode}b");
        }
    }

    function 
fn_write($fp$str) {

        if (
$this->SET['comp_method'] == 2) {

            
bzwrite($fp$str);
        }
        elseif (
$this->SET['comp_method'] == 1) {

            
gzwrite($fp$str);
        }
        else
        {
            
fwrite($fp$str);
        }
    }

    function 
fn_read($fp) {

        if (
$this->SET['comp_method'] == 2) {

            return 
bzread($fp4096);
        }
        elseif (
$this->SET['comp_method'] == 1) {

            return 
gzread($fp4096);
        }
        else
        {
            return 
fread($fp4096);
        }
    }

    function 
fn_read_str($fp) {

        
$string '';
        
$this->file_cache ltrim($this->file_cache);
        
$pos strpos($this->file_cache"n"0);

        if (
$pos 1) {

            while (!
$string && ($str $this->fn_read($fp))) {

                
$pos strpos($str"n"0);

                if (
$pos === false) {

                    
$this->file_cache .= $str;
                }
                else
                {
                    
$string $this->file_cache substr($str0$pos);
                    
$this->file_cache substr($str$pos 1);
                }
            }

            if (!
$str) {

                if (
$this->file_cache) {

                    
$string $this->file_cache;
                    
$this->file_cache '';
                    return 
trim($string);
                }

                return 
false;
            }
        }
        else
        {
            
$string substr($this->file_cache0$pos);
            
$this->file_cache substr($this->file_cache$pos 1);
        }

        return 
trim($string);
    }

    function 
fn_close($fp) {

        if (
$this->SET['comp_method'] == 2) {

            
bzclose($fp);
        }
        elseif (
$this->SET['comp_method'] == 1) {

            
gzclose($fp);
        }
        else
        {
            
fclose($fp);
        }

        @
chmod($this->rootpath $this->filename0644);
        
$this->fn_index();
    }

    function 
fn_select($items$selected) {

        
$select '';
        foreach(
$items as $key => $value) {

            
$select .= $key == $selected "<option value='{$key}' selected='selected'>{$value}"<option value='{$key}'>{$value}";
        }

        return 
$select;
    }

    function 
fn_save() {
/*
        if (SC) {
            $ne = !file_exists($this->rootpath . "dumper.cfg.php");
            $fp = fopen($this->rootpath . "dumper.cfg.php", "wb");
            fwrite($fp, "<?phpn$this->SET = " . fn_arr2str($this->SET) . "n?>");
            fclose($fp);
            if ($ne) @chmod($this->rootpath . "dumper.cfg.php", 0644);
            $this->fn_index();
        }
*/
    
}

    function 
fn_index() {
/*
        if (!file_exists($this->rootpath . 'index.html')) {
            $fh = fopen($this->rootpath . 'index.html', 'wb');
            fwrite($fh, tpl_backup_index());
            fclose($fh);
            @chmod($this->rootpath . 'index.html', 0644);
        }
*/
    
}
}

function 
fn_int($num) {

    return 
number_format($num0','' ');
}

function 
fn_arr2str($array) {

    
$str "array(n";

    foreach (
$array as $key => $value) {

        if (
is_array($value)) {

            
$str .= "'$key' => " fn_arr2str($value) . ",nn";
        }
        else
        {
            
$str .= "'$key' => '" str_replace("'""'"$value) . "',n";
        }
    }

    return 
$str ")";
}
?>
Онлайн: 1
Реклама