CanDoOperation('edit_php')) $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED")); if(!defined("START_EXEC_TIME")) define("START_EXEC_TIME", microtime(true)); IncludeModuleLangFile(__FILE__); require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/backup.php"); $strBXError = ''; $bGzip = function_exists('gzcompress'); $encrypt = function_exists('openssl_encrypt'); $bHash = function_exists('hash'); $bBitrixCloud = $encrypt && $bHash; if (!CModule::IncludeModule('bitrixcloud')) { $bBitrixCloud = false; $strBXError = GetMessage('ERR_NO_BX_CLOUD'); } elseif (!CModule::IncludeModule('clouds')) { $bBitrixCloud = false; $strBXError = GetMessage('ERR_NO_CLOUDS'); } if($bBitrixCloud) { $backup = CBitrixCloudBackup::getInstance(); $arFiles = $backup->listFiles(); $backup->saveToOptions(); } define('DOCUMENT_ROOT', rtrim(str_replace('\\','/',$_SERVER['DOCUMENT_ROOT']),'/')); // define('DUMP_DEBUG_MODE', true); // xdebug_start_trace(); $arAllBucket = CBackup::GetBucketList(); $status_title = ""; if (isset($_REQUEST['ajax_mode']) && $_REQUEST['ajax_mode'] == 'Y') { if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'get_table_size') { ?> die(); } } elseif(isset($_REQUEST['process']) && $_REQUEST['process'] == "Y") { if (!check_bitrix_sessid()) RaiseErrorAndDie(GetMessage("DUMP_MAIN_SESISON_ERROR")); require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_js.php"); $NS =& \Bitrix\Main\Application::getInstance()->getSession()['BX_DUMP_STATE']; if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'start') { define('NO_TIME', true); $bFull = isset($_REQUEST['dump_all']) && $_REQUEST['dump_all'] == 'Y'; if(!file_exists(DOCUMENT_ROOT.BX_ROOT."/backup")) mkdir(DOCUMENT_ROOT.BX_ROOT."/backup", BX_DIR_PERMISSIONS); if(!file_exists(DOCUMENT_ROOT.BX_ROOT."/backup/index.php")) { $f = fopen(DOCUMENT_ROOT.BX_ROOT."/backup/index.php","w"); fwrite($f,"
"); fclose($f); } if(!is_dir(DOCUMENT_ROOT.BX_ROOT."/backup") || !is_writable(DOCUMENT_ROOT.BX_ROOT."/backup")) RaiseErrorAndDie(GetMessage("MAIN_DUMP_FOLDER_ERR",array('#FOLDER#' => DOCUMENT_ROOT.BX_ROOT.'/backup'))); DeleteDirFilesEx(BX_ROOT.'/backup/clouds'); $NS = Array(); $NS['finished_steps'] = 0; $NS['dump_state'] = ''; $NS['BUCKET_ID'] = intval($_REQUEST['dump_bucket_id'] ?? 0); COption::SetOptionInt("main", "dump_bucket_id", $NS['BUCKET_ID']); if ($encrypt && !empty($_REQUEST['dump_encrypt_key'])) { $NS['dump_encrypt_key'] = $_REQUEST['dump_encrypt_key']; COption::SetOptionInt("main", "dump_encrypt", 1); } else COption::SetOptionInt("main", "dump_encrypt", 0); if ($NS['BUCKET_ID'] == -1 && !$NS['dump_encrypt_key']) RaiseErrorAndDie(GetMessage('MAIN_DUMP_BXCLOUD_ENC')); $bUseCompression = $bGzip && (!isset($_REQUEST['dump_disable_gzip']) || $_REQUEST['dump_disable_gzip'] != 'Y' || $bFull); COption::SetOptionInt("main", "dump_use_compression", $bUseCompression); if ($bFull) { $NS['total_steps'] = 4; // dump, tar dump, tar files, integrity COption::SetOptionInt("main", "dump_max_exec_time", 20); COption::SetOptionInt("main", "dump_max_exec_time_sleep", 1); COption::SetOptionInt("main", "dump_archive_size_limit", 100 * 1024 * 1024); COption::SetOptionInt("main", "dump_integrity_check", 1); COption::SetOptionInt("main", "dump_max_file_size", 0); COption::SetOptionInt("main", "dump_file_public", 1); COption::SetOptionInt("main", "dump_file_kernel", 1); COption::SetOptionInt("main", "dump_base", $DB->type == 'MYSQL' ? 1 : 0); COption::SetOptionInt("main", "dump_base_skip_stat", 0); COption::SetOptionInt("main", "dump_base_skip_search", 0); COption::SetOptionInt("main", "dump_base_skip_log", 0); if ($arAllBucket) { $bDumpCloud = 1; $NS['total_steps']++; COption::SetOptionInt("main", "dump_do_clouds", 1); foreach($arAllBucket as $arBucket) COption::SetOptionInt('main', 'dump_cloud_'.$arBucket['ID'], 1); } COption::SetOptionInt("main", "skip_mask", 0); } else { COption::SetOptionInt("main", "dump_max_exec_time", max(intval($_REQUEST['dump_max_exec_time'] ?? 0), 5)); COption::SetOptionInt("main", "dump_max_exec_time_sleep", $_REQUEST['dump_max_exec_time_sleep'] ?? 0); $dump_archive_size_limit = intval($_REQUEST['dump_archive_size_limit'] ?? 0); if ($dump_archive_size_limit > 2047 || $dump_archive_size_limit <= 10) $dump_archive_size_limit = 100; COption::SetOptionInt("main", "dump_archive_size_limit", $dump_archive_size_limit * 1024 * 1024); COption::SetOptionInt("main", "dump_max_file_size", $_REQUEST['max_file_size'] ?? 0); $NS['total_steps'] = 0; if ($r = (isset($_REQUEST['dump_file_public']) && $_REQUEST['dump_file_public'] == 'Y')) $NS['total_steps'] = 1; COption::SetOptionInt("main", "dump_file_public", $r); if ($r = (isset($_REQUEST['dump_file_kernel']) && $_REQUEST['dump_file_kernel'] == 'Y')) $NS['total_steps'] = 1; COption::SetOptionInt("main", "dump_file_kernel", $r); if ($r = $DB->type == 'MYSQL' ? (isset($_REQUEST['dump_base']) && $_REQUEST['dump_base'] == 'Y') : 0) $NS['total_steps'] += 2; COption::SetOptionInt("main", "dump_base", $r); COption::SetOptionInt("main", "dump_base_skip_stat", isset($_REQUEST['dump_base_skip_stat']) && $_REQUEST['dump_base_skip_stat'] == 'Y'); COption::SetOptionInt("main", "dump_base_skip_search", isset($_REQUEST['dump_base_skip_search']) && $_REQUEST['dump_base_skip_search'] == 'Y'); COption::SetOptionInt("main", "dump_base_skip_log", isset($_REQUEST['dump_base_skip_log']) && $_REQUEST['dump_base_skip_log'] == 'Y'); if ($r = (isset($_REQUEST['dump_integrity_check']) && $_REQUEST['dump_integrity_check'] == 'Y')) $NS['total_steps']++; COption::SetOptionInt("main", "dump_integrity_check", $r); $bDumpCloud = false; if ($arAllBucket) { foreach($arAllBucket as $arBucket) { if ($res = (isset($_REQUEST['dump_cloud'][$arBucket['ID']]) && $_REQUEST['dump_cloud'][$arBucket['ID']] == 'Y')) $bDumpCloud = true; COption::SetOptionInt('main', 'dump_cloud_'.$arBucket['ID'], $res); } if ($bDumpCloud) $NS['total_steps']++; } COption::SetOptionInt("main", "dump_do_clouds", $bDumpCloud); $skip_mask = isset($_REQUEST['skip_mask']) && $_REQUEST['skip_mask'] == 'Y'; COption::SetOptionInt("main", "skip_mask", $skip_mask); $skip_mask_array = array(); if ($skip_mask && isset($_REQUEST['arMask']) && is_array($_REQUEST['arMask'])) { $arMask = array_unique($_REQUEST['arMask']); foreach($arMask as $mask) if (trim($mask)) { $mask = rtrim(str_replace('\\','/',trim($mask)),'/'); $skip_mask_array[] = $mask; } COption::SetOptionString("main", "skip_mask_array", serialize($skip_mask_array)); } } $NS["step"] = 1; if ($NS['BUCKET_ID']) // send to the [bitrix]cloud $NS['total_steps']++; $NS['dump_site_id'] = $_REQUEST['dump_site_id'] ?? ''; if (!is_array($NS['dump_site_id'])) $NS['dump_site_id'] = array(); COption::SetOptionString("main", "dump_site_id", serialize($NS['dump_site_id'])); if ($NS['BUCKET_ID'] == -1) // Bitrixcloud { $name = DOCUMENT_ROOT . BX_ROOT . "/backup/" . date('Ymd_His_') . Random::getStringByAlphabet(16, Random::ALPHABET_NUM); $NS['arc_name'] = $name.'.enc'.($bUseCompression ? ".gz" : ''); $NS['dump_name'] = $name.'.sql'; } else { $prefix = ''; if (count($NS['dump_site_id']) == 1) { $rs = CSite::GetList('sort', 'asc', array('ID' => $NS['dump_site_id'][0], 'ACTIVE' => 'Y')); if ($f = $rs->Fetch()) $prefix = str_replace('/', '', $f['SERVER_NAME']); } else $prefix = str_replace('/', '', COption::GetOptionString("main", "server_name", "")); $arc_name = CBackup::GetArcName(preg_match('#^[a-z0-9.\-]+$#i', $prefix) ? substr($prefix, 0, 20).'_' : ''); $NS['dump_name'] = $arc_name.".sql"; $NS['arc_name'] = $arc_name.(!empty($NS['dump_encrypt_key']) ? ".enc" : ".tar").($bUseCompression ? ".gz" : ''); } } elseif(isset($_REQUEST['action']) && $_REQUEST['action'] == 'cloud_send') { define('NO_TIME', true); $NS = Array(); $NS['finished_steps'] = 0; $NS['total_steps'] = 1; $NS['cloud_send'] = 1; $NS['dump_encrypt_key'] = $_REQUEST['dump_encrypt_key'] ?? ''; $NS['arc_name'] = $name = DOCUMENT_ROOT.BX_ROOT.'/backup/'.str_replace(array('..','/','\\'),'',$_REQUEST['f_id'] ?? ''); $NS['arc_size'] = filesize($NS['arc_name']); $NS['BUCKET_ID'] = intval($_REQUEST['dump_bucket_id'] ?? 0); $tar = new CTar; while(file_exists($name = $tar->getNextName($name))) $NS['arc_size'] += filesize($name); $NS['step'] = 6; } elseif(isset($_REQUEST['action']) && $_REQUEST['action'] == 'check_archive') { define('NO_TIME', true); $NS = Array(); $NS['finished_steps'] = 0; $NS['total_steps'] = 1; $NS['arc_name'] = $name = DOCUMENT_ROOT.BX_ROOT.'/backup/'.str_replace(array('..','/','\\'),'',$_REQUEST['f_id'] ?? ''); $NS['step'] = 5; $NS['dump_encrypt_key'] = $_REQUEST['dump_encrypt_key'] ?? ''; $NS['check_archive'] = true; $tar = new CTar; $NS['data_size'] = $tar->getDataSize($name); } else { $ar = unserialize(COption::GetOptionString("main","skip_mask_array"), ['allowed_classes' => false]); $skip_mask_array = is_array($ar) ? $ar : array(); } $after_file = str_replace('.sql','_after_connect.sql',preg_replace('#\.[0-9]+$#', '', $NS['dump_name'])); $FinishedTables = 0; // Step 1: Dump if($NS["step"] == 1) { $step_done = 0; if (IntOption('dump_base')) { if (!CBackup::MakeDump($NS['dump_name'], $NS['dump_state'])) { RaiseErrorAndDie(GetMessage('DUMP_NO_PERMS')); } $TotalTables = $NS['dump_state']['TableCount']; $FinishedTables = $TotalTables - count($NS['dump_state']['TABLES']); $status_title = GetMessage('DUMP_DB_CREATE'); $status_details = GetMessage("MAIN_DUMP_TABLE_FINISH")." ".(intval($FinishedTables))." ".GetMessage('MAIN_DUMP_FROM').' '.$TotalTables.''; $step_done = $FinishedTables / $TotalTables; if (!empty($NS['dump_state']['end'])) { $rs = $DB->Query('SHOW VARIABLES LIKE "character_set_results"'); if (($f = $rs->Fetch()) && array_key_exists ('Value', $f)) file_put_contents($after_file, "SET NAMES '".$f['Value']."';\n"); $rs = $DB->Query('SHOW VARIABLES LIKE "collation_database"'); if (($f = $rs->Fetch()) && array_key_exists ('Value', $f)) file_put_contents($after_file, "ALTER DATABASE `