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());
}
BitrixCloudsFileSaveTable::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
{
$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 ($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);
BitrixCloudsFileSaveTable::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);
BitrixCloudsFileSaveTable::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;
}