Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/clouds/classes/general/ |
Current File : /var/www/www-root/data/www/monolith-realty.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 = ''; protected static $lockId = ''; /** * @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, false); } if (defined("BX_MOBILE") && constant("BX_MOBILE") === true) $bImmediate = true; else $bImmediate = $arResizeParams[5]; $callbackData['bImmediate'] = $bImmediate; $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 = $obTargetBucket->GetFileSRC($callbackData["fileURL"], false); $arDestinationSize = array(); //Check if it is cache file was deleted, but there was a successful resize $delayInfo = $bImmediate ? false : CCloudStorage::ResizeImageFileGet($cacheImageFile); if (is_array($delayInfo) && ($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"], "size" => null, ); $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 (!$arFileToStore) { $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, false); } return false; } if (!preg_match("/^image\\//", $arFileToStore["type"])) $arFileToStore["type"] = $arFile["CONTENT_TYPE"]; if ($obTargetBucket->SaveFile($callbackData["fileURL"], $arFileToStore)) { $cacheImageFile = $obTargetBucket->GetFileSRC($callbackData["fileURL"], false); $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 ); } } 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, false); } 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"], false); $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; } } elseif (is_array($callbackData["cacheVARS"])) { $cacheImageFile = $callbackData["cacheVARS"]["cacheImageFile"]; $arImageSize = array( $callbackData["cacheVARS"]["width"], $callbackData["cacheVARS"]["height"], $callbackData["cacheVARS"]["size"], ); $arCloudImageSizeCache[$cacheImageFile] = $arImageSize; } else { return false; } $delayedResize = $callbackData['bImmediate'] ? false : COption::GetOptionString("clouds", "delayed_resize") === "Y"; foreach (GetModuleEvents("clouds", "OnAfterResizeImage", true) as $arEvent) { $cacheImageFileBefore = $cacheImageFile; ExecuteModuleEventEx($arEvent, [$delayedResize, &$cacheImageFile]); if ($cacheImageFile !== $cacheImageFileBefore && $cacheImageFile) { $arCloudImageSizeCache[$cacheImageFile] = $arCloudImageSizeCache[$cacheImageFileBefore]; } } return true; } public static function ResizeImageFileGet($destinationFile) { global $DB; $destinationFile = preg_replace("/^https?:/i", "", $destinationFile); $destinationFile = CCloudUtil::URLEncode($destinationFile, "UTF-8", true); $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); $destinationFile = CCloudUtil::URLEncode($destinationFile, "UTF-8", true); $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" => CCloudUtil::URLEncode($sourceFile["SRC"], "UTF-8", true), "TO_PATH" => $destinationFile, "FILE_ID" => $sourceFile["ID"], )); } } public static function ResizeImageFileDelay(&$arDestinationSize, $sourceFile, $destinationFile, $arResizeParams) { global $DB; $destinationFile = preg_replace("/^https?:/i", "", $destinationFile); $destinationFile = CCloudUtil::URLEncode($destinationFile, "UTF-8", true); $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" => CCloudUtil::URLEncode($sourceFile["SRC"], "UTF-8", true), "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; $io = CBXVirtualIo::GetInstance(); $path = preg_replace("/^https?:/i", "", $path); $path = CCloudUtil::URLEncode($path, "UTF-8", true); $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"])) // { // $tmpFile = CFile::MakeFileArray(\Bitrix\Main\Web\Uri::urnEncode($task["FROM_PATH"], "UTF-8")); // } 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]; $from_path = $io->GetLogicalName($tmpFile["tmp_name"]); $to_path = \Bitrix\Main\Text\Encoding::convertEncoding(rawurldecode($task["TO_PATH"]), "UTF-8", LANG_CHARSET); $to_path = CFile::GetTempName('', bx_basename($to_path)); if (!CFile::ResizeImageFile($from_path, $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($io->GetPhysicalName($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); $pathToStore = \Bitrix\Main\Text\Encoding::convertEncoding(rawurldecode($pathToStore), "UTF-8", LANG_CHARSET); if (!$obBucket->SaveFile($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("/^https?:\\/\\//", $file)) return false; $bucket = CCloudStorage::FindBucketByFile($file); if (!is_object($bucket)) return false; $filePath = mb_substr($file, mb_strlen($bucket->GetFileSRC("/")) - 1); $filePath = \Bitrix\Main\Text\Encoding::convertEncoding(rawurldecode($filePath), "UTF-8", LANG_CHARSET); $io = CBXVirtualIo::GetInstance(); $target = CFile::GetTempName('', bx_basename($filePath)); $target = preg_replace("#[\\\\\\/]+#", "/", $target); if ($bucket->DownloadToFile($filePath, $target)) { $arDestination = $io->GetPhysicalName($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); \Bitrix\Clouds\FileHashTable::deleteByFilePath($bucket->ID, "/".$arFile["SUBDIR"]."/".$arFile["FILE_NAME"]); 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, false); } 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 = '') { 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 ($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; if ($copySize === false) { $info = $bucket->GetFileInfo('/' . urldecode(mb_substr($copyPath, mb_strlen($targetPath)))); if ($info) { $copySize = $info["size"]; } else { return false; } } } } else { 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 ($arFile["FILE_HASH"] <> '') { if (is_callable(['CFile', 'lockFileHash'])) { static::$lockId = CFile::lockFileHash($size, $arFile["FILE_HASH"], $bucket->ID); } $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"] ); if (static::$lockId) { CFile::unlockFileHash(static::$lockId); static::$lockId = ''; } } public static function OnAfterFileDeleteDuplicate($original, $duplicate) { $result = false; if ($original->getHandlerId() > 0) { $bucket = new CCloudStorageBucket($original->getHandlerId()); if ($bucket->Init()) { $duplicatePath = '/' . $duplicate->getSubdir() . '/' . $duplicate->getFileName(); \Bitrix\Clouds\FileHashTable::deleteByFilePath($original->getHandlerId(), $duplicatePath); $result = $bucket->deleteFile($duplicatePath, $duplicate->getFileSize()); if ($result) { $bucket->decFileCounter($duplicate->getFileSize()); } } } return $result; } 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, ), "limit" => 100, // ~10 sec )); 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 = \Bitrix\Main\Text\Encoding::convertEncoding(rawurldecode($_SERVER["REQUEST_URI"]), "UTF-8", LANG_CHARSET); foreach (CCloudStorageBucket::GetAllBuckets() as $arBucket) { if ($arBucket["ACTIVE"] == "Y") { $obBucket = new CCloudStorageBucket($arBucket["ID"]); if ($obBucket->Init()) { $bucketUrl = $obBucket->GetFileSRC('/'); $bucketPrefix = rtrim(parse_url($bucketUrl, PHP_URL_PATH), '/'); $prefixMatch = $bucketPrefix ? "(?:$bucketPrefix|)" : ""; $match = array(); if ( COption::GetOptionString("clouds", "delayed_resize") === "Y" && preg_match("#^$prefixMatch(/resize_cache/.*\$)#", $request_uri, $match) ) { session_write_close(); $to_file = $obBucket->GetFileSRC($match[1], false); 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(\Bitrix\Main\Web\Uri::urnEncode($to_file, "UTF-8"), 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"]); } } }