9if (ini_get(
'short_open_tag') == 0 && strtoupper(ini_get(
'short_open_tag')) !=
'ON')
11 die(
"Error: short_open_tag parameter must be turned on in php.ini\n");
14error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_WARNING);
15define(
'START_TIME', microtime(1));
16define(
'BX_FORCE_DISABLE_SEPARATED_SESSION_MODE',
true);
19if (!defined(
'NOT_CHECK_PERMISSIONS'))
21 define(
'NOT_CHECK_PERMISSIONS',
true);
26if (
CLI && defined(
'BX_CRONTAB'))
35 $l = COption::GetOptionInt(
'main',
'last_backup_start_time', 0);
36 if (time() -
$l <
IntOption(
'dump_auto_interval') * 86400)
41 $min_left =
IntOption(
'dump_auto_time') - date(
'H') * 60 - date(
"i");
42 if ($min_left > 0 || $min_left < -60)
47 define(
'LOCK_FILE',
$_SERVER[
'DOCUMENT_ROOT'] .
'/bitrix/backup/auto_lock');
49 if (!file_exists(
$_SERVER[
'DOCUMENT_ROOT'] .
'/bitrix/backup'))
51 mkdir(
$_SERVER[
'DOCUMENT_ROOT'] .
'/bitrix/backup');
54 if (file_exists(LOCK_FILE))
56 if (!(
$time = file_get_contents(LOCK_FILE)))
61 if (
$time + 86400 > time())
69 "SEVERITY" =>
"WARNING",
70 "AUDIT_TYPE_ID" =>
"BACKUP_ERROR",
71 "MODULE_ID" =>
"main",
72 "ITEM_ID" => LOCK_FILE,
73 "DESCRIPTION" =>
GetMessage(
'AUTO_LOCK_EXISTS_ERR', [
'#DATETIME#' => ConvertTimeStamp(
$time)]),
76 foreach (
GetModuleEvents(
"main",
"OnAutoBackupUnknownError",
true) as $arEvent)
81 unlink(LOCK_FILE) ||
RaiseErrorAndDie(
'Can\'t delete file: ' . LOCK_FILE, 2);
85 if (!file_put_contents(LOCK_FILE, time()))
90 COption::SetOptionInt(
'main',
'last_backup_start_time', time());
94 define(
'NO_AGENT_CHECK',
true);
95 define(
"STATISTIC_SKIP_ACTIVITY_CHECK",
true);
100 require(
$_SERVER[
'DOCUMENT_ROOT'] .
'/bitrix/modules/main/include/prolog_before.php');
103if (!defined(
'DOCUMENT_ROOT'))
105 define(
'DOCUMENT_ROOT', rtrim(str_replace(
'\\',
'/',
$_SERVER[
'DOCUMENT_ROOT']),
'/'));
107require_once(
$_SERVER[
"DOCUMENT_ROOT"] .
"/bitrix/modules/main/classes/general/backup.php");
112 $NS =& $_SESSION[
'BX_DUMP_STATE'];
134 session_write_close();
135 ini_set(
"session.use_strict_mode",
"0");
136 session_id(md5($backup_secret_key));
138 $NS =& $_SESSION[
'BX_DUMP_STATE'];
140 if (
$NS[
'TIMESTAMP'] && (
$i =
IntOption(
'dump_max_exec_time_sleep')) > 0)
142 if (time() -
$NS[
'TIMESTAMP'] <
$i)
151if (!file_exists(DOCUMENT_ROOT .
'/bitrix/backup'))
153 mkdir(DOCUMENT_ROOT .
'/bitrix/backup');
156if (!file_exists(DOCUMENT_ROOT .
"/bitrix/backup/index.php"))
158 $f = fopen(DOCUMENT_ROOT .
"/bitrix/backup/index.php",
"w");
159 fwrite(
$f,
"<head><meta http-equiv=\"REFRESH\" content=\"0;URL=/bitrix/admin/index.php\"></head>");
163while (ob_end_flush())
171$bBitrixCloud = function_exists(
'openssl_encrypt') && CModule::IncludeModule(
'bitrixcloud') && CModule::IncludeModule(
'clouds');
176 'dump_archive_size_limit' => 100 * 1024 * 1024,
177 'dump_use_compression' =>
$bGzip,
178 'dump_integrity_check' => 1,
179 'dump_delete_old' => 0,
180 'dump_site_id' => [],
183 'dump_base_skip_stat' => 0,
184 'dump_base_skip_search' => 0,
185 'dump_base_skip_log' => 0,
187 'dump_file_public' => 1,
188 'dump_file_kernel' => 1,
189 'dump_do_clouds' => 0,
191 'skip_mask_array' => [],
192 'dump_max_file_size' => 0,
198 'dump_archive_size_limit' =>
IntOption(
'dump_archive_size_limit'),
200 'dump_integrity_check' =>
IntOption(
'dump_integrity_check'),
202 'dump_delete_old' =>
IntOption(
'dump_delete_old'),
203 'dump_old_time' =>
IntOption(
'dump_old_time'),
204 'dump_old_cnt' =>
IntOption(
'dump_old_cnt'),
205 'dump_old_size' =>
IntOption(
'dump_old_size'),
207 'dump_site_id' => is_array(
$ar = unserialize(COption::GetOptionString(
"main",
"dump_site_id" .
"_auto"), [
'allowed_classes' =>
false])) ?
$ar : [],
211 'dump_base' =>
IntOption(
'dump_base', 1),
212 'dump_base_skip_stat' =>
IntOption(
'dump_base_skip_stat'),
213 'dump_base_skip_search' =>
IntOption(
'dump_base_skip_search'),
214 'dump_base_skip_log' =>
IntOption(
'dump_base_skip_log'),
216 'dump_file_public' =>
IntOption(
'dump_file_public', 1),
217 'dump_file_kernel' =>
IntOption(
'dump_file_kernel', 1),
218 'dump_do_clouds' =>
IntOption(
'dump_do_clouds', 1),
220 'skip_mask_array' => is_array(
$ar = unserialize(COption::GetOptionString(
"main",
"skip_mask_array_auto"), [
'allowed_classes' =>
false])) ?
$ar : [],
221 'dump_max_file_size' =>
IntOption(
'dump_max_file_size'),
229if (
$DB->type !=
'MYSQL')
236 $NS = [
'step' => 1,
'step_cnt' => 0];
245 $dump_bucket_id =
IntOption(
'dump_bucket_id');
248 if ($dump_bucket_id == -1)
256 $NS[
'BUCKET_ID'] = $dump_bucket_id;
258 if ($dump_bucket_id == -1)
260 $arc_name = DOCUMENT_ROOT .
BX_ROOT .
"/backup/" . date(
'Ymd_His_') . rand(11111111, 99999999);
262 elseif (($arc_name = $argv[1]) && !is_dir($arc_name))
264 $arc_name = str_replace([
'.tar',
'.gz',
'.enc'],
'', $arc_name);
268 $prefix = str_replace(
'/',
'', COption::GetOptionString(
"main",
"server_name",
""));
269 $arc_name =
CBackup::GetArcName(preg_match(
'#^[a-z0-9.\-]+$#i', $prefix) ? substr($prefix, 0, 20) .
'_' :
'');
272 $NS[
'arc_name'] = $arc_name . (
$NS[
'dump_encrypt_key'] ?
".enc" :
".tar") . (
$arParams[
'dump_use_compression'] ?
".gz" :
'');
273 $NS[
'dump_name'] = $arc_name .
'.sql';
277 $NS[
'site_path_list'] = [];
279 while (
$f =
$res->Fetch())
281 $root = rtrim(str_replace(
'\\',
'/',
$f[
'ABS_DOC_ROOT']),
'/');
282 if (is_dir($root) && in_array(
$f[
'ID'],
$arParams[
'dump_site_id']))
284 $NS[
'site_path_list'][
$f[
'ID']] = $root;
290 $NS[
'site_path_list'] = [
's1' => DOCUMENT_ROOT];
295 foreach (
GetModuleEvents(
"main",
"OnAutoBackupStart",
true) as $arEvent)
318 if (
$NS[
'BUCKET_ID'])
326 $NS[
'step_finished'] = 0;
330$after_file = str_replace(
'.sql',
'_after_connect.sql', preg_replace(
'#\.[0-9]+$#',
'',
$NS[
'dump_name']));
337 if (
$NS[
'step'] == 1)
345 $TotalTables =
$NS[
'dump_state'][
'TableCount'];
346 $FinishedTables = $TotalTables -
count(
$NS[
'dump_state'][
'TABLES']);
347 $NS[
'step_done'] = $FinishedTables / $TotalTables;
349 if (!
$NS[
'dump_state'][
'end'])
354 $rs =
$DB->Query(
'SHOW VARIABLES LIKE "character_set_results"');
355 if ((
$f =
$rs->Fetch()) && array_key_exists(
'Value',
$f))
357 file_put_contents(
$after_file,
"SET NAMES '" .
$f[
'Value'] .
"';\n");
360 $rs =
$DB->Query(
'SHOW VARIABLES LIKE "collation_database"');
361 if ((
$f =
$rs->Fetch()) && array_key_exists(
'Value',
$f))
363 file_put_contents(
$after_file,
"ALTER DATABASE `<DATABASE>` COLLATE " .
$f[
'Value'] .
";\n", 8);
367 $NS[
'step_finished']++;
370 $next_part =
$NS[
'dump_name'];
371 $NS[
'dump_size'] = filesize($next_part);
374 $NS[
'dump_size'] += filesize($next_part);
380 $tar->EncryptKey =
$NS[
'dump_encrypt_key'];
381 $tar->ArchiveSizeLimit =
$arParams[
'dump_archive_size_limit'];
382 $tar->gzip =
$arParams[
'dump_use_compression'];
383 $tar->path = DOCUMENT_ROOT;
384 $tar->ReadBlockCurrent = intval(
$NS[
'ReadBlockCurrent']);
385 $tar->ReadFileSize = intval(
$NS[
'ReadFileSize']);
387 if (!$tar->openWrite(
$NS[
"arc_name"]))
392 if (!$tar->ReadBlockCurrent)
394 if (file_exists(
$f = DOCUMENT_ROOT .
BX_ROOT .
'/.config.php'))
406 $Block = $tar->Block;
409 $r = $tar->addFile(
$NS[
'dump_name']);
414 if ($tar->ReadBlockCurrent == 0)
416 unlink(
$NS[
"dump_name"]);
419 $NS[
'dump_name'] = $next_part;
425 while (file_exists(
$name))
427 $size = filesize(
$name);
428 $NS[
'arc_size'] += $size;
431 $NS[
'step_finished']++;
439 $NS[
"data_size"] += 512 * ($tar->Block - $Block);
440 $NS[
"ReadBlockCurrent"] = $tar->ReadBlockCurrent;
441 $NS[
"ReadFileSize"] = $tar->ReadFileSize;
442 $NS[
'step_done'] =
$NS[
'data_size'] /
$NS[
'dump_size'];
451 $NS[
'step_done'] = 0;
456 foreach ($arDumpClouds as $arBucket)
458 $id = $arBucket[
'ID'];
459 if (
$NS[
'bucket_finished_' . $id])
465 $obCloud->last_bucket_path =
$NS[
'last_bucket_path'];
466 if (
$res = $obCloud->Scan(
''))
468 $NS[
'bucket_finished_' . $id] =
true;
472 $NS[
'last_bucket_path'] = $obCloud->path;
478 $NS[
'step_finished']++;
488 $NS[
'step_done'] = 0;
494 $DirScan->startPath =
$NS[
'startPath'];
497 $tar->EncryptKey =
$NS[
'dump_encrypt_key'];
498 $tar->ArchiveSizeLimit =
$arParams[
'dump_archive_size_limit'];
499 $tar->gzip =
$arParams[
'dump_use_compression'];
500 $tar->ReadBlockCurrent = intval(
$NS[
'ReadBlockCurrent']);
501 $tar->ReadFileSize = intval(
$NS[
'ReadFileSize']);
503 foreach (
$NS[
'site_path_list'] as
$SITE_ID => $DOCUMENT_ROOT_SITE)
505 $DOCUMENT_ROOT_SITE = rtrim($DOCUMENT_ROOT_SITE,
'/');
507 $tar->path = $DOCUMENT_ROOT_SITE;
509 if (!$tar->openWrite(
$NS[
"arc_name"]))
517 if (
$NS[
'multisite'])
519 $tar->prefix =
'bitrix/backup/sites/' .
$SITE_ID .
'/';
520 $DirScan->arSkip[$DOCUMENT_ROOT_SITE .
'/bitrix'] =
true;
521 $DirScan->arSkip[$DOCUMENT_ROOT_SITE .
'/upload'] =
true;
522 if (is_link($DOCUMENT_ROOT_SITE .
'/local'))
525 $DirScan->arSkip[$DOCUMENT_ROOT_SITE .
'/local'] =
true;
529 $Block = $tar->Block;
531 $r = $DirScan->Scan($DOCUMENT_ROOT_SITE);
534 if (!isset(
$NS[
"data_size"]))
536 $NS[
"data_size"] = 0;
538 $NS[
"data_size"] += 512 * ($tar->Block - $Block);
542 RaiseErrorAndDie(implode(
'<br>', array_merge($tar->err, $DirScan->err)), 410, $tar->file,
true);
545 $NS[
"ReadBlockCurrent"] = $tar->ReadBlockCurrent;
546 $NS[
"ReadFileSize"] = $tar->ReadFileSize;
547 $NS[
"startPath"] = $DirScan->nextPath;
549 if (!isset(
$NS[
"cnt"]))
553 $NS[
"cnt"] += $DirScan->FileCount;
555 $last_files_count =
IntOption(
'last_files_count');
556 if (!$last_files_count)
558 $last_files_count = 200000;
560 $NS[
'step_done'] =
$NS[
'cnt'] / $last_files_count;
561 if (
$NS[
'step_done'] > 1)
563 $NS[
'step_done'] = 1;
568 array_shift(
$NS[
'site_path_list']);
569 $NS[
'multisite'] =
true;
570 unset(
$NS[
'startPath']);
579 while (file_exists(
$name))
581 $size = filesize(
$name);
582 $NS[
'arc_size'] += $size;
590 $NS[
'step_finished']++;
598 $NS[
'step_done'] = 0;
603 $tar->EncryptKey =
$NS[
'dump_encrypt_key'];
605 if (!$tar->openRead(
$NS[
"arc_name"]))
611 if (($Block = intval(
$NS[
'Block'] ?? 0)) && !$tar->SkipTo($Block))
615 while (($r = $tar->extractFile()) &&
haveTime())
619 $NS[
"Block"] = $tar->Block;
620 $NS[
'step_done'] =
$NS[
'Block'] * 512 /
$NS[
'data_size'];
629 $NS[
'step_finished']++;
639 $NS[
'step_done'] = 0;
640 if (
$NS[
'BUCKET_ID'])
643 if (!CModule::IncludeModule(
'clouds'))
651 $file_size = filesize(
$NS[
"arc_name"]);
652 $file_name =
$NS[
'BUCKET_ID'] == -1 ? basename(
$NS[
'arc_name']) : substr(
$NS[
'arc_name'], strlen(DOCUMENT_ROOT));
655 if (
$NS[
'BUCKET_ID'] == -1)
663 if (!
$NS[
'obBucket'])
668 $q = $backup->getQuota();
669 if ($q &&
$NS[
'arc_size'] > $q)
675 $NS[
'obBucket'] = serialize($obBucket);
679 unset(
$NS[
'obBucket']);
685 $obBucket = unserialize(
687 [
'allowed_classes' => [
'CBitrixCloudBackupBucket']]
692 $obBucket->GetService()->setPublic(
false);
694 $bucket_id = $obBucket;
699 $bucket_id =
$NS[
'BUCKET_ID'];
702 if (!$obUpload->isStarted())
704 if (is_object($obBucket))
706 $obBucket->setCheckWordHeader();
709 if (!$obUpload->Start($bucket_id, $file_size))
722 if (is_object($obBucket))
724 $obBucket->unsetCheckWordHeader();
728 if (!$fp = fopen(
$NS[
'arc_name'],
'rb'))
733 fseek($fp, $obUpload->getPos());
734 while ($obUpload->getPos() < $file_size &&
haveTime())
736 $part = fread($fp, $obUpload->getPartSize());
739 while ($obUpload->hasRetries())
741 if (
$res = $obUpload->Next($part, $obBucket))
748 $strError = $e ?
'. ' . $e->GetString() :
'';
752 $NS[
'step_done'] = $obUpload->getPos() /
$NS[
'arc_size'];
758 $strError = $e ?
'. ' . $e->GetString() :
'';
766 if ($obUpload->Finish($obBucket))
768 if (
$NS[
'BUCKET_ID'] != -1)
771 $oBucket->IncFileCounter($file_size);
774 if (file_exists($arc_name = $tar->getNextName(
$NS[
'arc_name'])))
776 unset(
$NS[
'obBucket']);
777 $NS[
'arc_name'] = $arc_name;
790 while (file_exists(
$name))
792 $size = filesize(
$name);
793 if (unlink(
$name) && COption::GetOptionInt(
'main',
'disk_space', 0) > 0)
795 CDiskQuota::updateDiskQuota(
"file", $size,
"del");
807 $strError = $e ?
'. ' . $e->GetString() :
'';
811 $NS[
'step_finished']++;
819 $NS[
'step_done'] = 0;
826 $TotalSize =
$NS[
'arc_size'];
828 if (is_dir(
$p = DOCUMENT_ROOT .
BX_ROOT .
'/backup'))
833 while (($item = readdir(
$dir)) !==
false)
835 $f =
$p .
'/' . $item;
841 if (!preg_match(
'#\.(sql|tar|gz|enc|[0-9]+)$#', $item))
847 if (
$name == $arc_name)
856 $arParts[
$name][] = $item;
870 if ($m >= time() - 86400 *
$arParams[
'dump_old_time'])
882 if ($TotalSize / 1024 / 1024 / 1024 <=
$arParams[
'dump_old_size'])
892 foreach ($arParts[
$name] as $item)
894 $f =
$p .
'/' . $item;
895 $size = filesize(
$f);
901 if (COption::GetOptionInt(
'main',
'disk_space', 0) > 0)
903 CDiskQuota::updateDiskQuota(
"file", $size,
"del");
907 $NS[
'step_finished']++;
912if (COption::GetOptionInt(
'main',
'disk_space', 0) > 0)
916 while (file_exists(
$name))
918 $size = filesize(
$name);
919 CDiskQuota::updateDiskQuota(
"file", $size,
"add");
924$info =
"Finished.\n\nData size: " . round(
$NS[
'data_size'] / 1024 / 1024, 2) .
" M\nArchive size: " . round(
$NS[
'arc_size'] / 1024 / 1024, 2) .
" M\nTime: " . round(time() -
$NS[
'START_TIME'], 2) .
" sec\n";
927 "SEVERITY" =>
"WARNING",
928 "AUDIT_TYPE_ID" =>
"BACKUP_SUCCESS",
929 "MODULE_ID" =>
"main",
930 "ITEM_ID" =>
$NS[
'arc_name'],
931 "DESCRIPTION" =>
$info,
934foreach (
GetModuleEvents(
"main",
"OnAutoBackupSuccess",
true) as $arEvent)
940if (defined(
'LOCK_FILE'))
942 unlink(LOCK_FILE) ||
RaiseErrorAndDie(
'Can\'t delete file: ' . LOCK_FILE, 1000);
961 if (!isset($CACHE[
$name]))
965 return $CACHE[
$name];
975 echo round(microtime(1) -
$NS[
'START_TIME'], 2) .
' sec ' .
$str .
"\n";
983 $timeout =
IntOption(
'dump_max_exec_time', 30);
1004 if (
$dir = opendir(
$path = DOCUMENT_ROOT .
'/bitrix/backup'))
1006 while ($item = readdir(
$dir))
1008 if (is_dir(
$path .
'/' . $item))
1014 $delete = unlink(
$path .
'/' . $item) && $delete;
1024 $strError .=
"\n" . ($delete ?
'The backup was incorrect and it was deleted' :
'The backup was incorrect but there was an error deleting it');
1029 session_write_close();
1033 echo
'Error [' . $errCode .
']: ' . str_replace(
'<br>',
"\n",
$strError) .
"\n";
1045 "SEVERITY" =>
"WARNING",
1046 "AUDIT_TYPE_ID" =>
"BACKUP_ERROR",
1047 "MODULE_ID" =>
"main",
1048 "ITEM_ID" => $ITEM_ID,
1049 "DESCRIPTION" =>
"[" . $errCode .
"] " .
$strError,
1052 foreach (
GetModuleEvents(
"main",
"OnAutoBackupError",
true) as $arEvent)
1057 $link =
'/bitrix/admin/event_log.php?set_filter=Y&find_type=audit_type_id&find_audit_type[]=BACKUP_ERROR';
1059 "MESSAGE" =>
'The last automatic backup has failed. Please check your <a href="' . $link .
'">system log<a>',
1061 "MODULE_ID" =>
"MAIN",
1063 'ENABLE_CLOSE' =>
'Y',
1065 foreach ([
'ru',
'ua',
'en',
'de'] as
$lang)
1084 $NS[
'TIMESTAMP'] = time();
1086 session_write_close();
1093 if (
$NS[
'step_done'] > 1)
1095 $NS[
'step_done'] = 1;
1097 $res = round(100 * (
$NS[
'step_finished'] +
$NS[
'step_done']) /
$NS[
'step_cnt']);
static loadLanguageFile($file, $language=null, $normalize=true)
static getMessage($code, $replace=null, $language=null)
static SetOptionInt($module_id, $name, $value="", $desc="", $site="")
static GetList($by="sort", $order="asc", $arFilter=[])
static $DOCUMENT_ROOT_SITE
static MakeDump($strDumpFile, &$arState)
static $REAL_DOCUMENT_ROOT_SITE
static GetArcName($prefix='')
static GetBucketList($arFilter=array())
static getNextName($file)
static getFirstName($file)
static getCheckword($key)
$_SERVER["DOCUMENT_ROOT"]
if(!defined('SITE_ID')) $lang
RaiseErrorAndDie($strError, $errCode=0, $ITEM_ID='', $delete=false)
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
$arExpertBackupDefaultParams
if(!defined('NOT_CHECK_PERMISSIONS')) $NS
ExecuteModuleEventEx($arEvent, $arParams=[])
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
DeleteDirFilesEx($path, $root=null)
GetMessage($name, $aReplace=null)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
foreach($arTemplatesList as $templ) if(mb_strpos($templ["NAME"] $def