%PDF- %PDF- 403WebShell
403Webshell
Server IP : 37.220.80.31  /  Your IP : 3.147.238.1
Web Server : Apache/2.4.52 (Ubuntu)
System : Linux 3051455-guretool.twc1.net 5.15.0-107-generic #117-Ubuntu SMP Fri Apr 26 12:26:49 UTC 2024 x86_64
User : www-root ( 1010)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/www-root/data/www/dev.artlot24.ru/bitrix/modules/clouds/classes/general/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/www-root/data/www/dev.artlot24.ru/bitrix/modules/clouds/classes/general/storage.php
<?php
IncludeModuleLangFile(__FILE__);

class CCloudStorage
{
	const FILE_SKIPPED = 0;
	const FILE_MOVED = 1;
	const FILE_PARTLY_UPLOADED = 2;
	const FILE_UPLOAD_ERROR = 3;

	public static $part_size = 0;
	public static $part_count = 0;

	private static $_services = /*.(array[string]CCloudStorageService).*/
		null;

	public static $file_skip_reason = '';
	/**
	 * @return void
	 */
	static function _init()
	{
		if (!isset(self::$_services))
		{
			$obService = /*.(CCloudStorageService).*/
				null;
			self::$_services = /*.(array[string]CCloudStorageService).*/
				array();
			foreach (GetModuleEvents("clouds", "OnGetStorageService", true) as $arEvent)
			{
				$obService = ExecuteModuleEventEx($arEvent);
				if (is_object($obService))
					self::$_services[$obService->GetID()] = $obService;
			}
		}
	}

	/**
	 * @param string $ID
	 * @return CCloudStorageService
	 */
	public static function GetServiceByID($ID)
	{
		self::_init();
		if (array_key_exists($ID, self::$_services))
			return self::$_services[$ID];
		else
			return null;
	}

	/**
	 * @return array[string]CCloudStorageService
	 */
	public static function GetServiceList()
	{
		self::_init();
		return self::$_services;
	}

	/**
	 * @param string $ID
	 * @return array[string]string|false
	 */
	public static function GetServiceLocationList($ID)
	{
		$obService = CCloudStorage::GetServiceByID($ID);
		if (is_object($obService))
			return $obService->GetLocationList();
		else
			return /*.(array[string]string).*/
				array();
	}

	/**
	 * @param string $ID
	 * @return string
	 */
	public static function GetServiceDescription($ID)
	{
		$obService = CCloudStorage::GetServiceByID($ID);
		if (is_object($obService))
			return $obService->GetName();
		else
			return "";
	}

	/**
	 * @param array [string]string $arFile
	 * @param string $strFileName
	 * @return CCloudStorageBucket
	 */
	public static function FindBucketForFile($arFile, $strFileName)
	{
		if (array_key_exists("size", $arFile) && $arFile["size"] > 0)
			$file_size = intval($arFile["size"]);
		elseif (array_key_exists("FILE_SIZE", $arFile) && $arFile["FILE_SIZE"] > 0)
			$file_size = intval($arFile["FILE_SIZE"]);
		else
			$file_size = intval($arFile["file_size"]);

		self::$file_skip_reason = '';
		$activeCounter = 0;
		$writableCounter = 0;
		foreach (CCloudStorageBucket::GetAllBuckets() as $bucket)
		{
			if ($bucket["ACTIVE"] !== "Y")
			{
				continue;
			}
			$activeCounter++;


			if ($bucket["READ_ONLY"] === "Y")
			{
				continue;
			}
			$writableCounter++;

			foreach ($bucket["FILE_RULES_COMPILED"] as $rule)
			{
				if ($rule["MODULE_MASK"] != "")
				{
					$bMatchModule = (preg_match($rule["MODULE_MASK"], $arFile["MODULE_ID"]) > 0);
				}
				else
				{
					$bMatchModule = true;
				}

				if ($rule["EXTENTION_MASK"] != "")
				{
					$bMatchExtention =
						(preg_match($rule["EXTENTION_MASK"], $strFileName) > 0)
						|| (preg_match($rule["EXTENTION_MASK"], $arFile["ORIGINAL_NAME"]) > 0);
				}
				else
				{
					$bMatchExtention = true;
				}

				if ($rule["SIZE_ARRAY"])
				{
					$bMatchSize = false;
					foreach ($rule["SIZE_ARRAY"] as $size)
					{
						if (
							($file_size >= $size[0])
							&& ($size[1] === 0.0 || $file_size <= $size[1])
						)
							$bMatchSize = true;
					}
				}
				else
				{
					$bMatchSize = true;
				}

				if (!$bMatchModule)
				{
					self::$file_skip_reason = 'NO_FILE_MODULE_MATCH';
				}
				elseif (!$bMatchExtention)
				{
					self::$file_skip_reason = 'NO_FILE_EXTENTION_MATCH';
				}
				elseif (!$bMatchSize)
				{
					self::$file_skip_reason = 'NO_FILE_SIZE_MATCH';
				}

				if ($bMatchModule && $bMatchExtention && $bMatchSize)
				{
					return new CCloudStorageBucket(intval($bucket["ID"]));
				}
			}
		}

		if (!$activeCounter)
		{
			self::$file_skip_reason = 'NO_ACTIVE_BUCKETS';
		}
		elseif (!$writableCounter)
		{
			self::$file_skip_reason = 'NO_WRITABLE_BUCKETS';
		}

		return null;
	}

