5 private $arFileVersions =
null;
6 private $fileGenerateDate = 0;
8 private $serverUniqID =
"";
9 private $isProcessingMain =
false;
12 private $versionsFileName =
"";
15 private $versionsDatabaseFolder =
"";
17 private $updatersDir =
"";
21 $this->serverUniqID = self::GetServerUniqID();
22 $this->isProcessingMain = $isProcessingMain;
24 $this->versionsFileName =
$_SERVER[
"DOCUMENT_ROOT"].self::versionsFileNameConst;
25 $this->versionsDatabaseFolder =
$_SERVER[
"DOCUMENT_ROOT"].self::versionsDatabaseFolderConst;
26 $this->updatersDir =
$_SERVER[
"DOCUMENT_ROOT"].US_SAVE_UPDATERS_DIR.
"/";
29 private static function GetOption(
$name,
$def =
"")
34 if (isset($cacheFlags[
"config_options"]))
35 $cacheTtl = $cacheFlags[
"config_options"];
39 if ($cache->read($cacheTtl,
"b_option:main",
"b_option"))
41 $options = $cache->get(
"b_option:main");
45 $con = \Bitrix\Main\Application::getConnection();
46 $sqlHelper =
$con->getSqlHelper();
51 WHERE MODULE_ID = 'main'
52 AND NAME = '{$sqlHelper->forSql($name)}'
64 private static function SetOption(
$name, $value =
"")
66 $con = \Bitrix\Main\Application::getConnection();
67 $sqlHelper =
$con->getSqlHelper();
74 "MODULE_ID" =>
"main",
79 $keyFields = [
"MODULE_ID",
"NAME"];
81 $sql = $sqlHelper->prepareMerge(
"b_option", $keyFields, $insertFields, $updateFields);
83 $con->queryExecute(current($sql));
85 $cache = \Bitrix\Main\Application::getInstance()->getManagedCache();
86 $cache->clean(
"b_option:main",
"b_option");
93 private static function GetServerUniqID()
95 $uniq = self::GetOption(
"server_uniq_id",
"");
98 $uniq = md5(uniqid(rand(),
true));
99 self::SetOption(
"server_uniq_id", $uniq);
108 $uniq = $this->serverUniqID;
110 if (
$DB->type ==
"MYSQL")
112 $dbLock =
$DB->Query(
"SELECT GET_LOCK('".$uniq.
"_DBUpdater', 0) as L");
113 $arLock = $dbLock->Fetch();
114 if ($arLock[
"L"] ==
"1")
121 $dbLock =
$DB->Query(
"
125 lock_failed exception;
126 pragma exception_init(lock_failed, -54);
128 my_lock_id:=dbms_utility.get_hash_value(to_char('".$uniq.
"_DBUpdater'), 0, 1024);
129 my_result:=dbms_lock.request(my_lock_id, dbms_lock.x_mode, 0, true);
134 -- 3 - parameter error
135 -- 4 - already own lock specified by 'id' or 'lockhandle'
136 -- 5 - illegal lockhandle
137 if(my_result<>0 and my_result<>4)then
142 return ($dbLock !==
false);
147 $DB->Query(
"DELETE FROM b_option WHERE MODULE_ID = 'main' AND NAME = '".$uniq.
"_DBUpdater' AND SITE_ID IS NULL AND DATEDIFF(SECOND, CONVERT(DATETIME, DESCRIPTION), GETDATE()) > ".
$i);
148 $DB->Query(
"SET LOCK_TIMEOUT 1");
149 $dbLock =
$DB->Query(
"INSERT INTO b_option(MODULE_ID, NAME, SITE_ID, VALUE, DESCRIPTION) VALUES ('main', '".$uniq.
"_DBUpdater', NULL, NULL, CONVERT(VARCHAR(128), GETDATE()))",
true);
150 $DB->Query(
"SET LOCK_TIMEOUT -1");
151 return ($dbLock !==
false);
159 $uniq = $this->serverUniqID;
161 if (
$DB->type ==
"MYSQL")
163 $dbLock =
$DB->Query(
"SELECT RELEASE_LOCK('".$uniq.
"_DBUpdater') as L");
164 $arLock = $dbLock->Fetch();
165 if($arLock[
"L"] ==
"0")
176 $DB->Query(
"DELETE FROM b_option WHERE MODULE_ID = 'main' AND NAME = '".$uniq.
"_DBUpdater' AND SITE_ID IS NULL");
181 private static function GetDatabaseVersions()
185 $arDBVersions =
array();
187 $dbResult =
$DB->Query(
"SELECT VALUE FROM b_option WHERE MODULE_ID='main' AND NAME='BITRIX24_VERSIONS' AND SITE_ID IS NULL",
true);
193 $arDBVersions = unserialize(
$val, [
'allowed_classes' =>
false]);
194 if (!is_array($arDBVersions))
195 $arDBVersions =
array();
199 return $arDBVersions;
202 private static function SetDatabaseVersions($arDBVersions)
206 if(is_array($arDBVersions))
208 self::SetOption(
"BITRIX24_VERSIONS", serialize($arDBVersions));
209 $DB->Query(
"INSERT INTO b_sm_version_history(DATE_INSERT, VERSIONS) VALUES(NOW(), '".
$DB->ForSql(serialize($arDBVersions)).
"')",
true);
213 private function InitializeFileData()
216 $arVersions =
array();
218 if (file_exists($this->versionsFileName))
220 include($this->versionsFileName);
221 if (!is_array($arVersions))
222 $arVersions =
array();
225 if (empty($arVersions))
227 include_once(
$_SERVER[
"DOCUMENT_ROOT"].
"/bitrix/modules/main/classes/general/update_client.php");
230 $arVersions = CUpdateClient::GetCurrentModules(
$errorMessage,
false);
231 $generationDate = time();
234 $f = fopen($this->versionsFileName,
"w");
235 fwrite(
$f,
"<".
"?\n");
236 fwrite(
$f,
"\$generationDate = ".$generationDate.
";\n");
237 fwrite(
$f,
"\$arVersions = array(\n");
238 foreach ($arVersions as
$moduleId => $version)
239 fwrite(
$f,
"\t\"".htmlspecialchars(
$moduleId).
"\" => \"".htmlspecialchars($version).
"\",\n");
246 $this->fileGenerateDate = $generationDate;
247 $this->arFileVersions = $arVersions;
250 private function GetFileVersions()
252 if (is_null($this->arFileVersions))
253 $this->InitializeFileData();
255 return $this->arFileVersions;
258 private function GetFileGenerateDate()
260 if ($this->fileGenerateDate <= 0)
261 $this->InitializeFileData();
263 return $this->fileGenerateDate;
266 private function GetDatabaseGenerationDate()
268 return self::GetOption(
"BITRIX24_GENERATION_DATE_".($this->isProcessingMain ?
"M" :
"N"), 0);
273 $generationDate = $this->GetFileGenerateDate();
274 $dbGenerationDate = $this->GetDatabaseGenerationDate();
276 if ($dbGenerationDate >= $generationDate)
282 private function Collect4PreCheckUpdates($generationDate)
284 self::SetOption(
"BITRIX24_GENERATION_DATE_".($this->isProcessingMain ?
"M" :
"N"), $generationDate);
289 $arDBVersions = self::GetDatabaseVersions();
290 if (empty($arDBVersions))
293 $arDBVersions = self::GetDatabaseVersions();
296 $arFileVersions = $this->GetFileVersions();
299 foreach ($arFileVersions as
$moduleId => $version)
301 if (($this->isProcessingMain && (
$moduleId !==
"main"))
302 || (!$this->isProcessingMain && (
$moduleId ===
"main")))
305 if (CUpdateClient::CompareVersions($version, $arDBVersions[
$moduleId]) > 0)
312 if ($this->isProcessingMain && !empty(
$arResult))
314 if(!
$DB->TableExists(
"b_option_site"))
317 CREATE TABLE b_option_site
319 MODULE_ID VARCHAR(50) not null,
320 NAME VARCHAR(50) not null,
321 SITE_ID CHAR(2) not null,
323 PRIMARY KEY(MODULE_ID, NAME, SITE_ID),
324 INDEX ix_option_site_module_site(MODULE_ID, SITE_ID)
328 if(!
$DB->Query(
"SELECT UNIQUE_ID FROM b_module_to_module WHERE 1=0",
true))
330 $DB->Query(
"ALTER TABLE b_module_to_module ADD UNIQUE_ID VARCHAR(32) NOT NULL",
true);
347 if (file_exists($this->updatersDir.$moduleId) && is_dir($this->updatersDir.$moduleId))
349 $arUpdaters =
array();
351 if (
$handle = @opendir($this->updatersDir.$moduleId))
360 if (str_starts_with(
$dir,
"updater"))
362 if (is_file($this->updatersDir.$moduleId.
"/".
$dir))
364 $num = substr(
$dir, 7, strlen(
$dir) - 11);
365 if (substr(
$dir, strlen(
$dir) - 9) ==
"_post.php")
367 $num = substr(
$dir, 7, strlen(
$dir) - 16);
370 $arUpdaters[] =
array(
"/".
$dir, trim($num));
372 elseif (file_exists($this->updatersDir.$moduleId.
"/".
$dir.
"/index.php"))
374 $num = substr(
$dir, 7);
375 if (substr(
$dir, strlen(
$dir) - 5) ==
"_post")
377 $num = substr(
$dir, 7, strlen(
$dir) - 12);
380 $arUpdaters[] =
array(
"/".
$dir.
"/index.php", trim($num));
387 $ni1 =
count($arUpdaters);
388 for ($i1 = 0; $i1 < $ni1 - 1; $i1++)
390 for ($j1 = $i1 + 1; $j1 < $ni1; $j1++)
392 if (CUpdateClient::CompareVersions($arUpdaters[$i1][1], $arUpdaters[$j1][1]) > 0)
394 $tmp1 = $arUpdaters[$i1];
395 $arUpdaters[$i1] = $arUpdaters[$j1];
396 $arUpdaters[$j1] = $tmp1;
401 for ($i1 = 0; $i1 < $ni1; $i1++)
403 if (CUpdateClient::CompareVersions($arUpdaters[$i1][1], $dbVersion) <= 0)
408 $errorMessageTmp =
"";
410 syslog(LOG_INFO,
$_SERVER[
"HTTP_HOST"].
"\tstart\t".
$moduleId.$arUpdaters[$i1][0]);
412 CUpdateClient::RunUpdaterScript($this->updatersDir.$moduleId.$arUpdaters[$i1][0], $errorMessageTmp,
"",
$moduleId);
414 syslog(LOG_INFO,
$_SERVER[
"HTTP_HOST"].
"\tend\t".
$moduleId.$arUpdaters[$i1][0].
"\t".$errorMessageTmp);
416 if ($errorMessageTmp <>
'')
428 CUpdateClient::AddMessage2Log(
$message,
"DUE");
433 $message =
"Database updated successfully (".$moduleId.
"-".$dbVersion.
")";
434 CUpdateClient::AddMessage2Log(
$message,
"DUS");
441 $arDBVersions = self::GetDatabaseVersions();
442 $arFileVersions = $this->GetFileVersions();
450 self::SetDatabaseVersions($arDBVersions);
455 if ($this->isProcessingMain)
458 $arDBVersions[
"main"] = $arFileVersions[
"main"];
459 self::SetDatabaseVersions($arDBVersions);
464 $arFileVersions[
"main"] = $arDBVersions[
"main"];
465 self::SetDatabaseVersions($arFileVersions);
467 $this->Collect4PreCheckUpdates($this->GetFileGenerateDate());
472 self::SetDatabaseVersions($arFileVersions);
473 $this->Collect4PreCheckUpdates($this->GetFileGenerateDate());
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)