37 $this->_ID = intval(
$ID);
46 $this->enabledFailover =
false;
77 && $this->FAILOVER_ACTIVE ===
'Y'
78 && $this->FAILOVER_BUCKET_ID > 0
81 return $this->FAILOVER_BUCKET_ID;
94 if (!isset($this->arBucket))
97 $this->arBucket = self::$arBuckets[
$this->_ID];
100 && $this->arBucket[
'FAILOVER_ACTIVE'] ===
'Y'
101 && $this->arBucket[
'FAILOVER_BUCKET_ID'] > 0
105 if ($this->failoverBucket->Init())
107 $this->arBucket[
'SERVICE_ID'] = $this->failoverBucket->SERVICE_ID;
108 $this->arBucket[
'BUCKET'] = $this->failoverBucket->BUCKET;
109 $this->arBucket[
'LOCATION'] = $this->failoverBucket->LOCATION;
110 $this->arBucket[
'CNAME'] = $this->failoverBucket->CNAME;
111 $this->arBucket[
'PREFIX'] = $this->failoverBucket->PREFIX;
112 $this->arBucket[
'SETTINGS'] = $this->failoverBucket->SETTINGS;
116 $this->failoverBucket =
null;
136 private static function CompileModuleRule(
$str)
145 $res[$s] = preg_quote($s,
'/');
150 return '/^(' . implode(
'|',
$res) .
')$/';
162 private static function CompileExtentionRule(
$str)
171 $res[$s] = preg_quote(
'.' . $s,
'/');
176 return '/(' . implode(
'|',
$res) .
')$/i';
188 private static function ParseSize(
$str)
197 if (
$str !==
'' && preg_match(
'/([0-9.]+)(|K|M|G)$/',
$str, $match) > 0)
199 return doubleval($match[1]) * $scale[$match[2]];
211 private static function CompileSizeRule(
$str)
220 $arSize = explode(
'-', $s);
221 if (
count($arSize) == 1)
223 $res[] = [self::ParseSize($arSize[0]), self::ParseSize($arSize[0])];
227 $res[] = [self::ParseSize($arSize[0]), self::ParseSize($arSize[1])];
238 private static function CompileRules($arRules)
241 if (is_array($arRules))
243 foreach ($arRules as $rule)
248 'MODULE_MASK' => isset($rule[
'MODULE']) ? self::CompileModuleRule($rule[
'MODULE']) :
'',
249 'EXTENTION_MASK' => isset($rule[
'EXTENSION']) ? self::CompileExtentionRule($rule[
'EXTENSION']) :
'',
250 'SIZE_ARRAY' => isset($rule[
'SIZE']) ? self::CompileSizeRule($rule[
'SIZE']) :
'',
261 private static function _init()
265 if (isset(self::$arBuckets))
270 $cache_id =
'cloud_buckets_v2';
272 CACHED_b_clouds_file_bucket !==
false
273 &&
$CACHE_MANAGER->Read(CACHED_b_clouds_file_bucket, $cache_id,
'b_clouds_file_bucket')
280 self::$arBuckets = [];
284 FROM b_clouds_file_bucket
285 ORDER BY SORT DESC, ID ASC
287 while (is_array(
$ar =
$rs->Fetch()))
289 if (
$ar[
'FILE_RULES'] !=
'')
291 $arRules = unserialize(
$ar[
'FILE_RULES'], [
'allowed_classes' =>
false]);
298 $ar[
'FILE_RULES_COMPILED'] = self::CompileRules($arRules);
300 if (
$ar[
'SETTINGS'] !=
'')
302 $arSettings = unserialize(
$ar[
'SETTINGS'], [
'allowed_classes' =>
false]);
309 if (is_array($arSettings))
311 $ar[
'SETTINGS'] = $arSettings;
315 $ar[
'SETTINGS'] = [];
318 self::$arBuckets[intval(
$ar[
'ID'])] =
$ar;
321 if (CACHED_b_clouds_file_bucket !==
false)
350 if (is_object($this->service))
356 if ($this->SERVICE_ID)
360 return is_object($this->service);
369 if ($this->service->tokenHasExpired)
372 $newSettings =
false;
373 foreach (
GetModuleEvents(
'clouds',
'OnExpiredToken',
true) as $arEvent)
384 if ($this->failoverBucket)
386 $updateResult = $this->failoverBucket->Update([
'SETTINGS' => $newSettings]);
387 $this->arBucket =
null;
391 $updateResult = $this->
Update([
'SETTINGS' => $newSettings]);
396 $this->service->tokenHasExpired =
false;
411 return $this->service->CheckSettings($this->arBucket, $arSettings);
419 return $this->service->CreateBucket($this->arBucket);
429 if (is_array($arFile) && isset($arFile[
'URN']))
431 return $this->service->GetFileSRC($this->arBucket, $arFile[
'URN'], $encoded);
435 return preg_replace(
"'(?<!:)/+'s",
'/', $this->service->GetFileSRC($this->arBucket, $arFile, $encoded));
445 $result = $this->service->FileExists($this->arBucket, $filePath);
460 $result = $this->service->DownloadToFile($this->arBucket, $arFile, $filePath);
471 $result = $this->service->SaveFile($this->arBucket, $filePath, $arFile);
479 if ($this->queueFlag)
484 foreach (
GetModuleEvents(
'clouds',
'OnAfterSaveFile',
true) as $arEvent)
498 $result = $this->service->DeleteFile($this->arBucket, $filePath);
506 if ($this->queueFlag)
515 foreach (
GetModuleEvents(
'clouds',
'OnAfterDeleteFile',
true) as $arEvent)
530 $result = $this->service->FileCopy($this->arBucket, $arFile, $filePath);
538 if ($this->queueFlag)
543 foreach (
GetModuleEvents(
'clouds',
'OnAfterCopyFile',
true) as $arEvent)
557 public function FileRename($sourcePath, $targetPath, $overwrite =
true)
559 $result = $this->service->FileRename($this->arBucket, $sourcePath, $targetPath, $overwrite);
562 if ($this->queueFlag)
567 foreach (
GetModuleEvents(
'clouds',
'OnAfterRenameFile',
true) as $arEvent)
584 $result = $this->service->ListFiles($this->arBucket, $filePath, $bRecursive,
$pageSize, $pageMarker);
598 $DIR_NAME = mb_substr($filePath, 0, mb_strrpos($filePath,
'/') + 1);
599 $FILE_NAME = mb_substr($filePath, mb_strlen($DIR_NAME));
601 $arFileInfo = $this->service->GetFileInfo($this->arBucket, $filePath);
602 if ($arFileInfo ===
false && $this->
RenewToken())
604 $arFileInfo = $this->service->GetFileInfo($this->
getBucketArray(), $filePath);
607 if ($arFileInfo ===
null)
609 $arListing = $this->service->ListFiles($this->arBucket, $DIR_NAME,
false);
610 if (is_array($arListing))
612 foreach ($arListing[
'file'] as
$i =>
$name)
614 if (
$name === $FILE_NAME)
618 'size' => $arListing[
'file_size'][
$i],
619 'mtime' => $arListing[
'file_mtime'][
$i],
620 'hash' => $arListing[
'file_hash'][
$i],
628 $arFileInfo[
'name'] = $FILE_NAME;
643 return doubleval($fileInfo[
'size']);
657 return self::$arBuckets;
670 if (array_key_exists(
'ACTIVE',
$arFields))
675 if (array_key_exists(
'READ_ONLY',
$arFields))
683 if (!array_key_exists(
$arFields[
'SERVICE_ID'], $arServices))
685 $aMsg[] = [
'id' =>
'SERVICE_ID',
'text' =>
GetMessage(
'CLO_STORAGE_WRONG_SERVICE')];
694 if (mb_strpos(
$arFields[
'BUCKET'],
'.') !==
false)
696 $arName = explode(
'.',
$arFields[
'BUCKET']);
698 foreach ($arName as
$str)
700 if (mb_strlen(
$str) < 2 || mb_strlen(
$str) > 63)
709 $aMsg[] = [
'id' =>
'BUCKET',
'text' =>
GetMessage(
'CLO_STORAGE_EMPTY_BUCKET')];
711 if (preg_match(
'/[^a-z0-9._-]/',
$arFields[
'BUCKET']) > 0)
713 $aMsg[] = [
'id' =>
'BUCKET',
'text' =>
GetMessage(
'CLO_STORAGE_BAD_BUCKET_NAME')];
717 $aMsg[] = [
'id' =>
'BUCKET',
'text' =>
GetMessage(
'CLO_STORAGE_WRONG_BUCKET_NAME_LENGTH')];
721 $aMsg[] = [
'id' =>
'BUCKET',
'text' =>
GetMessage(
'CLO_STORAGE_WRONG_BUCKET_NAME_LENGTH2')];
723 if (!preg_match(
'/^[a-z0-9].*[a-z0-9]$/',
$arFields[
'BUCKET']))
725 $aMsg[] = [
'id' =>
'BUCKET',
'text' =>
GetMessage(
'CLO_STORAGE_BAD_BUCKET_NAME2')];
727 if (preg_match(
'/(-\\.|\\.-)/',
$arFields[
'BUCKET']) > 0)
729 $aMsg[] = [
'id' =>
'BUCKET',
'text' =>
GetMessage(
'CLO_STORAGE_BAD_BUCKET_NAME3')];
735 '=SERVICE_ID' =>
$arFields[
'SERVICE_ID'],
741 $aMsg[] = [
'id' =>
'BUCKET',
'text' =>
GetMessage(
'CLO_STORAGE_BUCKET_ALREADY_EXISTS')];
746 if (array_key_exists(
'FAILOVER_ACTIVE',
$arFields))
756 if (array_key_exists(
'FAILOVER_COPY',
$arFields))
761 if (array_key_exists(
'FAILOVER_DELETE',
$arFields))
766 if (array_key_exists(
'FAILOVER_DELETE_DELAY',
$arFields))
771 if (array_key_exists(
'CNAME',
$arFields))
795 if (!is_array($arSelect))
799 if (
count($arSelect) < 1)
817 'FAILOVER_BUCKET_ID',
820 'FAILOVER_DELETE_DELAY',
824 if (!is_array($arOrder))
830 foreach ($arOrder as $strColumn => $strDirection)
832 $strColumn = mb_strtoupper($strColumn);
833 $strDirection = mb_strtoupper($strDirection) ===
'ASC' ?
'ASC' :
'DESC';
838 $arSelect[] = $strColumn;
839 $arQueryOrder[$strColumn] = $strColumn .
' ' . $strDirection;
847 foreach ($arSelect as $strColumn)
849 $strColumn = mb_strtoupper($strColumn);
866 case 'FAILOVER_ACTIVE':
867 case 'FAILOVER_BUCKET_ID':
868 case 'FAILOVER_COPY':
869 case 'FAILOVER_DELETE':
870 case 'FAILOVER_DELETE_DELAY':
871 $arQuerySelect[$strColumn] =
's.' . $strColumn;
875 if (
count($arQuerySelect) < 1)
877 $arQuerySelect = [
'ID' =>
's.ID'];
883 'TABLE_ALIAS' =>
's',
884 'FIELD_NAME' =>
's.ID',
885 'FIELD_TYPE' =>
'int',
888 'TABLE_ALIAS' =>
's',
889 'FIELD_NAME' =>
's.ACTIVE',
890 'FIELD_TYPE' =>
'string',
893 'TABLE_ALIAS' =>
's',
894 'FIELD_NAME' =>
's.READ_ONLY',
895 'FIELD_TYPE' =>
'string',
898 'TABLE_ALIAS' =>
's',
899 'FIELD_NAME' =>
's.SERVICE_ID',
900 'FIELD_TYPE' =>
'string',
903 'TABLE_ALIAS' =>
's',
904 'FIELD_NAME' =>
's.BUCKET',
905 'FIELD_TYPE' =>
'string',
907 'FAILOVER_ACTIVE' => [
908 'TABLE_ALIAS' =>
's',
909 'FIELD_NAME' =>
's.FAILOVER_ACTIVE',
910 'FIELD_TYPE' =>
'string',
912 'FAILOVER_BUCKET_ID' => [
913 'TABLE_ALIAS' =>
's',
914 'FIELD_NAME' =>
's.FAILOVER_BUCKET_ID',
915 'FIELD_TYPE' =>
'int',
918 'TABLE_ALIAS' =>
's',
919 'FIELD_NAME' =>
's.FAILOVER_COPY',
920 'FIELD_TYPE' =>
'string',
922 'FAILOVER_DELETE' => [
923 'TABLE_ALIAS' =>
's',
924 'FIELD_NAME' =>
's.FAILOVER_DELETE',
925 'FIELD_TYPE' =>
'string',
927 'FAILOVER_DELETE_DELAY' => [
928 'TABLE_ALIAS' =>
's',
929 'FIELD_NAME' =>
's.FAILOVER_DELETE_DELAY',
930 'FIELD_TYPE' =>
'int',
939 $strQueryWhere = $obQueryWhere->GetQuery(
$arFilter);
941 $bDistinct = $obQueryWhere->bDistinctReqired;
944 SELECT ' . ($bDistinct ?
'DISTINCT' :
'') .
'
945 ' . implode(
', ', $arQuerySelect) .
'
947 b_clouds_file_bucket s
948 ' . $obQueryWhere->GetJoins() .
'
951 if ($strQueryWhere !==
'')
955 ' . $strQueryWhere .
'
959 if (
count($arQueryOrder) > 0)
963 ' . implode(
', ', $arQueryOrder) .
'
967 return $DB->Query($strSql);
1003 $this->arBucket[
'SETTINGS'] =
$arFields[
'SETTINGS'];
1011 $creationResult =
true;
1014 if ($creationResult)
1017 $this->_ID =
$DB->Add(
'b_clouds_file_bucket',
$arFields);
1018 self::$arBuckets =
null;
1019 $this->arBucket =
null;
1020 if (CACHED_b_clouds_file_bucket !==
false)
1031 $strError =
GetMessage(
'CLO_STORAGE_CLOUD_ADD_ERROR', [
'#error_msg#' => $e->GetString()]);
1045 $e =
new CApplicationException(
$strError);
1060 $isEmptyBucket = $this->service->IsEmptyBucket($this->arBucket);
1061 $forceDeleteTry =
false;
1062 if (!$isEmptyBucket && is_object(
$APPLICATION->GetException()))
1066 $this->service->GetLastRequestStatus() == 301
1067 && $this->service->GetLastRequestHeader(
'x-amz-bucket-region') !==
''
1070 $forceDeleteTry =
true;
1074 if ($isEmptyBucket || $forceDeleteTry)
1076 $isDeleted = $this->service->DeleteBucket($this->arBucket);
1077 $forceDelete =
false;
1078 if (!$isDeleted && is_object(
$APPLICATION->GetException()))
1082 $this->service->GetLastRequestStatus() == 301
1083 && $this->service->GetLastRequestHeader(
'x-amz-bucket-region') !==
''
1086 $forceDelete =
true;
1090 if ($isDeleted || $forceDelete)
1092 $res =
$DB->Query(
'DELETE FROM b_clouds_file_bucket WHERE ID = ' . $this->_ID);
1093 if (CACHED_b_clouds_file_bucket !==
false)
1097 if (is_object(
$res))
1099 $this->arBucket =
null;
1111 $strError =
GetMessage(
'CLO_STORAGE_CLOUD_DELETE_ERROR', [
'#error_msg#' => is_object($e) ? $e->GetString() :
'']);
1119 $strError =
GetMessage(
'CLO_STORAGE_CLOUD_DELETE_ERROR', [
'#error_msg#' => $e->GetString()]);
1133 $e =
new CApplicationException(
$strError);
1146 if ($this->_ID <= 0)
1159 && isset(
$arFields[
'SETTINGS'][
'MIGRATE_TO'])
1167 if (!is_object($this->service))
1177 if (array_key_exists(
'FILE_RULES',
$arFields))
1189 if (array_key_exists(
'SETTINGS',
$arFields))
1198 $strUpdate =
$DB->PrepareUpdate(
'b_clouds_file_bucket',
$arFields);
1199 if ($strUpdate <>
'')
1202 UPDATE b_clouds_file_bucket SET
1204 WHERE ID = ' . $this->_ID .
'
1206 if (!is_object(
$DB->Query($strSql)))
1212 self::$arBuckets =
null;
1213 $this->arBucket =
null;
1214 if (CACHED_b_clouds_file_bucket !==
false)
1230 if (isset($arPOST[
'MODULE']) && is_array($arPOST[
'MODULE']))
1232 foreach ($arPOST[
'MODULE'] as
$i => $MODULE)
1234 if (!isset($arRules[intval(
$i)]))
1236 $arRules[intval(
$i)] = [
'MODULE' =>
'',
'EXTENSION' =>
'',
'SIZE' =>
''];
1238 $arRules[intval(
$i)][
'MODULE'] = $MODULE;
1242 if (isset($arPOST[
'EXTENSION']) && is_array($arPOST[
'EXTENSION']))
1244 foreach ($arPOST[
'EXTENSION'] as
$i => $EXTENSION)
1246 if (!isset($arRules[intval(
$i)]))
1248 $arRules[intval(
$i)] = [
'MODULE' =>
'',
'EXTENSION' =>
'',
'SIZE' =>
''];
1250 $arRules[intval(
$i)][
'EXTENSION'] = $EXTENSION;
1254 if (isset($arPOST[
'SIZE']) && is_array($arPOST[
'SIZE']))
1256 foreach ($arPOST[
'SIZE'] as
$i => $SIZE)
1258 if (!isset($arRules[intval(
$i)]))
1260 $arRules[intval(
$i)] = [
'MODULE' =>
'',
'EXTENSION' =>
'',
'SIZE' =>
''];
1262 $arRules[intval(
$i)][
'SIZE'] = $SIZE;
1276 $this->service->SetHeader(
$name, $value);
1288 UPDATE b_clouds_file_bucket
1289 SET FILE_COUNT = ' . intval($file_count) .
'
1290 ,FILE_SIZE = ' .
roundDB($file_size) .
'
1294 if (CACHED_b_clouds_file_bucket !==
false)
1312 INSERT INTO b_clouds_size_queue (BUCKET_ID, FILE_COUNT, FILE_SIZE)
1316 if (defined(
'BX_CLOUDS_COUNTERS_DEBUG'))
1321 if (!static::$applyFileCounterJobAdded)
1323 static::$applyFileCounterJobAdded =
true;
1339 INSERT INTO b_clouds_size_queue (BUCKET_ID, FILE_COUNT, FILE_SIZE)
1343 if (defined(
'BX_CLOUDS_COUNTERS_DEBUG'))
1348 if (!static::$applyFileCounterJobAdded)
1350 static::$applyFileCounterJobAdded =
true;
1365 if (
$connection->lock(
'CCloudStorageBucket::ApplyFileCounter'))
1367 $res =
$DB->Query(
'SELECT * FROM b_clouds_size_queue ORDER BY ID');
1369 while ($job =
$res->Fetch())
1371 if ($job[
'FILE_COUNT'] > 0)
1374 UPDATE b_clouds_file_bucket
1375 SET FILE_COUNT = FILE_COUNT + 1
1376 ,FILE_SIZE = FILE_SIZE + ' . $job[
'FILE_SIZE'] .
'
1377 WHERE ID = ' . $job[
'BUCKET_ID'] .
'
1381 COption::SetOptionString(
'main_size',
'~cloud', intval(COption::GetOptionString(
'main_size',
'~cloud')) + $job[
'FILE_SIZE']);
1383 elseif ($job[
'FILE_COUNT'] < 0)
1386 UPDATE b_clouds_file_bucket
1387 SET FILE_COUNT = case when FILE_COUNT - 1 > 0 then FILE_COUNT - 1 else 0 end
1388 ,FILE_SIZE = case when FILE_SIZE - ' . $job[
'FILE_SIZE'] .
' > 0 then FILE_SIZE - ' . $job[
'FILE_SIZE'] .
' else 0 end
1389 WHERE ID = ' . $job[
'BUCKET_ID'] .
'
1393 COption::SetOptionString(
'main_size',
'~cloud', intval(COption::GetOptionString(
'main_size',
'~cloud')) - $job[
'FILE_SIZE']);
1396 $DB->Query(
'DELETE FROM b_clouds_size_queue WHERE ID = ' . $job[
'ID']);
1399 if ($c > 0 && CACHED_b_clouds_file_bucket !==
false)
1404 $connection->unlock(
'CCloudStorageBucket::ApplyFileCounter');
static getConnection($name="")
static queueCopy($obBucket, $FILE_PATH)
static queueDelete($obBucket, $FILE_PATH)
static queueRename($obBucket, $FILE_PATH_FROM, $FILE_PATH_TO)
IncFileCounter($file_size=0.0)
FileRename($sourcePath, $targetPath, $overwrite=true)
DecFileCounter($file_size=0.0)
CheckFields(&$arFields, $ID)
CheckSettings(&$arSettings)
DownloadToFile($arFile, $filePath)
SetFileCounter($file_size, $file_count)
DeleteFile($filePath, $fileSize=null)
__construct($ID, $enabledFailover=true)
setQueueFlag($queueFlag=true)
FileCopy($arFile, $filePath)
static $applyFileCounterJobAdded
static GetList($arOrder=[], $arFilter=[], $arSelect=[])
static ConvertPOST($arPOST)
GetFileSRC($arFile, $encoded=true)
Add($arFields, $createBucket=true)
SaveFile($filePath, $arFile)
static ApplyFileCounter()
ListFiles($filePath='/', $bRecursive=false, $pageSize=0, $pageMarker='')
static GetServiceByID($ID)
static getInstance($action='counters')
roundDB($value, $len=18, $dec=4)
ExecuteModuleEventEx($arEvent, $arParams=[])
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
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."%"