	/**
	 * @param array [string]string $arFile
	 * @param array [string]string $arResizeParams
	 * @param array [string]mixed $callbackData
	 * @param bool $bNeedResize
	 * @param array [string]string $sourceImageFile
	 * @param array [string]string $cacheImageFileTmp
	 * @return bool
	 */
	public static function OnBeforeResizeImage($arFile, $arResizeParams, &$callbackData, &$bNeedResize, &$sourceImageFile, &$cacheImageFileTmp)
	{
		$callbackData = null;

		if (intval($arFile["HANDLER_ID"]) <= 0)
			return false;

		$obSourceBucket = new CCloudStorageBucket(intval($arFile["HANDLER_ID"]));
		if (!$obSourceBucket->Init())
			return false;

		$callbackData = /*.(array[string]mixed).*/
			array();
		$callbackData["obSourceBucket"] = $obSourceBucket;

		//Assume target bucket same as source
		$callbackData["obTargetBucket"] = $obTargetBucket = $obSourceBucket;

		//if original file bucket is read only
		if ($obSourceBucket->READ_ONLY === "Y") //Try to find bucket with write rights
		{
			$bucket = CCloudStorage::FindBucketForFile($arFile, $arFile["FILE_NAME"]);
			if (!is_object($bucket))
				return false;
			if ($bucket->Init())
			{
				$callbackData["obTargetBucket"] = $obTargetBucket = $bucket;
			}
		}

		if (!$arFile["SRC"])
		{
			$arFile["SRC"] = $obSourceBucket->GetFileSRC($arFile);
		}

		if (defined("BX_MOBILE") && constant("BX_MOBILE") === true)
			$bImmediate = true;
		else
			$bImmediate = $arResizeParams[5];

		$callbackData["cacheID"] = $arFile["ID"]."/".md5(serialize($arResizeParams));
		$callbackData["cacheOBJ"] = new CPHPCache;
		$callbackData["fileDIR"] = "/"."resize_cache/".$callbackData["cacheID"]."/".$arFile["SUBDIR"];
		$callbackData["fileNAME"] = $arFile["FILE_NAME"];
		$callbackData["fileURL"] = $callbackData["fileDIR"]."/".$callbackData["fileNAME"];

		$result = true;
		if ($callbackData["cacheOBJ"]->StartDataCache(CACHED_clouds_file_resize, $callbackData["cacheID"], "clouds"))
		{
			$cacheImageFile = $callbackData["obTargetBucket"]->GetFileSRC($callbackData["fileURL"]);
			$arDestinationSize = array();

			//Check if it is cache file was deleted, but there was a successful resize
			if (
				!$bImmediate
				&& COption::GetOptionString("clouds", "delayed_resize") === "Y"
				&& is_array($delayInfo = CCloudStorage::ResizeImageFileGet($cacheImageFile))
				&& $delayInfo["ERROR_CODE"] < 10
			)
			{
				$callbackData["cacheSTARTED"] = true;
				if ($arFile["FILE_SIZE"] > 1)
					$callbackData["fileSize"] = $arFile["FILE_SIZE"];
				$bNeedResize = false;
				$result = true;
			}
			elseif (
				is_array($delayInfo = CCloudStorage::ResizeImageFileGet($cacheImageFile))
				&& $delayInfo["ERROR_CODE"] < 10
			)
			{
				$callbackData["cacheSTARTED"] = true;
				if ($arFile["FILE_SIZE"] > 1)
					$callbackData["fileSize"] = $arFile["FILE_SIZE"];
				$bNeedResize = false;
				$result = true;
			}
			//Check if it is cache file was deleted, but not the file in the cloud
			elseif ($fs = $obTargetBucket->FileExists($callbackData["fileURL"]))
			{
				//If file was resized before the fact was registered
				if (COption::GetOptionString("clouds", "delayed_resize") === "Y")
				{
					CCloudStorage::ResizeImageFileAdd(
						$arDestinationSize,
						$arFile,
						$cacheImageFile,
						$arResizeParams,
						9 //already where
					);
				}

				$callbackData["cacheSTARTED"] = true;
				if ($fs > 1)
					$callbackData["fileSize"] = $fs;
				$bNeedResize = false;
				$result = true;
			}
			else
			{
				$callbackData["tmpFile"] = CFile::GetTempName('', $arFile["FILE_NAME"]);
				$callbackData["tmpFile"] = preg_replace("#[\\\\\\/]+#", "/", $callbackData["tmpFile"]);

				if (
					!$bImmediate
					&& COption::GetOptionString("clouds", "delayed_resize") === "Y"
					&& CCloudStorage::ResizeImageFileDelay(
						$arDestinationSize,
						$arFile,
						$cacheImageFile,
						$arResizeParams
					)
				)
				{
					$callbackData["cacheSTARTED"] = false;
					$bNeedResize = false;
					$callbackData["cacheOBJ"]->AbortDataCache();
					$callbackData["cacheVARS"] = array(
						"cacheImageFile" => $cacheImageFile,
						"width" => $arDestinationSize["width"],
						"height" => $arDestinationSize["height"],
					);
					$result = true;
				}
				elseif ($obSourceBucket->DownloadToFile($arFile, $callbackData["tmpFile"]))
				{
					$callbackData["cacheSTARTED"] = true;
					$bNeedResize = true;
					$sourceImageFile = $callbackData["tmpFile"];
					$cacheImageFileTmp = CFile::GetTempName('', $arFile["FILE_NAME"]);
					$result = true;
				}
				else
				{
					$callbackData["cacheSTARTED"] = false;
					$bNeedResize = false;
					$callbackData["cacheOBJ"]->AbortDataCache();
					$result = false;
				}
			}
		}
		else
		{
			$callbackData["cacheSTARTED"] = false;
			$callbackData["cacheVARS"] = $callbackData["cacheOBJ"]->GetVars();
			$bNeedResize = false;
			$result = true;
		}

		return $result;
	}

	public static function OnAfterResizeImage($arFile, $arResizeParams, &$callbackData, &$cacheImageFile, &$cacheImageFileTmp, &$arImageSize)
	{
		global $arCloudImageSizeCache;
		$io = CBXVirtualIo::GetInstance();

		if (!is_array($callbackData))
			return false;

		if ($callbackData["cacheSTARTED"])
		{
			/** @var CCloudStorageBucket $obTargetBucket */
			$obTargetBucket = $callbackData["obTargetBucket"];
			/** @var CPHPCache $cacheOBJ */
			$cacheOBJ = $callbackData["cacheOBJ"];

			if (isset($callbackData["tmpFile"])) //have to upload to the cloud
			{
				$arFileToStore = CFile::MakeFileArray($io->GetPhysicalName($cacheImageFileTmp));
				if (!preg_match("/^image\\//", $arFileToStore["type"]))
					$arFileToStore["type"] = $arFile["CONTENT_TYPE"];

				if ($obTargetBucket->SaveFile($callbackData["fileURL"], $arFileToStore))
				{
					$cacheImageFile = $obTargetBucket->GetFileSRC($callbackData["fileURL"]);

					$arImageSize = CFile::GetImageSize($cacheImageFileTmp);
					$arImageSize[2] = filesize($io->GetPhysicalName($cacheImageFileTmp));
					$iFileSize = filesize($arFileToStore["tmp_name"]);

					if (!is_array($arImageSize))
						$arImageSize = array(0, 0);
					$cacheOBJ->EndDataCache(array(
						"cacheImageFile" => $cacheImageFile,
						"width" => $arImageSize[0],
						"height" => $arImageSize[1],
						"size" => $arImageSize[2],
					));

					$tmpFile = $io->GetPhysicalName($callbackData["tmpFile"]);
					unlink($tmpFile);
					@rmdir(mb_substr($tmpFile, 0, -mb_strlen(bx_basename($tmpFile))));

					$arCloudImageSizeCache[$cacheImageFile] = $arImageSize;

					$obTargetBucket->IncFileCounter($iFileSize);

					if (
						COption::GetOptionString("clouds", "delayed_resize") === "Y"
						&& !is_array(CCloudStorage::ResizeImageFileGet($cacheImageFile))
					)
					{
						$arDestinationSize = array();
						CCloudStorage::ResizeImageFileAdd(
							$arDestinationSize,
							$arFile,
							$cacheImageFile,
							$arResizeParams,
							9 //already there
						);
					}

					return true;
				}
				else
				{
					$cacheOBJ->AbortDataCache();

					$tmpFile = $io->GetPhysicalName($callbackData["tmpFile"]);
					unlink($tmpFile);
					@rmdir(mb_substr($tmpFile, 0, -mb_strlen(bx_basename($tmpFile))));

					unlink($cacheImageFileTmp);
					@rmdir(mb_substr($cacheImageFileTmp, 0, -mb_strlen(bx_basename($cacheImageFileTmp))));

					$obSourceBucket = new CCloudStorageBucket(intval($arFile["HANDLER_ID"]));
					if ($obSourceBucket->Init())
					{
						$cacheImageFile = $obSourceBucket->GetFileSRC($arFile);
					}

					return false;
				}
			}
			else //the file is already in the cloud
			{
				$bNeedCreatePicture = false;
				$arSourceSize = array("x" => 0, "y" => 0, "width" => 0, "height" => 0);
				$arDestinationSize = array("x" => 0, "y" => 0, "width" => 0, "height" => 0);
				CFile::ScaleImage($arFile["WIDTH"], $arFile["HEIGHT"], $arResizeParams[0], $arResizeParams[1], $bNeedCreatePicture, $arSourceSize, $arDestinationSize);

				$cacheImageFile = $obTargetBucket->GetFileSRC($callbackData["fileURL"]);
				$arImageSize = array(
					$arDestinationSize["width"],
					$arDestinationSize["height"],
					isset($callbackData["fileSize"])? $callbackData["fileSize"]: $obTargetBucket->GetFileSize($callbackData["fileURL"]),
				);
				$cacheOBJ->EndDataCache(array(
					"cacheImageFile" => $cacheImageFile,
					"width" => $arImageSize[0],
					"height" => $arImageSize[1],
					"size" => $arImageSize[2],
				));

				$arCloudImageSizeCache[$cacheImageFile] = $arImageSize;

				return true;
			}
		}
		elseif (is_array($callbackData["cacheVARS"]))
		{
			$cacheImageFile = $callbackData["cacheVARS"]["cacheImageFile"];
			$arImageSize = array(
				$callbackData["cacheVARS"]["width"],
				$callbackData["cacheVARS"]["height"],
				$callbackData["cacheVARS"]["size"],
			);
			$arCloudImageSizeCache[$cacheImageFile] = $arImageSize;
			return true;
		}

		return false;
	}

