1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
storage_bucket.php
См. документацию.
1<?php
3
21{
22 protected/*.int.*/$_ID = 0;
23 protected/*.array[string]string.*/$arBucket;
24 protected $enabledFailover = true;
25 protected/*.CCloudStorageBucket.*/$failoverBucket;
26 protected $queueFlag = true;
28 protected/*.CCloudStorageService.*/ $service;
29 protected static/*.array[int][string]string.*/$arBuckets;
30
35 public function __construct($ID, $enabledFailover = true)
36 {
37 $this->_ID = intval($ID);
39 {
40 $this->disableFailOver();
41 }
42 }
43
44 public function disableFailOver()
45 {
46 $this->enabledFailover = false;
47 }
48
52 public function isFailoverEnabled()
53 {
55 }
56
60 public function setQueueFlag($queueFlag = true)
61 {
62 $this->queueFlag = (bool)$queueFlag;
63 }
64
68 public function getQueueFlag()
69 {
70 return $this->queueFlag;
71 }
72
73 protected function GetActualBucketId()
74 {
75 if (
77 && $this->FAILOVER_ACTIVE === 'Y'
78 && $this->FAILOVER_BUCKET_ID > 0
79 )
80 {
81 return $this->FAILOVER_BUCKET_ID;
82 }
83 else
84 {
85 return $this->ID;
86 }
87 }
88
92 public function getBucketArray()
93 {
94 if (!isset($this->arBucket))
95 {
96 self::_init();
97 $this->arBucket = self::$arBuckets[$this->_ID];
98 if (
100 && $this->arBucket['FAILOVER_ACTIVE'] === 'Y'
101 && $this->arBucket['FAILOVER_BUCKET_ID'] > 0
102 )
103 {
104 $this->failoverBucket = new CCloudStorageBucket($this->FAILOVER_BUCKET_ID, false);
105 if ($this->failoverBucket->Init())
106 {
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;
113 }
114 else
115 {
116 $this->failoverBucket = null;
117 }
118 }
119 }
120
121 return $this->arBucket;
122 }
123
127 public function getService()
128 {
129 return $this->service;
130 }
131
136 private static function CompileModuleRule($str)
137 {
138 $res = [];
139 $ar = explode(',', $str);
140 foreach ($ar as $s)
141 {
142 $s = trim($s);
143 if ($s !== '')
144 {
145 $res[$s] = preg_quote($s, '/');
146 }
147 }
148 if (!empty($res))
149 {
150 return '/^(' . implode('|', $res) . ')$/';
151 }
152 else
153 {
154 return '';
155 }
156 }
157
162 private static function CompileExtentionRule($str)
163 {
164 $res = [];
165 $ar = explode(',', $str);
166 foreach ($ar as $s)
167 {
168 $s = trim($s);
169 if ($s !== '')
170 {
171 $res[$s] = preg_quote('.' . $s, '/');
172 }
173 }
174 if (!empty($res))
175 {
176 return '/(' . implode('|', $res) . ')$/i';
177 }
178 else
179 {
180 return '';
181 }
182 }
183
188 private static function ParseSize($str)
189 {
190 static $scale = [
191 '' => 1.0,
192 'K' => 1024.0,
193 'M' => 1048576.0,
194 'G' => 1073741824.0,
195 ];
196 $str = mb_strtoupper(trim($str));
197 if ($str !== '' && preg_match('/([0-9.]+)(|K|M|G)$/', $str, $match) > 0)
198 {
199 return doubleval($match[1]) * $scale[$match[2]];
200 }
201 else
202 {
203 return 0.0;
204 }
205 }
206
211 private static function CompileSizeRule($str)
212 {
213 $res = /*.(array[int][int]double).*/[];
214 $ar = explode(',', $str);
215 foreach ($ar as $s)
216 {
217 $s = trim($s);
218 if ($s !== '')
219 {
220 $arSize = explode('-', $s);
221 if (count($arSize) == 1)
222 {
223 $res[] = [self::ParseSize($arSize[0]), self::ParseSize($arSize[0])];
224 }
225 else
226 {
227 $res[] = [self::ParseSize($arSize[0]), self::ParseSize($arSize[1])];
228 }
229 }
230 }
231 return $res;
232 }
233
238 private static function CompileRules($arRules)
239 {
240 $arCompiled = /*.(array[int][string]string).*/[];
241 if (is_array($arRules))
242 {
243 foreach ($arRules as $rule)
244 {
245 if (is_array($rule))
246 {
247 $arCompiled[] = [
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']) : '',
251 ];
252 }
253 }
254 }
255 return $arCompiled;
256 }
257
261 private static function _init()
262 {
263 global $DB, $CACHE_MANAGER;
264
265 if (isset(self::$arBuckets))
266 {
267 return;
268 }
269
270 $cache_id = 'cloud_buckets_v2';
271 if (
272 CACHED_b_clouds_file_bucket !== false
273 && $CACHE_MANAGER->Read(CACHED_b_clouds_file_bucket, $cache_id, 'b_clouds_file_bucket')
274 )
275 {
276 self::$arBuckets = $CACHE_MANAGER->Get($cache_id);
277 }
278 else
279 {
280 self::$arBuckets = /*.(array[int]CCloudStorageBucket).*/[];
281
282 $rs = $DB->Query('
283 SELECT *
284 FROM b_clouds_file_bucket
285 ORDER BY SORT DESC, ID ASC
286 ');
287 while (is_array($ar = $rs->Fetch()))
288 {
289 if ($ar['FILE_RULES'] != '')
290 {
291 $arRules = unserialize($ar['FILE_RULES'], ['allowed_classes' => false]);
292 }
293 else
294 {
295 $arRules = [];
296 }
297
298 $ar['FILE_RULES_COMPILED'] = self::CompileRules($arRules);
299
300 if ($ar['SETTINGS'] != '')
301 {
302 $arSettings = unserialize($ar['SETTINGS'], ['allowed_classes' => false]);
303 }
304 else
305 {
306 $arSettings = [];
307 }
308
309 if (is_array($arSettings))
310 {
311 $ar['SETTINGS'] = $arSettings;
312 }
313 else
314 {
315 $ar['SETTINGS'] = [];
316 }
317
318 self::$arBuckets[intval($ar['ID'])] = $ar;
319 }
320
321 if (CACHED_b_clouds_file_bucket !== false)
322 {
323 $CACHE_MANAGER->Set($cache_id, self::$arBuckets);
324 }
325 }
326 }
327
332 public function __get($name)
333 {
334 $arBucket = $this->getBucketArray();
335 if ($arBucket && array_key_exists($name, $arBucket))
336 {
337 return $arBucket[$name];
338 }
339 else
340 {
341 return null;
342 }
343 }
344
348 public function Init()
349 {
350 if (is_object($this->service))
351 {
352 return true;
353 }
354 else
355 {
356 if ($this->SERVICE_ID)
357 {
358 $this->service = CCloudStorage::GetServiceByID($this->SERVICE_ID);
359 }
360 return is_object($this->service);
361 }
362 }
363
367 public function RenewToken()
368 {
369 if ($this->service->tokenHasExpired)
370 {
371 $arBucket = $this->failoverBucket ? $this->failoverBucket->arBucket : $this->arBucket;
372 $newSettings = false;
373 foreach (GetModuleEvents('clouds', 'OnExpiredToken', true) as $arEvent)
374 {
375 $newSettings = ExecuteModuleEventEx($arEvent, [$arBucket]);
376 if ($newSettings)
377 {
378 break;
379 }
380 }
381
382 if ($newSettings)
383 {
384 if ($this->failoverBucket)
385 {
386 $updateResult = $this->failoverBucket->Update(['SETTINGS' => $newSettings]);
387 $this->arBucket = null;
388 }
389 else
390 {
391 $updateResult = $this->Update(['SETTINGS' => $newSettings]);
392 }
393
394 if ($updateResult)
395 {
396 $this->service->tokenHasExpired = false;
397 return true;
398 }
399 }
400 }
401
402 return false;
403 }
404
409 public function CheckSettings(&$arSettings)
410 {
411 return $this->service->CheckSettings($this->arBucket, $arSettings);
412 }
413
417 public function CreateBucket()
418 {
419 return $this->service->CreateBucket($this->arBucket);
420 }
421
427 public function GetFileSRC($arFile, $encoded = true)
428 {
429 if (is_array($arFile) && isset($arFile['URN']))
430 {
431 return $this->service->GetFileSRC($this->arBucket, $arFile['URN'], $encoded);
432 }
433 else
434 {
435 return preg_replace("'(?<!:)/+'s", '/', $this->service->GetFileSRC($this->arBucket, $arFile, $encoded));
436 }
437 }
438
443 public function FileExists($filePath)
444 {
445 $result = $this->service->FileExists($this->arBucket, $filePath);
446 if (!$result && $this->RenewToken())
447 {
448 $result = $this->service->FileExists($this->getBucketArray(), $filePath);
449 }
450 return $result;
451 }
452
458 public function DownloadToFile($arFile, $filePath)
459 {
460 $result = $this->service->DownloadToFile($this->arBucket, $arFile, $filePath);
461 return $result;
462 }
463
469 public function SaveFile($filePath, $arFile)
470 {
471 $result = $this->service->SaveFile($this->arBucket, $filePath, $arFile);
472 if (!$result && $this->RenewToken())
473 {
474 $result = $this->service->SaveFile($this->getBucketArray(), $filePath, $arFile);
475 }
476
477 if ($result)
478 {
479 if ($this->queueFlag)
480 {
481 CCloudFailover::queueCopy($this, $filePath);
482 }
483
484 foreach (GetModuleEvents('clouds', 'OnAfterSaveFile', true) as $arEvent)
485 {
486 ExecuteModuleEventEx($arEvent, [$this, $arFile, $filePath]);
487 }
488 }
489 return $result;
490 }
491
496 public function DeleteFile($filePath, $fileSize = null)
497 {
498 $result = $this->service->DeleteFile($this->arBucket, $filePath);
499 if (!$result && $this->RenewToken())
500 {
501 $result = $this->service->DeleteFile($this->getBucketArray(), $filePath);
502 }
503
504 if ($result)
505 {
506 if ($this->queueFlag)
507 {
508 CCloudFailover::queueDelete($this, $filePath);
509 }
510
511 $eventData = [
512 'del' => 'Y',
513 'size' => $fileSize,
514 ];
515 foreach (GetModuleEvents('clouds', 'OnAfterDeleteFile', true) as $arEvent)
516 {
517 ExecuteModuleEventEx($arEvent, [$this, $eventData, $filePath]);
518 }
519 }
520 return $result;
521 }
522
528 public function FileCopy($arFile, $filePath)
529 {
530 $result = $this->service->FileCopy($this->arBucket, $arFile, $filePath);
531 if (!$result && $this->RenewToken())
532 {
533 $result = $this->service->FileCopy($this->getBucketArray(), $arFile, $filePath);
534 }
535
536 if ($result)
537 {
538 if ($this->queueFlag)
539 {
540 CCloudFailover::queueCopy($this, $filePath);
541 }
542
543 foreach (GetModuleEvents('clouds', 'OnAfterCopyFile', true) as $arEvent)
544 {
545 ExecuteModuleEventEx($arEvent, [$this, $arFile, $filePath]);
546 }
547 }
548 return $result;
549 }
550
557 public function FileRename($sourcePath, $targetPath, $overwrite = true)
558 {
559 $result = $this->service->FileRename($this->arBucket, $sourcePath, $targetPath, $overwrite);
560 if ($result)
561 {
562 if ($this->queueFlag)
563 {
564 CCloudFailover::queueRename($this, $sourcePath, $targetPath);
565 }
566
567 foreach (GetModuleEvents('clouds', 'OnAfterRenameFile', true) as $arEvent)
568 {
569 ExecuteModuleEventEx($arEvent, [$this, $sourcePath, $targetPath]);
570 }
571 }
572 return $result;
573 }
574
582 public function ListFiles($filePath = '/', $bRecursive = false, $pageSize = 0, $pageMarker = '')
583 {
584 $result = $this->service->ListFiles($this->arBucket, $filePath, $bRecursive, $pageSize, $pageMarker);
585 if (!$result && $this->RenewToken())
586 {
587 $result = $this->service->ListFiles($this->getBucketArray(), $filePath, $bRecursive, $pageSize, $pageMarker);
588 }
589 return $result;
590 }
591
596 public function GetFileInfo($filePath)
597 {
598 $DIR_NAME = mb_substr($filePath, 0, mb_strrpos($filePath, '/') + 1);
599 $FILE_NAME = mb_substr($filePath, mb_strlen($DIR_NAME));
600
601 $arFileInfo = $this->service->GetFileInfo($this->arBucket, $filePath);
602 if ($arFileInfo === false && $this->RenewToken())
603 {
604 $arFileInfo = $this->service->GetFileInfo($this->getBucketArray(), $filePath);
605 }
606
607 if ($arFileInfo === null)
608 {
609 $arListing = $this->service->ListFiles($this->arBucket, $DIR_NAME, false);
610 if (is_array($arListing))
611 {
612 foreach ($arListing['file'] as $i => $name)
613 {
614 if ($name === $FILE_NAME)
615 {
616 return [
617 'name' => $name,
618 'size' => $arListing['file_size'][$i],
619 'mtime' => $arListing['file_mtime'][$i],
620 'hash' => $arListing['file_hash'][$i],
621 ];
622 }
623 }
624 }
625 }
626 elseif ($arFileInfo)
627 {
628 $arFileInfo['name'] = $FILE_NAME;
629 return $arFileInfo;
630 }
631 return false;
632 }
633
638 public function GetFileSize($filePath)
639 {
640 $fileInfo = $this->GetFileInfo($filePath);
641 if ($fileInfo)
642 {
643 return doubleval($fileInfo['size']);
644 }
645 else
646 {
647 return 0.0;
648 }
649 }
650
654 public static function GetAllBuckets()
655 {
656 self::_init();
657 return self::$arBuckets;
658 }
659
665 public function CheckFields(&$arFields, $ID)
666 {
667 global $APPLICATION;
668 $aMsg = [];
669
670 if (array_key_exists('ACTIVE', $arFields))
671 {
672 $arFields['ACTIVE'] = $arFields['ACTIVE'] === 'N' ? 'N' : 'Y';
673 }
674
675 if (array_key_exists('READ_ONLY', $arFields))
676 {
677 $arFields['READ_ONLY'] = $arFields['READ_ONLY'] === 'Y' ? 'Y' : 'N';
678 }
679
680 $arServices = CCloudStorage::GetServiceList();
681 if (isset($arFields['SERVICE_ID']))
682 {
683 if (!array_key_exists($arFields['SERVICE_ID'], $arServices))
684 {
685 $aMsg[] = ['id' => 'SERVICE_ID', 'text' => GetMessage('CLO_STORAGE_WRONG_SERVICE')];
686 }
687 }
688
689 if (isset($arFields['BUCKET']))
690 {
691 $arFields['BUCKET'] = trim($arFields['BUCKET']);
692
693 $bBadLength = false;
694 if (mb_strpos($arFields['BUCKET'], '.') !== false)
695 {
696 $arName = explode('.', $arFields['BUCKET']);
697 $bBadLength = false;
698 foreach ($arName as $str)
699 {
700 if (mb_strlen($str) < 2 || mb_strlen($str) > 63)
701 {
702 $bBadLength = true;
703 }
704 }
705 }
706
707 if ($arFields['BUCKET'] == '')
708 {
709 $aMsg[] = ['id' => 'BUCKET', 'text' => GetMessage('CLO_STORAGE_EMPTY_BUCKET')];
710 }
711 if (preg_match('/[^a-z0-9._-]/', $arFields['BUCKET']) > 0)
712 {
713 $aMsg[] = ['id' => 'BUCKET', 'text' => GetMessage('CLO_STORAGE_BAD_BUCKET_NAME')];
714 }
715 if (mb_strlen($arFields['BUCKET']) < 2 || mb_strlen($arFields['BUCKET']) > 63)
716 {
717 $aMsg[] = ['id' => 'BUCKET', 'text' => GetMessage('CLO_STORAGE_WRONG_BUCKET_NAME_LENGTH')];
718 }
719 if ($bBadLength)
720 {
721 $aMsg[] = ['id' => 'BUCKET', 'text' => GetMessage('CLO_STORAGE_WRONG_BUCKET_NAME_LENGTH2')];
722 }
723 if (!preg_match('/^[a-z0-9].*[a-z0-9]$/', $arFields['BUCKET']))
724 {
725 $aMsg[] = ['id' => 'BUCKET', 'text' => GetMessage('CLO_STORAGE_BAD_BUCKET_NAME2')];
726 }
727 if (preg_match('/(-\\.|\\.-)/', $arFields['BUCKET']) > 0)
728 {
729 $aMsg[] = ['id' => 'BUCKET', 'text' => GetMessage('CLO_STORAGE_BAD_BUCKET_NAME3')];
730 }
731
732 if ($arFields['BUCKET'] <> '')
733 {
734 $rsBucket = self::GetList([], [
735 '=SERVICE_ID' => $arFields['SERVICE_ID'],
736 '=BUCKET' => $arFields['BUCKET'],
737 ]);
738 $arBucket = $rsBucket->Fetch();
739 if (is_array($arBucket) && $arBucket['ID'] != $ID)
740 {
741 $aMsg[] = ['id' => 'BUCKET', 'text' => GetMessage('CLO_STORAGE_BUCKET_ALREADY_EXISTS')];
742 }
743 }
744 }
745
746 if (array_key_exists('FAILOVER_ACTIVE', $arFields))
747 {
748 $arFields['FAILOVER_ACTIVE'] = $arFields['FAILOVER_ACTIVE'] === 'Y' ? 'Y' : 'N';
749 }
750
751 if (isset($arFields['FAILOVER_BUCKET_ID']) && $arFields['FAILOVER_BUCKET_ID'] == $ID)
752 {
753 unset($arFields['FAILOVER_BUCKET_ID']);
754 }
755
756 if (array_key_exists('FAILOVER_COPY', $arFields))
757 {
758 $arFields['FAILOVER_COPY'] = $arFields['FAILOVER_COPY'] === 'Y' ? 'Y' : 'N';
759 }
760
761 if (array_key_exists('FAILOVER_DELETE', $arFields))
762 {
763 $arFields['FAILOVER_DELETE'] = $arFields['FAILOVER_DELETE'] === 'Y' ? 'Y' : 'N';
764 }
765
766 if (array_key_exists('FAILOVER_DELETE_DELAY', $arFields))
767 {
768 $arFields['FAILOVER_DELETE_DELAY'] = (int)$arFields['FAILOVER_DELETE_DELAY'];
769 }
770
771 if (array_key_exists('CNAME', $arFields))
772 {
773 $arFields['CNAME'] = preg_replace('#^https?://#i', '', $arFields['CNAME']);
774 }
775
776 if (!empty($aMsg))
777 {
778 $e = new CAdminException($aMsg);
779 $APPLICATION->ThrowException($e);
780 return false;
781 }
782 return true;
783 }
784
791 public static function GetList($arOrder=[], $arFilter=[], $arSelect=[])
792 {
793 global $DB;
794
795 if (!is_array($arSelect))
796 {
797 $arSelect = /*.(array[string]string).*/[];
798 }
799 if (count($arSelect) < 1)
800 {
801 $arSelect = [
802 'ID',
803 'ACTIVE',
804 'READ_ONLY',
805 'SORT',
806 'SERVICE_ID',
807 'LOCATION',
808 'BUCKET',
809 'SETTINGS',
810 'CNAME',
811 'PREFIX',
812 'FILE_COUNT',
813 'FILE_SIZE',
814 'LAST_FILE_ID',
815 'FILE_RULES',
816 'FAILOVER_ACTIVE',
817 'FAILOVER_BUCKET_ID',
818 'FAILOVER_COPY',
819 'FAILOVER_DELETE',
820 'FAILOVER_DELETE_DELAY',
821 ];
822 }
823
824 if (!is_array($arOrder))
825 {
826 $arOrder = /*.(array[string]string).*/[];
827 }
828
829 $arQueryOrder = [];
830 foreach ($arOrder as $strColumn => $strDirection)
831 {
832 $strColumn = mb_strtoupper($strColumn);
833 $strDirection = mb_strtoupper($strDirection) === 'ASC' ? 'ASC' : 'DESC';
834 switch ($strColumn)
835 {
836 case 'ID':
837 case 'SORT':
838 $arSelect[] = $strColumn;
839 $arQueryOrder[$strColumn] = $strColumn . ' ' . $strDirection;
840 break;
841 default:
842 break;
843 }
844 }
845
846 $arQuerySelect = [];
847 foreach ($arSelect as $strColumn)
848 {
849 $strColumn = mb_strtoupper($strColumn);
850 switch ($strColumn)
851 {
852 case 'ID':
853 case 'ACTIVE':
854 case 'READ_ONLY':
855 case 'SORT':
856 case 'SERVICE_ID':
857 case 'LOCATION':
858 case 'BUCKET':
859 case 'SETTINGS':
860 case 'CNAME':
861 case 'PREFIX':
862 case 'FILE_COUNT':
863 case 'FILE_SIZE':
864 case 'LAST_FILE_ID':
865 case 'FILE_RULES':
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;
872 break;
873 }
874 }
875 if (count($arQuerySelect) < 1)
876 {
877 $arQuerySelect = ['ID' => 's.ID'];
878 }
879
880 $obQueryWhere = new CSQLWhere;
881 $arFields = [
882 'ID' => [
883 'TABLE_ALIAS' => 's',
884 'FIELD_NAME' => 's.ID',
885 'FIELD_TYPE' => 'int',
886 ],
887 'ACTIVE' => [
888 'TABLE_ALIAS' => 's',
889 'FIELD_NAME' => 's.ACTIVE',
890 'FIELD_TYPE' => 'string',
891 ],
892 'READ_ONLY' => [
893 'TABLE_ALIAS' => 's',
894 'FIELD_NAME' => 's.READ_ONLY',
895 'FIELD_TYPE' => 'string',
896 ],
897 'SERVICE_ID' => [
898 'TABLE_ALIAS' => 's',
899 'FIELD_NAME' => 's.SERVICE_ID',
900 'FIELD_TYPE' => 'string',
901 ],
902 'BUCKET' => [
903 'TABLE_ALIAS' => 's',
904 'FIELD_NAME' => 's.BUCKET',
905 'FIELD_TYPE' => 'string',
906 ],
907 'FAILOVER_ACTIVE' => [
908 'TABLE_ALIAS' => 's',
909 'FIELD_NAME' => 's.FAILOVER_ACTIVE',
910 'FIELD_TYPE' => 'string',
911 ],
912 'FAILOVER_BUCKET_ID' => [
913 'TABLE_ALIAS' => 's',
914 'FIELD_NAME' => 's.FAILOVER_BUCKET_ID',
915 'FIELD_TYPE' => 'int',
916 ],
917 'FAILOVER_COPY' => [
918 'TABLE_ALIAS' => 's',
919 'FIELD_NAME' => 's.FAILOVER_COPY',
920 'FIELD_TYPE' => 'string',
921 ],
922 'FAILOVER_DELETE' => [
923 'TABLE_ALIAS' => 's',
924 'FIELD_NAME' => 's.FAILOVER_DELETE',
925 'FIELD_TYPE' => 'string',
926 ],
927 'FAILOVER_DELETE_DELAY' => [
928 'TABLE_ALIAS' => 's',
929 'FIELD_NAME' => 's.FAILOVER_DELETE_DELAY',
930 'FIELD_TYPE' => 'int',
931 ],
932 ];
933 $obQueryWhere->SetFields($arFields);
934
935 if (!is_array($arFilter))
936 {
937 $arFilter = /*.(array[string]string).*/[];
938 }
939 $strQueryWhere = $obQueryWhere->GetQuery($arFilter);
940
941 $bDistinct = $obQueryWhere->bDistinctReqired;
942
943 $strSql = '
944 SELECT ' . ($bDistinct ? 'DISTINCT' : '') . '
945 ' . implode(', ', $arQuerySelect) . '
946 FROM
947 b_clouds_file_bucket s
948 ' . $obQueryWhere->GetJoins() . '
949 ';
950
951 if ($strQueryWhere !== '')
952 {
953 $strSql .= '
954 WHERE
955 ' . $strQueryWhere . '
956 ';
957 }
958
959 if (count($arQueryOrder) > 0)
960 {
961 $strSql .= '
962 ORDER BY
963 ' . implode(', ', $arQueryOrder) . '
964 ';
965 }
966
967 return $DB->Query($strSql);
968 }
969
975 public function Add($arFields, $createBucket = true)
976 {
978 $strError = '';
979 $this->_ID = 0;
980
981 if (!$this->CheckFields($arFields, 0))
982 {
983 return false;
984 }
985
986 $arFields['FILE_COUNT'] = 0;
987 if (is_array($arFields['FILE_RULES']))
988 {
989 $arFields['FILE_RULES'] = serialize($arFields['FILE_RULES']);
990 }
991 else
992 {
993 $arFields['FILE_RULES'] = false;
994 }
995
996 $this->arBucket = $arFields;
997 if ($this->Init())
998 {
999 if (!$this->CheckSettings($arFields['SETTINGS']))
1000 {
1001 return false;
1002 }
1003 $this->arBucket['SETTINGS'] = $arFields['SETTINGS'];
1004
1005 if ($createBucket)
1006 {
1007 $creationResult = $this->CreateBucket();
1008 }
1009 else
1010 {
1011 $creationResult = true;
1012 }
1013
1014 if ($creationResult)
1015 {
1016 $arFields['SETTINGS'] = serialize($arFields['SETTINGS']);
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)
1021 {
1022 $CACHE_MANAGER->CleanDir('b_clouds_file_bucket');
1023 }
1024 return $this->_ID;
1025 }
1026 else
1027 {
1028 $e = $APPLICATION->GetException();
1029 if (is_object($e))
1030 {
1031 $strError = GetMessage('CLO_STORAGE_CLOUD_ADD_ERROR', ['#error_msg#' => $e->GetString()]);
1032 }
1033 else
1034 {
1035 $strError = GetMessage('CLO_STORAGE_CLOUD_ADD_ERROR', ['#error_msg#' => 'CSB42343']);
1036 }
1037 }
1038 }
1039 else
1040 {
1041 $strError = GetMessage('CLO_STORAGE_CLOUD_ADD_ERROR', ['#error_msg#' => GetMessage('CLO_STORAGE_UNKNOWN_SERVICE')]);
1042 }
1043
1044 $APPLICATION->ResetException();
1045 $e = new CApplicationException($strError);
1046 $APPLICATION->ThrowException($e);
1047 return false;
1048 }
1049
1053 public function Delete()
1054 {
1056 $strError = '';
1057
1058 if ($this->Init())
1059 {
1060 $isEmptyBucket = $this->service->IsEmptyBucket($this->arBucket);
1061 $forceDeleteTry = false;
1062 if (!$isEmptyBucket && is_object($APPLICATION->GetException()))
1063 {
1064 // The bucket was created within wrong s3 region
1065 if (
1066 $this->service->GetLastRequestStatus() == 301
1067 && $this->service->GetLastRequestHeader('x-amz-bucket-region') !== ''
1068 )
1069 {
1070 $forceDeleteTry = true;
1071 }
1072 }
1073
1074 if ($isEmptyBucket || $forceDeleteTry)
1075 {
1076 $isDeleted = $this->service->DeleteBucket($this->arBucket);
1077 $forceDelete = false;
1078 if (!$isDeleted && is_object($APPLICATION->GetException()))
1079 {
1080 // The bucket was created within wrong s3 region
1081 if (
1082 $this->service->GetLastRequestStatus() == 301
1083 && $this->service->GetLastRequestHeader('x-amz-bucket-region') !== ''
1084 )
1085 {
1086 $forceDelete = true;
1087 }
1088 }
1089
1090 if ($isDeleted || $forceDelete)
1091 {
1092 $res = $DB->Query('DELETE FROM b_clouds_file_bucket WHERE ID = ' . $this->_ID);
1093 if (CACHED_b_clouds_file_bucket !== false)
1094 {
1095 $CACHE_MANAGER->CleanDir('b_clouds_file_bucket');
1096 }
1097 if (is_object($res))
1098 {
1099 $this->arBucket = null;
1100 $this->_ID = 0;
1101 return true;
1102 }
1103 else
1104 {
1105 $strError = GetMessage('CLO_STORAGE_DB_DELETE_ERROR');
1106 }
1107 }
1108 else
1109 {
1110 $e = $APPLICATION->GetException();
1111 $strError = GetMessage('CLO_STORAGE_CLOUD_DELETE_ERROR', ['#error_msg#' => is_object($e) ? $e->GetString() : '']);
1112 }
1113 }
1114 else
1115 {
1116 $e = $APPLICATION->GetException();
1117 if (is_object($e))
1118 {
1119 $strError = GetMessage('CLO_STORAGE_CLOUD_DELETE_ERROR', ['#error_msg#' => $e->GetString()]);
1120 }
1121 else
1122 {
1123 $strError = GetMessage('CLO_STORAGE_CLOUD_BUCKET_NOT_EMPTY');
1124 }
1125 }
1126 }
1127 else
1128 {
1129 $strError = GetMessage('CLO_STORAGE_CLOUD_DELETE_ERROR', ['#error_msg#' => GetMessage('CLO_STORAGE_UNKNOWN_SERVICE')]);
1130 }
1131
1132 $APPLICATION->ResetException();
1133 $e = new CApplicationException($strError);
1134 $APPLICATION->ThrowException($e);
1135 return false;
1136 }
1137
1142 public function Update($arFields)
1143 {
1144 global $DB, $CACHE_MANAGER;
1145
1146 if ($this->_ID <= 0)
1147 {
1148 return false;
1149 }
1150
1151 unset($arFields['FILE_COUNT']);
1152 unset($arFields['SERVICE_ID']);
1153 unset($arFields['LOCATION']);
1154 unset($arFields['BUCKET']);
1155
1156 if (
1157 array_key_exists('SETTINGS', $arFields)
1158 && is_array($arFields['SETTINGS'])
1159 && isset($arFields['SETTINGS']['MIGRATE_TO'])
1160 && $arFields['SETTINGS']['MIGRATE_TO']
1161 )
1162 {
1163 $this->SERVICE_ID = $arFields['SERVICE_ID'] = $arFields['SETTINGS']['MIGRATE_TO'];
1164 }
1165
1166 $this->service = CCloudStorage::GetServiceByID($this->SERVICE_ID);
1167 if (!is_object($this->service))
1168 {
1169 return false;
1170 }
1171
1172 if (!$this->CheckFields($arFields, $this->_ID))
1173 {
1174 return false;
1175 }
1176
1177 if (array_key_exists('FILE_RULES', $arFields))
1178 {
1179 if (is_array($arFields['FILE_RULES']))
1180 {
1181 $arFields['FILE_RULES'] = serialize($arFields['FILE_RULES']);
1182 }
1183 else
1184 {
1185 $arFields['FILE_RULES'] = false;
1186 }
1187 }
1188
1189 if (array_key_exists('SETTINGS', $arFields))
1190 {
1191 if (!$this->CheckSettings($arFields['SETTINGS']))
1192 {
1193 return false;
1194 }
1195 $arFields['SETTINGS'] = serialize($arFields['SETTINGS']);
1196 }
1197
1198 $strUpdate = $DB->PrepareUpdate('b_clouds_file_bucket', $arFields);
1199 if ($strUpdate <> '')
1200 {
1201 $strSql = '
1202 UPDATE b_clouds_file_bucket SET
1203 ' . $strUpdate . '
1204 WHERE ID = ' . $this->_ID . '
1205 ';
1206 if (!is_object($DB->Query($strSql)))
1207 {
1208 return false;
1209 }
1210 }
1211
1212 self::$arBuckets = null;
1213 $this->arBucket = null;
1214 if (CACHED_b_clouds_file_bucket !== false)
1215 {
1216 $CACHE_MANAGER->CleanDir('b_clouds_file_bucket');
1217 }
1218
1219 return $this->_ID;
1220 }
1221
1226 public static function ConvertPOST($arPOST)
1227 {
1228 $arRules = /*.(array[int][string]string).*/[];
1229
1230 if (isset($arPOST['MODULE']) && is_array($arPOST['MODULE']))
1231 {
1232 foreach ($arPOST['MODULE'] as $i => $MODULE)
1233 {
1234 if (!isset($arRules[intval($i)]))
1235 {
1236 $arRules[intval($i)] = ['MODULE' => '', 'EXTENSION' => '', 'SIZE' => ''];
1237 }
1238 $arRules[intval($i)]['MODULE'] = $MODULE;
1239 }
1240 }
1241
1242 if (isset($arPOST['EXTENSION']) && is_array($arPOST['EXTENSION']))
1243 {
1244 foreach ($arPOST['EXTENSION'] as $i => $EXTENSION)
1245 {
1246 if (!isset($arRules[intval($i)]))
1247 {
1248 $arRules[intval($i)] = ['MODULE' => '', 'EXTENSION' => '', 'SIZE' => ''];
1249 }
1250 $arRules[intval($i)]['EXTENSION'] = $EXTENSION;
1251 }
1252 }
1253
1254 if (isset($arPOST['SIZE']) && is_array($arPOST['SIZE']))
1255 {
1256 foreach ($arPOST['SIZE'] as $i => $SIZE)
1257 {
1258 if (!isset($arRules[intval($i)]))
1259 {
1260 $arRules[intval($i)] = ['MODULE' => '', 'EXTENSION' => '', 'SIZE' => ''];
1261 }
1262 $arRules[intval($i)]['SIZE'] = $SIZE;
1263 }
1264 }
1265
1266 return $arRules;
1267 }
1268
1274 public function setHeader($name, $value)
1275 {
1276 $this->service->SetHeader($name, $value);
1277 }
1278
1284 public function SetFileCounter($file_size, $file_count)
1285 {
1286 global $DB, $CACHE_MANAGER;
1287 $res = $DB->Query('
1288 UPDATE b_clouds_file_bucket
1289 SET FILE_COUNT = ' . intval($file_count) . '
1290 ,FILE_SIZE = ' . roundDB($file_size) . '
1291 WHERE ID = ' . $this->GetActualBucketId() . '
1292 ');
1293
1294 if (CACHED_b_clouds_file_bucket !== false)
1295 {
1296 $CACHE_MANAGER->CleanDir('b_clouds_file_bucket');
1297 }
1298 return $res;
1299 }
1300
1301 protected static $applyFileCounterJobAdded = false;
1302
1307 public function IncFileCounter($file_size = 0.0)
1308 {
1309 global $DB;
1310
1311 $res = $DB->Query('
1312 INSERT INTO b_clouds_size_queue (BUCKET_ID, FILE_COUNT, FILE_SIZE)
1313 VALUES (' . $this->GetActualBucketId() . ', 1, ' . roundDB($file_size) . ')
1314 ');
1315
1316 if (defined('BX_CLOUDS_COUNTERS_DEBUG'))
1317 {
1318 \CCloudsDebug::getInstance()->endAction();
1319 }
1320
1321 if (!static::$applyFileCounterJobAdded)
1322 {
1323 static::$applyFileCounterJobAdded = true;
1324 \Bitrix\Main\Application::getInstance()->addBackgroundJob([__CLASS__, 'ApplyFileCounter'], [], \Bitrix\Main\Application::JOB_PRIORITY_NORMAL);
1325 }
1326
1327 return $res;
1328 }
1329
1334 public function DecFileCounter($file_size = 0.0)
1335 {
1336 global $DB;
1337
1338 $res = $DB->Query('
1339 INSERT INTO b_clouds_size_queue (BUCKET_ID, FILE_COUNT, FILE_SIZE)
1340 VALUES (' . $this->GetActualBucketId() . ', -1, ' . roundDB($file_size) . ')
1341 ');
1342
1343 if (defined('BX_CLOUDS_COUNTERS_DEBUG'))
1344 {
1345 \CCloudsDebug::getInstance()->endAction();
1346 }
1347
1348 if (!static::$applyFileCounterJobAdded)
1349 {
1350 static::$applyFileCounterJobAdded = true;
1351 \Bitrix\Main\Application::getInstance()->addBackgroundJob([__CLASS__, 'ApplyFileCounter'], [], \Bitrix\Main\Application::JOB_PRIORITY_NORMAL);
1352 }
1353
1354 return $res;
1355 }
1356
1360 public static function ApplyFileCounter()
1361 {
1362 global $DB, $CACHE_MANAGER;
1363
1365 if ($connection->lock('CCloudStorageBucket::ApplyFileCounter'))
1366 {
1367 $res = $DB->Query('SELECT * FROM b_clouds_size_queue ORDER BY ID');
1368 $c = 0;
1369 while ($job = $res->Fetch())
1370 {
1371 if ($job['FILE_COUNT'] > 0)
1372 {
1373 $DB->Query('
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'] . '
1378 ');
1379 $c++;
1380
1381 COption::SetOptionString('main_size', '~cloud', intval(COption::GetOptionString('main_size', '~cloud')) + $job['FILE_SIZE']);
1382 }
1383 elseif ($job['FILE_COUNT'] < 0)
1384 {
1385 $DB->Query('
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'] . '
1390 ');
1391 $c++;
1392
1393 COption::SetOptionString('main_size', '~cloud', intval(COption::GetOptionString('main_size', '~cloud')) - $job['FILE_SIZE']);
1394 }
1395
1396 $DB->Query('DELETE FROM b_clouds_size_queue WHERE ID = ' . $job['ID']);
1397 }
1398
1399 if ($c > 0 && CACHED_b_clouds_file_bucket !== false)
1400 {
1401 $CACHE_MANAGER->CleanDir('b_clouds_file_bucket');
1402 }
1403
1404 $connection->unlock('CCloudStorageBucket::ApplyFileCounter');
1405 }
1406 }
1407}
$connection
Определения actionsdefinitions.php:38
global $APPLICATION
Определения include.php:80
static getInstance()
Определения application.php:98
static getConnection($name="")
Определения application.php:638
static queueCopy($obBucket, $FILE_PATH)
Определения failover.php:44
static queueDelete($obBucket, $FILE_PATH)
Определения failover.php:17
static queueRename($obBucket, $FILE_PATH_FROM, $FILE_PATH_TO)
Определения failover.php:89
static IsEnabled()
Определения failover.php:12
GetFileSize($filePath)
Определения storage_bucket.php:638
static GetAllBuckets()
Определения storage_bucket.php:654
disableFailOver()
Определения storage_bucket.php:44
IncFileCounter($file_size=0.0)
Определения storage_bucket.php:1307
FileRename($sourcePath, $targetPath, $overwrite=true)
Определения storage_bucket.php:557
DecFileCounter($file_size=0.0)
Определения storage_bucket.php:1334
CheckFields(&$arFields, $ID)
Определения storage_bucket.php:665
GetFileInfo($filePath)
Определения storage_bucket.php:596
CheckSettings(&$arSettings)
Определения storage_bucket.php:409
static $arBuckets
Определения storage_bucket.php:29
setHeader($name, $value)
Определения storage_bucket.php:1274
Update($arFields)
Определения storage_bucket.php:1142
FileExists($filePath)
Определения storage_bucket.php:443
getBucketArray()
Определения storage_bucket.php:92
isFailoverEnabled()
Определения storage_bucket.php:52
DownloadToFile($arFile, $filePath)
Определения storage_bucket.php:458
SetFileCounter($file_size, $file_count)
Определения storage_bucket.php:1284
DeleteFile($filePath, $fileSize=null)
Определения storage_bucket.php:496
__construct($ID, $enabledFailover=true)
Определения storage_bucket.php:35
setQueueFlag($queueFlag=true)
Определения storage_bucket.php:60
CreateBucket()
Определения storage_bucket.php:417
$enabledFailover
Определения storage_bucket.php:24
$failoverBucket
Определения storage_bucket.php:25
getQueueFlag()
Определения storage_bucket.php:68
FileCopy($arFile, $filePath)
Определения storage_bucket.php:528
__get($name)
Определения storage_bucket.php:332
static $applyFileCounterJobAdded
Определения storage_bucket.php:1301
static GetList($arOrder=[], $arFilter=[], $arSelect=[])
Определения storage_bucket.php:791
static ConvertPOST($arPOST)
Определения storage_bucket.php:1226
GetActualBucketId()
Определения storage_bucket.php:73
getService()
Определения storage_bucket.php:127
GetFileSRC($arFile, $encoded=true)
Определения storage_bucket.php:427
Add($arFields, $createBucket=true)
Определения storage_bucket.php:975
RenewToken()
Определения storage_bucket.php:367
SaveFile($filePath, $arFile)
Определения storage_bucket.php:469
static ApplyFileCounter()
Определения storage_bucket.php:1360
ListFiles($filePath='/', $bRecursive=false, $pageSize=0, $pageMarker='')
Определения storage_bucket.php:582
static GetServiceByID($ID)
Определения storage.php:44
static GetServiceList()
Определения storage.php:60
static getInstance($action='counters')
Определения include.php:53
Определения sqlwhere.php:1359
global $CACHE_MANAGER
Определения clear_component_cache.php:7
$str
Определения commerceml2.php:63
$arFields
Определения dblapprove.php:5
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
if($ajaxMode) $ID
Определения get_user.php:27
$strError
Определения options_user_settings.php:4
global $DB
Определения cron_frame.php:29
$pageSize
Определения csv_new_run.php:34
roundDB($value, $len=18, $dec=4)
Определения tools.php:4641
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
$name
Определения menu_edit.php:35
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
$i
Определения factura.php:643
</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."%"
Определения waybill.php:936
$rs
Определения action.php:82
$arFilter
Определения user_search.php:106