	public static function ResizeImageFileGet($destinationFile)
	{
		global $DB;
		$destinationFile = preg_replace("/^https?:/i", "", $destinationFile);
		$q = $DB->Query("
			select
				ID
				,ERROR_CODE
				,FILE_ID
				,".$DB->DateToCharFunction("TIMESTAMP_X", "FULL")." TIMESTAMP_X
			from b_clouds_file_resize
			where TO_PATH = '".$DB->ForSql($destinationFile)."'
		");
		$a = $q->Fetch();
		return $a;
	}

	public static function ResizeImageFileAdd(&$arDestinationSize, $sourceFile, $destinationFile, $arResizeParams, $errorCode = 0)
	{
		global $DB;
		$destinationFile = preg_replace("/^https?:/i", "", $destinationFile);
		$q = $DB->Query("
			select
				ID
				,ERROR_CODE
				,PARAMS
				,".$DB->DateToCharFunction("TIMESTAMP_X", "FULL")." TIMESTAMP_X
			from b_clouds_file_resize
			where TO_PATH = '".$DB->ForSql($destinationFile)."'
		");

		$a = $q->Fetch();
		if ($a && $a["ERROR_CODE"] >= 10 && $a["ERROR_CODE"] < 20)
		{
			$DB->Query("DELETE from b_clouds_file_resize WHERE ID = ".$a["ID"]);
			$a = false;
		}

		if (!$a)
		{
			$arResizeParams["type"] = $sourceFile["CONTENT_TYPE"];
			$DB->Add("b_clouds_file_resize", array(
				"~TIMESTAMP_X" => $DB->CurrentTimeFunction(),
				"ERROR_CODE" => intval($errorCode),
				"PARAMS" => serialize($arResizeParams),
				"FROM_PATH" => $sourceFile["SRC"],
				"TO_PATH" => $destinationFile,
				"FILE_ID" => $sourceFile["ID"],
			));
		}
	}

	public static function ResizeImageFileDelay(&$arDestinationSize, $sourceFile, $destinationFile, $arResizeParams)
	{
		global $DB;
		$destinationFile = preg_replace("/^https?:/i", "", $destinationFile);
		$q = $DB->Query("
			select
				ID
				,ERROR_CODE
				,PARAMS
				,".$DB->DateToCharFunction("TIMESTAMP_X", "FULL")." TIMESTAMP_X
			from b_clouds_file_resize
			where TO_PATH = '".$DB->ForSql($destinationFile)."'
		");
		if ($resize = $q->Fetch())
		{
			if ($resize["ERROR_CODE"] < 10)
			{
				$arResizeParams = unserialize($resize["PARAMS"], ['allowed_classes' => false]);
				$id = $resize["ID"];
			} //Give it a try
			elseif (
				$resize["ERROR_CODE"] >= 10
				&& $resize["ERROR_CODE"] < 20
				&& (MakeTimeStamp($resize["TIMESTAMP_X"]) + 300/*5min*/) < (time() + CTimeZone::GetOffset())
			)
			{
				$DB->Query("
					UPDATE b_clouds_file_resize
					SET ERROR_CODE='1'
					WHERE ID=".$resize["ID"]."
				");
				$arResizeParams = unserialize($resize["PARAMS"], ['allowed_classes' => false]);
				$id = $resize["ID"];
			}
			else
			{
				return false;
			}
		}
		else
		{
			$id = 0;
		}

		$sourceImageWidth = $sourceFile["WIDTH"];
		$sourceImageHeight = $sourceFile["HEIGHT"];
		$arSize = $arResizeParams[0];
		$resizeType = $arResizeParams[1];
		$arWaterMark = $arResizeParams[2];
		$jpgQuality = $arResizeParams[3];
		$arFilters = $arResizeParams[4];
		$bNeedCreatePicture = false;
		$arSourceSize = array("x" => 0, "y" => 0, "width" => 0, "height" => 0);
		$arDestinationSize = array("x" => 0, "y" => 0, "width" => 0, "height" => 0);

		CFile::ScaleImage(
			$sourceImageWidth,
			$sourceImageHeight,
			$arSize,
			$resizeType,
			$bNeedCreatePicture,
			$arSourceSize,
			$arDestinationSize
		);
		$bNeedCreatePicture |= is_array($arWaterMark) && !empty($arWaterMark);
		$bNeedCreatePicture |= is_array($arFilters) && !empty($arFilters);

		if ($bNeedCreatePicture)
		{
			if ($id <= 0)
			{
				$arResizeParams["type"] = $sourceFile["CONTENT_TYPE"];
				$id = $DB->Add("b_clouds_file_resize", array(
					"~TIMESTAMP_X" => $DB->CurrentTimeFunction(),
					"ERROR_CODE" => "2",
					"PARAMS" => serialize($arResizeParams),
					"FROM_PATH" => $sourceFile["SRC"],
					"TO_PATH" => $destinationFile,
					"FILE_ID" => $sourceFile["ID"],
				));
			}

			return $id > 0;
		}
		else
		{
			return false;
		}
	}

	/**
	 * @param CCloudStorageBucket $obBucket
	 * @param string $path
	 * @return bool
	 */
	public static function ResizeImageFileCheck($obBucket, $path)
	{
		global $DB;
		$path = preg_replace("/^https?:/i", "", $path);
		$q = $DB->Query("
			select
				ID
				,ERROR_CODE
				,TO_PATH
				,FROM_PATH
				,PARAMS
				,".$DB->DateToCharFunction("TIMESTAMP_X", "FULL")." TIMESTAMP_X
			from b_clouds_file_resize
			where TO_PATH = '".$DB->ForSql($path)."'
		");
		$task = $q->Fetch();
		if (!$task)
			return false;

		//File in the Sky with Diamonds
		if ($task["ERROR_CODE"] == 9)
		{
			return true;
		}

		//Fatal error
		if ($task["ERROR_CODE"] >= 20)
		{
			return false;
		}

		//Recoverable error
		if ($task["ERROR_CODE"] >= 10 && $task["ERROR_CODE"] < 20)
		{
			if ((MakeTimeStamp($task["TIMESTAMP_X"]) + 300/*5min*/) > (time() + CTimeZone::GetOffset()))
				return false;
		}

		$DB->Query("
			UPDATE b_clouds_file_resize
			SET ERROR_CODE = '11'
			WHERE ID = ".$task["ID"]."
		");

		$tmpFile = CFile::MakeFileArray($task["FROM_PATH"]);
		if (!is_array($tmpFile) || !file_exists($tmpFile["tmp_name"]))
		{
			$DB->Query("
				UPDATE b_clouds_file_resize
				SET ERROR_CODE = '22'
				WHERE ID = ".$task["ID"]."
			");
			return false;
		}

		$arResizeParams = unserialize($task["PARAMS"], ['allowed_classes' => false]);
		if (!is_array($arResizeParams))
		{
			$DB->Query("
				UPDATE b_clouds_file_resize
				SET ERROR_CODE = '23'
				WHERE ID = ".$task["ID"]."
			");
			return false;
		}

		$DB->Query("
			UPDATE b_clouds_file_resize
			SET ERROR_CODE = '14'
			WHERE ID = ".$task["ID"]."
		");

		$arSize = $arResizeParams[0];
		$resizeType = $arResizeParams[1];
		$arWaterMark = $arResizeParams[2];
		$jpgQuality = $arResizeParams[3];
		$arFilters = $arResizeParams[4];

		$to_path = CFile::GetTempName('', bx_basename($task["TO_PATH"]));

		if (!CFile::ResizeImageFile($tmpFile["tmp_name"], $to_path, $arSize, $resizeType, $arWaterMark, $jpgQuality, $arFilters))
		{
			$DB->Query("
				UPDATE b_clouds_file_resize
				SET ERROR_CODE = '25'
				WHERE ID = ".$task["ID"]."
			");
			return false;
		}

		$DB->Query("
			UPDATE b_clouds_file_resize
			SET ERROR_CODE = '16'
			WHERE ID = ".$task["ID"]."
		");

		$fileToStore = CFile::MakeFileArray($to_path);
		if ($arResizeParams["type"] && !preg_match("/^image\\//", $fileToStore["type"]))
			$fileToStore["type"] = $arResizeParams["type"];

		$baseURL = preg_replace("/^https?:/i", "", $obBucket->GetFileSRC("/"));
		$pathToStore = mb_substr($task["TO_PATH"], mb_strlen($baseURL) - 1);
		if (!$obBucket->SaveFile(urldecode($pathToStore), $fileToStore))
		{
			$DB->Query("
				UPDATE b_clouds_file_resize
				SET ERROR_CODE = '27'
				WHERE ID = ".$task["ID"]."
			");
			return false;
		}
		$obBucket->IncFileCounter($fileToStore["size"]);
		$DB->Query("
			UPDATE b_clouds_file_resize
			SET ERROR_CODE = '9'
			WHERE ID = ".$task["ID"]."
		");
		return true;
	}

	public static function OnMakeFileArray($arSourceFile, &$arDestination)
	{
		if (!is_array($arSourceFile))
		{
			$file = $arSourceFile;
			if (mb_substr($file, 0, mb_strlen($_SERVER["DOCUMENT_ROOT"])) == $_SERVER["DOCUMENT_ROOT"])
				$file = ltrim(mb_substr($file, mb_strlen($_SERVER["DOCUMENT_ROOT"])), "/");

			if (!preg_match("/^http:\\/\\//", $file))
				return false;

			$bucket = CCloudStorage::FindBucketByFile($file);
			if (!is_object($bucket))
				return false;

			$filePath = mb_substr($file, mb_strlen($bucket->GetFileSRC("/")) - 1);
			$filePath = urldecode($filePath);

			$target = CFile::GetTempName('', bx_basename($filePath));
			$target = preg_replace("#[\\\\\\/]+#", "/", $target);

			if ($bucket->DownloadToFile($filePath, $target))
			{
				$arDestination = $target;
			}

			return true;
		}
		else
		{
			if ($arSourceFile["HANDLER_ID"] <= 0)
				return false;

			$bucket = new CCloudStorageBucket($arSourceFile["HANDLER_ID"]);
			if (!$bucket->Init())
				return false;

			$target = CFile::GetTempName('', $arSourceFile["FILE_NAME"]);
			$target = preg_replace("#[\\\\\\/]+#", "/", $target);

			if ($bucket->DownloadToFile($arSourceFile, $target))
			{
				$arDestination["name"] = ($arSourceFile['ORIGINAL_NAME'] <> ''? $arSourceFile['ORIGINAL_NAME']: $arSourceFile['FILE_NAME']);
				$arDestination["size"] = $arSourceFile['FILE_SIZE'];
				$arDestination["type"] = $arSourceFile['CONTENT_TYPE'];
				$arDestination["description"] = $arSourceFile['DESCRIPTION'];
				$arDestination["tmp_name"] = $target;
			}

			return true;
		}
	}

	public static function OnFileDelete($arFile)
	{
		global $DB;

		if ($arFile["HANDLER_ID"] <= 0)
			return false;

		$bucket = new CCloudStorageBucket($arFile["HANDLER_ID"]);
		if ((!$bucket->Init()) || ($bucket->READ_ONLY === "Y"))
			return false;

		$result = $bucket->DeleteFile("/".$arFile["SUBDIR"]."/".$arFile["FILE_NAME"]);
		if ($result)
			$bucket->DecFileCounter($arFile["FILE_SIZE"]);

		$path = '/resize_cache/'.$arFile["ID"]."/";
		$arCloudFiles = $bucket->ListFiles($path, true);
		if (is_array($arCloudFiles["file"]))
		{
			$delete_size = 0;
			foreach ($arCloudFiles["file"] as $i => $file_name)
			{
				$tmp = $bucket->DeleteFile($path.$file_name);
				if ($tmp)
				{
					$bucket->DecFileCounter($arCloudFiles["file_size"][$i]);
					$delete_size += $arCloudFiles["file_size"][$i];
				}
			}
			/****************************** QUOTA ******************************/
			if($delete_size > 0 && COption::GetOptionInt("main", "disk_space") > 0)
				CDiskQuota::updateDiskQuota("file", $delete_size, "delete");
			/****************************** QUOTA ******************************/
		}

		$DB->Query("
			DELETE FROM b_clouds_file_resize
			WHERE FILE_ID = ".intval($arFile["ID"])."
		", true);

		return $result;
	}

	public static function DeleteDirFilesEx($path)
	{
		$path = rtrim($path, "/")."/";
		foreach (CCloudStorageBucket::GetAllBuckets() as $bucket)
		{
			$obBucket = new CCloudStorageBucket($bucket["ID"]);
			if (
				$obBucket->Init()
				&& ($bucket->READ_ONLY == "N")
				&& ($bucket->ACTIVE == "Y")
			)
			{
				$arCloudFiles = $obBucket->ListFiles($path, true);
				if (is_array($arCloudFiles["file"]))
				{
					foreach ($arCloudFiles["file"] as $i => $file_name)
					{
						$tmp = $obBucket->DeleteFile($path.$file_name);
						if ($tmp)
							$obBucket->DecFileCounter($arCloudFiles["file_size"][$i]);
					}
				}
			}
		}
	}

	public static function OnFileCopy(&$arFile, $newPath = "")
	{
		if ($arFile["HANDLER_ID"] <= 0)
			return false;

		$bucket = new CCloudStorageBucket($arFile["HANDLER_ID"]);
		if (!$bucket->Init())
			return false;

		if ($bucket->READ_ONLY == "Y")
			return false;

		$filePath = "";
		$newName = "";

		if($newPath <> '')
		{
			$filePath = "/".trim(str_replace("//", "/", $newPath), "/");
		}
		else
		{
			$strFileExt = strrchr($arFile["FILE_NAME"], ".");
			while(true)
			{
				$newName = md5(uniqid(mt_rand(), true)).$strFileExt;
				$filePath = "/".$arFile["SUBDIR"]."/".$newName;
				if(!$bucket->FileExists($filePath))
				{
					break;
				}
			}
		}

		if ($newPath == '')
		{
			if ($arFile["EXTERNAL_ID"] == "")
			{
				$arFile["EXTERNAL_ID"] = md5(mt_rand());
			}

			\Bitrix\Clouds\FileSaveTable::startFileOperation(
				$bucket->ID
				,$arFile["SUBDIR"]
				,$newName
				,$arFile["EXTERNAL_ID"]
			);
		}

		$result = $bucket->FileCopy($arFile, $filePath);

		if ($result)
		{
			$copySize = $arFile["FILE_SIZE"];
			$bucket->IncFileCounter($copySize);
			\Bitrix\Clouds\FileSaveTable::setFileSize(
				$bucket->ID
				,$arFile["SUBDIR"]
				,$newName
				,$copySize
			);

			if($newPath <> '')
			{
				$arFile["FILE_NAME"] = bx_basename($filePath);
				$arFile["SUBDIR"] = mb_substr($filePath, 1, -(mb_strlen(bx_basename($filePath)) + 1));
			}
			else
			{
				$arFile["FILE_NAME"] = $newName;
			}
		}

		return $result;
	}

	public static function OnGetFileSRC($arFile)
	{
		if ($arFile["HANDLER_ID"] <= 0)
			return false;

		$bucket = new CCloudStorageBucket($arFile["HANDLER_ID"]);
		if ($bucket->Init())
			return $bucket->GetFileSRC($arFile);
		else
			return false;

	}

	protected static function _delete_file($file)
	{
		if (is_array($file))
		{
			CCloudStorage::OnFileDelete($file);
		}
		elseif (is_string($file) && file_exists($file))
		{
			unlink($file);
			@rmdir(mb_substr($file, 0, -mb_strlen(bx_basename($file))));
		}
	}

	public static function MoveFile($arFile, $obTargetBucket)
	{
		$io = CBXVirtualIo::GetInstance();
		self::$file_skip_reason = '';

		//Try to find suitable bucket for the file
		$bucket = CCloudStorage::FindBucketForFile($arFile, $arFile["FILE_NAME"]);
		if (!is_object($bucket))
		{
			return CCloudStorage::FILE_SKIPPED;
		}

		if (!$bucket->Init())
		{
			self::$file_skip_reason = 'FAILED_TO_INIT_BUCKET';
			return CCloudStorage::FILE_SKIPPED;
		}

		//Check if this is same bucket as the target
		if ($bucket->ID != $obTargetBucket->ID)
		{
			self::$file_skip_reason = 'FOUND_BUCKET_DOES_NOT_MATCH_TARGET';
			return CCloudStorage::FILE_SKIPPED;
		}

		$filePath = "/".$arFile["SUBDIR"]."/".$arFile["FILE_NAME"];
		$filePath = preg_replace("#[\\\\\\/]+#", "/", $filePath);

		if ($bucket->FileExists($filePath))
		{
			self::$file_skip_reason = 'CLOUD_FILE_EXISTS';
			return CCloudStorage::FILE_SKIPPED;
		}

		if ($arFile["FILE_SIZE"] > $bucket->GetService()->GetMinUploadPartSize())
		{
			$obUpload = new CCloudStorageUpload($filePath);
			if (!$obUpload->isStarted())
			{
				if ($arFile["HANDLER_ID"])
				{
					$ar = array();
					if (!CCloudStorage::OnMakeFileArray($arFile, $ar))
					{
						self::$file_skip_reason = 'FAILED_TO_DOWNLOAD_FILE_1';
						return CCloudStorage::FILE_SKIPPED;
					}

					if (!isset($ar["tmp_name"]))
					{
						self::$file_skip_reason = 'FAILED_TO_DOWNLOAD_FILE_2';
						return CCloudStorage::FILE_SKIPPED;
					}
				}
				else
				{
					$ar = CFile::MakeFileArray($arFile["ID"]);
					if (!isset($ar["tmp_name"]))
					{
						self::$file_skip_reason = 'FAILED_TO_GET_SOURCE_FILE_INFO_1';
						return CCloudStorage::FILE_SKIPPED;
					}
				}

				$temp_file = CTempFile::GetDirectoryName(2, "clouds").bx_basename($arFile["FILE_NAME"]);
				$temp_fileX = $io->GetPhysicalName($temp_file);
				CheckDirPath($temp_fileX);

				if (file_exists($ar["tmp_name"]))
				{
					$sourceFile = $ar["tmp_name"];
				}
				elseif (file_exists($io->GetPhysicalName($ar["tmp_name"])))
				{
					$sourceFile = $io->GetPhysicalName($ar["tmp_name"]);
				}
				else
				{
					self::$file_skip_reason = 'FAILED_TO_FIND_SOURCE_FILE';
					return CCloudStorage::FILE_SKIPPED;
				}

				if (!copy($sourceFile, $temp_fileX))
				{
					self::$file_skip_reason = 'FAILED_TO_COPY_SOURCE_FILE';
					return CCloudStorage::FILE_SKIPPED;
				}

				if ($obUpload->Start($bucket->ID, $arFile["FILE_SIZE"], $arFile["CONTENT_TYPE"], $temp_file))
				{
					return CCloudStorage::FILE_PARTLY_UPLOADED;
				}
				else
				{
					self::$file_skip_reason = 'FAILED_TO_START_UPLOAD';
					return CCloudStorage::FILE_SKIPPED;
				}
			}
			else
			{
				$temp_file = $obUpload->getTempFileName();
				$temp_fileX = $io->GetPhysicalName($temp_file);

				$fp = fopen($temp_fileX, "rb");
				if (!is_resource($fp))
				{
					self::$file_skip_reason = 'FAILED_TO_READ_SOURCE_FILE';
					return CCloudStorage::FILE_SKIPPED;
				}

				$pos = $obUpload->getPos();
				if ($pos > filesize($temp_fileX))
				{
					if ($obUpload->Finish())
					{
						$bucket->IncFileCounter(filesize($temp_fileX));

						if ($arFile["HANDLER_ID"])
						{
							self::_delete_file($arFile);
						}
						else
						{
							$ar = CFile::MakeFileArray($arFile["ID"]);
							$fileNameX = $io->GetPhysicalName($ar["tmp_name"]);
							self::_delete_file($fileNameX);
						}

						return CCloudStorage::FILE_MOVED;
					}
					else
					{
						self::$file_skip_reason = 'FAILED_TO_FINISH_UPLOAD';
						return CCloudStorage::FILE_SKIPPED;
					}
				}

				fseek($fp, $pos);
				self::$part_count = $obUpload->GetPartCount();
				self::$part_size = $obUpload->getPartSize();
				$part = fread($fp, self::$part_size);
				while ($obUpload->hasRetries())
				{
					if ($obUpload->Next($part))
					{
						return CCloudStorage::FILE_PARTLY_UPLOADED;
					}
				}

				self::$file_skip_reason = 'FAILED_TO_UPLOAD_FILE_CHUNK';
				return CCloudStorage::FILE_SKIPPED;
			}
		}
		else
		{
			if ($arFile["HANDLER_ID"])
			{
				$ar = array();
				if (!CCloudStorage::OnMakeFileArray($arFile, $ar))
				{
					self::$file_skip_reason = 'FAILED_TO_DOWNLOAD_FILE_3';
					return CCloudStorage::FILE_SKIPPED;
				}

				if (!isset($ar["tmp_name"]))
				{
					self::$file_skip_reason = 'FAILED_TO_DOWNLOAD_FILE_4';
					return CCloudStorage::FILE_SKIPPED;
				}
			}
			else
			{
				$ar = CFile::MakeFileArray($arFile["ID"]);
				if (!isset($ar["tmp_name"]))
				{
					self::$file_skip_reason = 'FAILED_TO_GET_SOURCE_FILE_INFO_2';
					return CCloudStorage::FILE_SKIPPED;
				}
			}

			$res = $bucket->SaveFile($filePath, $ar);
			if ($res)
			{
				$bucket->IncFileCounter(filesize($ar["tmp_name"]));

				if ($arFile["HANDLER_ID"])
				{
					self::_delete_file($arFile);
				}
				else
				{
					self::_delete_file($ar["tmp_name"]);
				}

				self::$file_skip_reason = 'FAILED_TO_UPLOAD_FILE';
				return CCloudStorage::FILE_MOVED;
			}
			else
			{        //delete temporary copy
				if ($arFile["HANDLER_ID"])
				{
					self::_delete_file($ar["tmp_name"]);
				}

				return CCloudStorage::FILE_SKIPPED;
			}

		}
	}

	public static function OnFileSave(&$arFile, $strFileName, $strSavePath, $bForceMD5 = false, $bSkipExt = false, $dirAdd = '', $checkDuplicates = true)
	{
		if (!$arFile["tmp_name"] && !array_key_exists("content", $arFile))
			return false;

		if (array_key_exists("bucket", $arFile))
			$bucket = $arFile["bucket"];
		else
			$bucket = CCloudStorage::FindBucketForFile($arFile, $strFileName);

		if (!is_object($bucket))
			return false;

		if (!$bucket->Init())
			return false;

		$original = null;
		$copySize = false;
		$subDir = "";
		$filePath = "";

		if (array_key_exists("bucket", $arFile))
		{
			$newName = bx_basename($arFile["tmp_name"]);

			$prefix = $bucket->GetFileSRC("/");
			$subDir = mb_substr($arFile["tmp_name"], mb_strlen($prefix));
			$subDir = mb_substr($subDir, 0, -mb_strlen($newName) - 1);
		}
		else
		{
			if (array_key_exists("content", $arFile))
			{
				$arFile["tmp_name"] = CTempFile::GetFileName(bx_basename($arFile["name"]));
				CheckDirPath($arFile["tmp_name"]);
				$fp = fopen($arFile["tmp_name"], "ab");
				if ($fp)
				{
					fwrite($fp, $arFile["content"]);
					fclose($fp);
				}
			}

			if (
				$bForceMD5 != true
				&& COption::GetOptionString("main", "save_original_file_name", "N") == "Y"
			)
			{
				if (COption::GetOptionString("main", "convert_original_file_name", "Y") == "Y")
					$newName = CCloudStorage::translit($strFileName);
				else
					$newName = $strFileName;
			}
			else
			{
				$strFileExt = ($bSkipExt == true? '': strrchr($strFileName, "."));
				$newName = md5(uniqid(mt_rand(), true)).$strFileExt;
			}

			//check for double extension vulnerability
			$newName = RemoveScriptExtension($newName);
			$dir_add = $dirAdd;

			if (empty($dir_add))
			{
				while (true)
				{
					$dir_add = md5(mt_rand());
					$dir_add = mb_substr($dir_add, 0, 3)."/".$dir_add;

					$subDir = trim(trim($strSavePath, "/")."/".$dir_add, "/");
					$filePath = "/".$subDir."/".$newName;

					if (!$bucket->FileExists($filePath))
						break;
				}
			}
			else
			{
				$subDir = trim(trim($strSavePath, "/")."/".$dir_add, "/");
				$filePath = "/".$subDir."/".$newName;
			}

			if (!isset($arFile["external_id"]))
			{
				$arFile["external_id"] = md5(mt_rand());
			}

			\Bitrix\Clouds\FileSaveTable::startFileOperation(
				$bucket->ID
				,$subDir
				,$newName
				,$arFile["external_id"]
			);

			$targetPath = $bucket->GetFileSRC("/");
			if (mb_strpos($arFile["tmp_name"], $targetPath) === 0)
			{
				$arDbFile = array(
					"SUBDIR" => "",
					"FILE_NAME" => mb_substr($arFile["tmp_name"], mb_strlen($targetPath)),
					"CONTENT_TYPE" => $arFile["type"],
				);

				//get the file hash
				$arFile["FILE_HASH"] = '';
				if(COption::GetOptionString('main', 'control_file_duplicates', 'N') === 'Y')
				{
					$info = $bucket->GetFileInfo($arDbFile['FILE_NAME']);
					if($info)
					{
						$arFile["FILE_HASH"] = $info["hash"];
						$copySize = $info["size"];
					}
				}

				//control of duplicates
				if($checkDuplicates && $arFile["FILE_HASH"] <> '')
				{
					$original = CFile::FindDuplicate($copySize, $arFile["FILE_HASH"], $bucket->ID);
					if($original !== null)
					{
						$arFile["original_file"] = $original;
					}
				}

				//copy only if the file is not a duplicate
				if($original === null)
				{
					$copyPath = $bucket->FileCopy($arDbFile, $filePath);
					if (!$copyPath)
						return false;

					$copySize = $bucket->GetFileSize("/".urldecode(mb_substr($copyPath, mb_strlen($targetPath))));
				}
			}
			else
			{
				$imgArray = CFile::GetImageSize($arFile["tmp_name"], true, false);
				if (is_array($imgArray) && $imgArray[2] == IMAGETYPE_JPEG)
				{
					$exifData = CFile::ExtractImageExif($arFile["tmp_name"]);
					if ($exifData && isset($exifData['Orientation']))
					{
						$properlyOriented = CFile::ImageHandleOrientation($exifData['Orientation'], $arFile["tmp_name"]);
						if ($properlyOriented)
						{
							$jpgQuality = intval(COption::GetOptionString('main', 'image_resize_quality', '95'));
							if ($jpgQuality <= 0 || $jpgQuality > 100)
								$jpgQuality = 95;

							imagejpeg($properlyOriented, $arFile["tmp_name"], $jpgQuality);
							clearstatcache(true, $arFile["tmp_name"]);
						}
						$arFile['size'] = filesize($arFile["tmp_name"]);
					}
				}

				if (!$bucket->SaveFile($filePath, $arFile))
				{
					return false;
				}

				//get the file hash
				$arFile["FILE_HASH"] = '';
				$size = 0;
				if(COption::GetOptionString('main', 'control_file_duplicates', 'N') === 'Y')
				{
					$info = $bucket->GetFileInfo($filePath);
					if($info)
					{
						$arFile["FILE_HASH"] = $info["hash"];
						$size = $info["size"];
					}
				}

				//control of duplicates
				if($checkDuplicates && $arFile["FILE_HASH"] <> '')
				{
					$original = CFile::FindDuplicate($size, $arFile["FILE_HASH"], $bucket->ID);
					if($original !== null)
					{
						$arFile["original_file"] = $original;

						//we don't need the duplicate anymore
						$bucket->DeleteFile($filePath);
					}
				}
			}
		}

		$arFile["HANDLER_ID"] = $bucket->ID;
		$arFile["WIDTH"] = 0;
		$arFile["HEIGHT"] = 0;

		if($original === null)
		{
			$arFile["SUBDIR"] = $subDir;
			$arFile["FILE_NAME"] = $newName;
		}
		else
		{
			//points to the original's physical path
			$arFile["SUBDIR"] = $original->getFile()->getSubdir();
			$arFile["FILE_NAME"] = $original->getFile()->getFileName();
		}

		if (array_key_exists("bucket", $arFile))
		{
			$arFile["WIDTH"] = $arFile["width"];
			$arFile["HEIGHT"] = $arFile["height"];
			$arFile["size"] = $arFile["file_size"];
		}
		elseif ($copySize !== false)
		{
			$arFile["WIDTH"] = $arFile["width"];
			$arFile["HEIGHT"] = $arFile["height"];
			$arFile["size"] = $copySize;

			//if the file is a duplicate we shouldn't increase the size counter
			if($original === null)
			{
				$bucket->IncFileCounter($copySize);
				\Bitrix\Clouds\FileSaveTable::setFileSize(
					$bucket->ID
					,$subDir
					,$newName
					,$copySize
				);
			}
		}
		else
		{
			//if the file is a duplicate we shouldn't increase the size counter
			if($original === null)
			{
				$fileSize = filesize($arFile["tmp_name"]);
				$bucket->IncFileCounter($fileSize);
				\Bitrix\Clouds\FileSaveTable::setFileSize(
					$bucket->ID
					,$subDir
					,$newName
					,$fileSize
				);
			}

			$flashEnabled = !CFile::IsImage($arFile["ORIGINAL_NAME"], $arFile["type"]);
			$imgArray = CFile::GetImageSize($arFile["tmp_name"], true, $flashEnabled);
			if (is_array($imgArray))
			{
				$arFile["WIDTH"] = $imgArray[0];
				$arFile["HEIGHT"] = $imgArray[1];
			}
		}

		if (isset($arFile["old_file"]))
		{
			CFile::Delete($arFile["old_file"]);
		}

		return true;
	}

	public static function OnAfterFileSave($arFile)
	{
		\Bitrix\Clouds\FileSaveTable::endFileOperation(
			$arFile["HANDLER_ID"]
			,$arFile["SUBDIR"]
			,$arFile["FILE_NAME"]
		);
	}

	public static function CleanUp()
	{
		$buckets = array();
		$date = new \Bitrix\Main\Type\DateTime();
		$date->add("-1D");
		$savedFiles = \Bitrix\Clouds\FileSaveTable::getList(array(
			"filter" => array(
				"<TIMESTAMP_X" => $date,
			),
		));
		while ($saveFile = $savedFiles->fetchObject())
		{
			$dbFile = CFile::GetList(array(), array(
				"EXTERNAL_ID" => $saveFile->getExternalId(),
				"SUBDIR" => $saveFile->getSubdir(),
				"FILE_NAME" => $saveFile->getFileName(),
				"HANDLER_ID" => $saveFile->getBucketId(),
			));
			if ($dbFile->Fetch())
			{
				$saveFile->delete();
			}
			else
			{
				$bucketId = $saveFile->getBucketId();
				if (!isset($buckets[$bucketId]))
				{
					$buckets[$bucketId] = new \CCloudStorageBucket($bucketId);
				}
				$bucket = $buckets[$bucketId];

				if ($bucket->Init())
				{
					$filePath = "/".$saveFile->getSubdir()."/".$saveFile->getFileName();
					if ($bucket->DeleteFile($filePath))
					{
						$fileSize = $saveFile->getFileSize();
						if ($fileSize >= 0)
						{
							$bucket->DecFileCounter($fileSize);
						}
					}
					$saveFile->delete();
				}
			}
		}

		CCloudStorageUpload::CleanUp();

		return "CCloudStorage::CleanUp();";
	}

	public static function FindBucketByFile($file_name)
	{
		foreach (CCloudStorageBucket::GetAllBuckets() as $bucket)
		{
			if ($bucket["ACTIVE"] == "Y")
			{
				$obBucket = new CCloudStorageBucket($bucket["ID"]);
				if ($obBucket->Init())
				{
					$prefix = $obBucket->GetFileSRC("/");
					if (mb_substr($file_name, 0, mb_strlen($prefix)) === $prefix)
						return $obBucket;
				}
			}
		}
		return false;
	}

	public static function FindFileURIByURN($urn, $log_descr = "")
	{
		foreach (CCloudStorageBucket::GetAllBuckets() as $bucket)
		{
			if ($bucket["ACTIVE"] == "Y")
			{
				$obBucket = new CCloudStorageBucket($bucket["ID"]);
				if ($obBucket->Init() && $obBucket->FileExists($urn))
				{
					$uri = $obBucket->GetFileSRC($urn);

					if ($log_descr && COption::GetOptionString("clouds", "log_404_errors") === "Y")
						CEventLog::Log("WARNING", "CLOUDS_404", "clouds", $uri, $log_descr);

					return $uri;
				}
			}
		}
		return "";
	}

	public static function OnBuildGlobalMenu(&$aGlobalMenu, &$aModuleMenu)
	{
		global $USER;
		if (!$USER->CanDoOperation("clouds_browse"))
			return;

		//When UnRegisterModuleDependences is called from module uninstall
		//cached EventHandlers may be called
		if (defined("BX_CLOUDS_UNINSTALLED"))
			return;

		$aMenu = array(
			"parent_menu" => "global_menu_content",
			"section" => "clouds",
			"sort" => 150,
			"text" => GetMessage("CLO_STORAGE_MENU"),
			"title" => GetMessage("CLO_STORAGE_TITLE"),
			"icon" => "clouds_menu_icon",
			"page_icon" => "clouds_page_icon",
			"items_id" => "menu_clouds",
			"items" => array()
		);

		$rsBuckets = CCloudStorageBucket::GetList(array("SORT" => "DESC", "ID" => "ASC"));
		while ($arBucket = $rsBuckets->Fetch())
			$aMenu["items"][] = array(
				"text" => $arBucket["BUCKET"],
				"url" => "clouds_file_list.php?lang=".LANGUAGE_ID."&bucket=".$arBucket["ID"]."&path=/",
				"more_url" => array(
					"clouds_file_list.php?bucket=".$arBucket["ID"],
				),
				"title" => "",
				"page_icon" => "clouds_page_icon",
				"items_id" => "menu_clouds_bucket_".$arBucket["ID"],
				"module_id" => "clouds",
				"items" => array()
			);

		if (!empty($aMenu["items"]))
			$aModuleMenu[] = $aMenu;
	}

	public static function OnAdminListDisplay(&$obList)
	{
		global $USER;

		if ($obList->table_id !== "tbl_fileman_admin")
			return;

		if (!is_object($USER) || !$USER->CanDoOperation("clouds_upload"))
			return;

		static $clouds = null;
		if (!isset($clouds))
		{
			$clouds = array();
			$rsClouds = CCloudStorageBucket::GetList(array("SORT" => "DESC", "ID" => "ASC"));
			while ($arStorage = $rsClouds->Fetch())
			{
				if ($arStorage["READ_ONLY"] == "N" && $arStorage["ACTIVE"] == "Y")
					$clouds[$arStorage["ID"]] = $arStorage["BUCKET"];
			}
		}

		if (empty($clouds))
			return;

		foreach ($obList->aRows as $obRow)
		{
			if ($obRow->arRes["TYPE"] === "F")
			{
				$ID = "F".$obRow->arRes["NAME"];
				$file = $obRow->arRes["NAME"];
				$path = mb_substr($obRow->arRes["ABS_PATH"], 0, -mb_strlen($file));

				$arSubMenu = array();
				foreach ($clouds as $id => $bucket)
					$arSubMenu[] = array(
						"TEXT" => $bucket,
						"ACTION" => $s = "if(confirm('".GetMessage("CLO_STORAGE_UPLOAD_CONF")."')) jsUtils.Redirect([], '".CUtil::AddSlashes("/bitrix/admin/clouds_file_list.php?lang=".LANGUAGE_ID."&bucket=".urlencode($id)."&path=".urlencode($path)."&ID=".urlencode($ID)."&action=upload&".bitrix_sessid_get())."');"
					);

				$obRow->aActions[] = array(
					"TEXT" => GetMessage("CLO_STORAGE_UPLOAD_MENU"),
					"MENU" => $arSubMenu,
				);
			}
		}
	}

	public static function HasActiveBuckets()
	{
		foreach (CCloudStorageBucket::GetAllBuckets() as $bucket)
			if ($bucket["ACTIVE"] === "Y")
				return true;
		return false;
	}

	public static function OnBeforeProlog()
	{
		if (defined("BX_CHECK_SHORT_URI") && BX_CHECK_SHORT_URI)
		{
			$upload_dir = "/".trim(COption::GetOptionString("main", "upload_dir", "upload"), "/")."/";
			$request_uri = urldecode($_SERVER["REQUEST_URI"]);
			$request_uri = CCloudUtil::URLEncode($request_uri, LANG_CHARSET);
			foreach (CCloudStorageBucket::GetAllBuckets() as $arBucket)
			{
				if ($arBucket["ACTIVE"] == "Y")
				{
					$obBucket = new CCloudStorageBucket($arBucket["ID"]);
					if ($obBucket->Init())
					{
						$match = array();
						if (
							COption::GetOptionString("clouds", "delayed_resize") === "Y"
							&& preg_match("#^(/".$obBucket->PREFIX."|)(/resize_cache/.*\$)#", $request_uri, $match)
						)
						{
							session_write_close();
							$to_file = $obBucket->GetFileSRC(urldecode($match[2]));
							if (CCloudStorage::ResizeImageFileCheck($obBucket, $to_file))
							{
								$cache_time = 3600 * 24 * 30; // 30 days
								header("Cache-Control: max-age=".$cache_time);
								header("Expires: ".gmdate("D, d M Y H:i:s", time() + $cache_time)." GMT");
								header_remove("Pragma");
								LocalRedirect($to_file, true, "301 Moved Permanently");
							}
						}
						elseif (
							!preg_match("/[?&]/", $request_uri)
							&& $obBucket->FileExists($request_uri)
						)
						{
							if (COption::GetOptionString("clouds", "log_404_errors") === "Y")
								CEventLog::Log("WARNING", "CLOUDS_404", "clouds", $_SERVER["REQUEST_URI"], $_SERVER["HTTP_REFERER"]);
							LocalRedirect($obBucket->GetFileSRC($request_uri), true);
						}
						elseif (mb_strpos($request_uri, $upload_dir) === 0)
						{
							$check_url = mb_substr($request_uri, mb_strlen($upload_dir) - 1);
							if ($obBucket->FileExists($check_url))
							{
								if (COption::GetOptionString("clouds", "log_404_errors") === "Y")
									CEventLog::Log("WARNING", "CLOUDS_404", "clouds", $_SERVER["REQUEST_URI"], $_SERVER["HTTP_REFERER"]);
								LocalRedirect($obBucket->GetFileSRC($check_url), true);
							}
						}
					}
				}
			}
		}
	}

	public static function GetAuditTypes()
	{
		return array(
			"CLOUDS_404" => "[CLOUDS_404] ".GetMessage("CLO_404_ON_MOVED_FILE"),
		);
	}

	public static function translit($file_name, $safe_chars = '')
	{
		return CUtil::translit($file_name, LANGUAGE_ID, array(
			"safe_chars" => "-. ".$safe_chars,
			"change_case" => false,
			"max_len" => 255,
		));
	}

	/**
	 * @param array [string]string $arFile
	 * @return void
	 */
	public static function FixFileContentType(&$arFile)
	{
		global $DB;
		$fixedContentType = "";

		if ($arFile["CONTENT_TYPE"] === "image/jpg")
			$fixedContentType = "image/jpeg";
		else
		{
			$hexContentType = unpack("H*", $arFile["CONTENT_TYPE"]);
			if (
				$hexContentType[1] === "e0f3e4e8ee2f6d706567"
				|| $hexContentType[1] === "d0b0d183d0b4d0b8d0be2f6d706567"
			)
				$fixedContentType = "audio/mpeg";
		}

		if ($fixedContentType !== "")
		{
			$arFile["CONTENT_TYPE"] = $fixedContentType;
			$DB->Query("
				UPDATE b_file
				SET CONTENT_TYPE = '".$DB->ForSQL($fixedContentType)."'
				WHERE ID = ".intval($arFile["ID"])."
			");
			CFile::CleanCache($arFile["ID"]);
		}
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit