Created
October 25, 2019 13:36
-
-
Save madcatgith/b3491cd99e37c6e2e653b0a22f43de91 to your computer and use it in GitHub Desktop.
Фикс для CFile::ResizeImageGet на OPEN SERVER
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php/* | |
| При неработающем ресайзе картинок на OpenServer (локальных проектах) закоментировать hLock в функции ResizeImageFile | |
| Строка: 2176-2196 | |
| \bitrix\modules\main\classes\general\file.php | |
| */ | |
| /** | |
| * Bitrix Framework | |
| * @package bitrix | |
| * @subpackage main | |
| * @copyright 2001-2013 Bitrix | |
| */ | |
| use Bitrix\Main\IO; | |
| use Bitrix\Main\UI\Viewer; | |
| IncludeModuleLangFile(__FILE__); | |
| class CAllFile | |
| { | |
| protected static $enableTrackingResizeImage = false; | |
| public static function SaveForDB(&$arFields, $field, $strSavePath) | |
| { | |
| $arFile = $arFields[$field]; | |
| if(isset($arFile) && is_array($arFile)) | |
| { | |
| if($arFile["name"] <> '' || $arFile["del"] <> '' || array_key_exists("description", $arFile)) | |
| { | |
| $res = CFile::SaveFile($arFile, $strSavePath); | |
| if($res !== false) | |
| { | |
| $arFields[$field] = (intval($res) > 0? $res : false); | |
| return true; | |
| } | |
| } | |
| } | |
| unset($arFields[$field]); | |
| return false; | |
| } | |
| public static function checkForDb($arFields, $field) | |
| { | |
| if(isset($arFields[$field]) && is_array($arFields[$field])) | |
| { | |
| $arFile = $arFields[$field]; | |
| if($arFile["name"] == "") | |
| { | |
| return ""; | |
| } | |
| $fileName = self::transformName($arFile["name"]); | |
| return self::validateFile($fileName, $arFile); | |
| } | |
| else | |
| { | |
| return ""; | |
| } | |
| } | |
| protected static function transformName($name, $bForceMD5 = false, $bSkipExt = false) | |
| { | |
| //safe filename without path | |
| $fileName = GetFileName($name); | |
| $originalName = ($bForceMD5 != true && COption::GetOptionString("main", "save_original_file_name", "N") == "Y"); | |
| if($originalName) | |
| { | |
| //transforming original name: | |
| //transliteration | |
| if(COption::GetOptionString("main", "translit_original_file_name", "N") == "Y") | |
| { | |
| $fileName = CUtil::translit($fileName, LANGUAGE_ID, array( | |
| "max_len" => 1024, | |
| "safe_chars" => ".", | |
| "replace_space" => '-', | |
| "change_case" => false, | |
| )); | |
| } | |
| //replace invalid characters | |
| if(COption::GetOptionString("main", "convert_original_file_name", "Y") == "Y") | |
| { | |
| $io = CBXVirtualIo::GetInstance(); | |
| $fileName = $io->RandomizeInvalidFilename($fileName); | |
| } | |
| } | |
| //.jpe is not image type on many systems | |
| if($bSkipExt == false && strtolower(GetFileExtension($fileName)) == "jpe") | |
| { | |
| $fileName = substr($fileName, 0, -4).".jpg"; | |
| } | |
| //double extension vulnerability | |
| $fileName = RemoveScriptExtension($fileName); | |
| if(!$originalName) | |
| { | |
| //name is md5-generated: | |
| $fileName = md5(uniqid("", true)).($bSkipExt == true || ($ext = GetFileExtension($fileName)) == ''? '' : ".".$ext); | |
| } | |
| return $fileName; | |
| } | |
| protected static function validateFile($strFileName, $arFile) | |
| { | |
| if($strFileName == '') | |
| return GetMessage("FILE_BAD_FILENAME"); | |
| $io = CBXVirtualIo::GetInstance(); | |
| if(!$io->ValidateFilenameString($strFileName)) | |
| return GetMessage("MAIN_BAD_FILENAME1"); | |
| if(strlen($strFileName) > 255) | |
| return GetMessage("MAIN_BAD_FILENAME_LEN"); | |
| //check .htaccess etc. | |
| if(IsFileUnsafe($strFileName)) | |
| return GetMessage("FILE_BAD_TYPE"); | |
| //nginx returns octet-stream for .jpg | |
| if(GetFileNameWithoutExtension($strFileName) == '') | |
| return GetMessage("FILE_BAD_FILENAME"); | |
| if (COption::GetOptionInt("main", "disk_space") > 0) | |
| { | |
| $quota = new CDiskQuota(); | |
| if (!$quota->checkDiskQuota($arFile)) | |
| return GetMessage("FILE_BAD_QUOTA"); | |
| } | |
| return ""; | |
| } | |
| public static function SaveFile($arFile, $strSavePath, $bForceMD5=false, $bSkipExt=false, $dirAdd='') | |
| { | |
| $strFileName = GetFileName($arFile["name"]); /* filename.gif */ | |
| if(isset($arFile["del"]) && $arFile["del"] <> '') | |
| { | |
| CFile::DoDelete($arFile["old_file"]); | |
| if($strFileName == '') | |
| return "NULL"; | |
| } | |
| if($arFile["name"] == '') | |
| { | |
| if(isset($arFile["description"]) && intval($arFile["old_file"])>0) | |
| { | |
| CFile::UpdateDesc($arFile["old_file"], $arFile["description"]); | |
| } | |
| return false; | |
| } | |
| if (isset($arFile["content"])) | |
| { | |
| if (!isset($arFile["size"])) | |
| { | |
| $arFile["size"] = CUtil::BinStrlen($arFile["content"]); | |
| } | |
| } | |
| else | |
| { | |
| try | |
| { | |
| $file = new IO\File(IO\Path::convertPhysicalToLogical($arFile["tmp_name"])); | |
| $arFile["size"] = $file->getSize(); | |
| } | |
| catch(IO\IoException $e) | |
| { | |
| $arFile["size"] = 0; | |
| } | |
| } | |
| $arFile["ORIGINAL_NAME"] = $strFileName; | |
| //translit, replace unsafe chars, etc. | |
| $strFileName = self::transformName($strFileName, $bForceMD5, $bSkipExt); | |
| //transformed name must be valid, check disk quota, etc. | |
| if (self::validateFile($strFileName, $arFile) !== "") | |
| { | |
| return false; | |
| } | |
| if($arFile["type"] == "image/pjpeg" || $arFile["type"] == "image/jpg") | |
| { | |
| $arFile["type"] = "image/jpeg"; | |
| } | |
| $bExternalStorage = false; | |
| foreach(GetModuleEvents("main", "OnFileSave", true) as $arEvent) | |
| { | |
| if(ExecuteModuleEventEx($arEvent, array(&$arFile, $strFileName, $strSavePath, $bForceMD5, $bSkipExt, $dirAdd))) | |
| { | |
| $bExternalStorage = true; | |
| break; | |
| } | |
| } | |
| if(!$bExternalStorage) | |
| { | |
| $upload_dir = COption::GetOptionString("main", "upload_dir", "upload"); | |
| $io = CBXVirtualIo::GetInstance(); | |
| if($bForceMD5 != true && COption::GetOptionString("main", "save_original_file_name", "N") == "Y") | |
| { | |
| $dir_add = $dirAdd; | |
| if($dir_add == '') | |
| { | |
| $i = 0; | |
| while(true) | |
| { | |
| $dir_add = substr(md5(uniqid("", true)), 0, 3); | |
| if(!$io->FileExists($_SERVER["DOCUMENT_ROOT"]."/".$upload_dir."/".$strSavePath."/".$dir_add."/".$strFileName)) | |
| { | |
| break; | |
| } | |
| if($i >= 25) | |
| { | |
| $j = 0; | |
| while(true) | |
| { | |
| $dir_add = substr(md5(mt_rand()), 0, 3)."/".substr(md5(mt_rand()), 0, 3); | |
| if(!$io->FileExists($_SERVER["DOCUMENT_ROOT"]."/".$upload_dir."/".$strSavePath."/".$dir_add."/".$strFileName)) | |
| { | |
| break; | |
| } | |
| if($j >= 25) | |
| { | |
| $dir_add = substr(md5(mt_rand()), 0, 3)."/".md5(mt_rand()); | |
| break; | |
| } | |
| $j++; | |
| } | |
| break; | |
| } | |
| $i++; | |
| } | |
| } | |
| if(substr($strSavePath, -1, 1) <> "/") | |
| { | |
| $strSavePath .= "/".$dir_add; | |
| } | |
| else | |
| { | |
| $strSavePath .= $dir_add."/"; | |
| } | |
| } | |
| else | |
| { | |
| $strFileExt = ($bSkipExt == true || ($ext = GetFileExtension($strFileName)) == ''? '' : ".".$ext); | |
| while(true) | |
| { | |
| if(substr($strSavePath, -1, 1) <> "/") | |
| { | |
| $strSavePath .= "/".substr($strFileName, 0, 3); | |
| } | |
| else | |
| { | |
| $strSavePath .= substr($strFileName, 0, 3)."/"; | |
| } | |
| if(!$io->FileExists($_SERVER["DOCUMENT_ROOT"]."/".$upload_dir."/".$strSavePath."/".$strFileName)) | |
| break; | |
| //try the new name | |
| $strFileName = md5(uniqid("", true)).$strFileExt; | |
| } | |
| } | |
| $arFile["SUBDIR"] = $strSavePath; | |
| $arFile["FILE_NAME"] = $strFileName; | |
| $strDirName = $_SERVER["DOCUMENT_ROOT"]."/".$upload_dir."/".$strSavePath."/"; | |
| $strDbFileNameX = $strDirName.$strFileName; | |
| $strPhysicalFileNameX = $io->GetPhysicalName($strDbFileNameX); | |
| CheckDirPath($strDirName); | |
| if(is_set($arFile, "content")) | |
| { | |
| $f = fopen($strPhysicalFileNameX, "w"); | |
| if(!$f) | |
| return false; | |
| if(fwrite($f, $arFile["content"]) === false) | |
| return false; | |
| fclose($f); | |
| } | |
| elseif( | |
| !copy($arFile["tmp_name"], $strPhysicalFileNameX) | |
| && !move_uploaded_file($arFile["tmp_name"], $strPhysicalFileNameX) | |
| ) | |
| { | |
| CFile::DoDelete($arFile["old_file"]); | |
| return false; | |
| } | |
| if(isset($arFile["old_file"])) | |
| CFile::DoDelete($arFile["old_file"]); | |
| @chmod($strPhysicalFileNameX, BX_FILE_PERMISSIONS); | |
| //flash is not an image | |
| $flashEnabled = !CFile::IsImage($arFile["ORIGINAL_NAME"], $arFile["type"]); | |
| $imgArray = CFile::GetImageSize($strDbFileNameX, false, $flashEnabled); | |
| if(is_array($imgArray)) | |
| { | |
| $arFile["WIDTH"] = $imgArray[0]; | |
| $arFile["HEIGHT"] = $imgArray[1]; | |
| if($imgArray[2] == IMAGETYPE_JPEG) | |
| { | |
| $exifData = CFile::ExtractImageExif($strPhysicalFileNameX); | |
| if ($exifData && isset($exifData['Orientation'])) | |
| { | |
| //swap width and height | |
| if ($exifData['Orientation'] >= 5 && $exifData['Orientation'] <= 8) | |
| { | |
| $arFile["WIDTH"] = $imgArray[1]; | |
| $arFile["HEIGHT"] = $imgArray[0]; | |
| } | |
| $properlyOriented = CFile::ImageHandleOrientation($exifData['Orientation'], $io->GetPhysicalName($strDbFileNameX)); | |
| if ($properlyOriented) | |
| { | |
| $jpgQuality = intval(COption::GetOptionString('main', 'image_resize_quality', '95')); | |
| if($jpgQuality <= 0 || $jpgQuality > 100) | |
| $jpgQuality = 95; | |
| imagejpeg($properlyOriented, $strPhysicalFileNameX, $jpgQuality); | |
| clearstatcache(true, $strPhysicalFileNameX); | |
| } | |
| $arFile['size'] = filesize($strPhysicalFileNameX); | |
| } | |
| } | |
| } | |
| else | |
| { | |
| $arFile["WIDTH"] = 0; | |
| $arFile["HEIGHT"] = 0; | |
| } | |
| } | |
| if($arFile["WIDTH"] == 0 || $arFile["HEIGHT"] == 0) | |
| { | |
| //mock image because we got false from CFile::GetImageSize() | |
| if(strpos($arFile["type"], "image/") === 0 && $arFile["type"] <> 'image/svg+xml') | |
| { | |
| $arFile["type"] = "application/octet-stream"; | |
| } | |
| } | |
| if($arFile["type"] == '' || !is_string($arFile["type"])) | |
| { | |
| $arFile["type"] = "application/octet-stream"; | |
| } | |
| /****************************** QUOTA ******************************/ | |
| if (COption::GetOptionInt("main", "disk_space") > 0) | |
| { | |
| CDiskQuota::updateDiskQuota("file", $arFile["size"], "insert"); | |
| } | |
| /****************************** QUOTA ******************************/ | |
| $NEW_IMAGE_ID = CFile::DoInsert(array( | |
| "HEIGHT" => $arFile["HEIGHT"], | |
| "WIDTH" => $arFile["WIDTH"], | |
| "FILE_SIZE" => $arFile["size"], | |
| "CONTENT_TYPE" => $arFile["type"], | |
| "SUBDIR" => $arFile["SUBDIR"], | |
| "FILE_NAME" => $arFile["FILE_NAME"], | |
| "MODULE_ID" => $arFile["MODULE_ID"], | |
| "ORIGINAL_NAME" => $arFile["ORIGINAL_NAME"], | |
| "DESCRIPTION" => isset($arFile["description"])? $arFile["description"]: '', | |
| "HANDLER_ID" => isset($arFile["HANDLER_ID"])? $arFile["HANDLER_ID"]: '', | |
| "EXTERNAL_ID" => isset($arFile["external_id"])? $arFile["external_id"]: md5(mt_rand()), | |
| )); | |
| CFile::CleanCache($NEW_IMAGE_ID); | |
| return $NEW_IMAGE_ID; | |
| } | |
| public static function DoInsert($arFields) | |
| { | |
| global $DB; | |
| $strSql = | |
| "INSERT INTO b_file( | |
| HEIGHT, | |
| WIDTH, | |
| FILE_SIZE, | |
| CONTENT_TYPE, | |
| SUBDIR, | |
| FILE_NAME, | |
| MODULE_ID, | |
| ORIGINAL_NAME, | |
| DESCRIPTION, | |
| HANDLER_ID, | |
| EXTERNAL_ID, | |
| TIMESTAMP_X | |
| ) VALUES ( | |
| ".intval($arFields["HEIGHT"]).", | |
| ".intval($arFields["WIDTH"]).", | |
| ".round(floatval($arFields["FILE_SIZE"])).", | |
| '".$DB->ForSql($arFields["CONTENT_TYPE"], 255)."', | |
| '".$DB->ForSql($arFields["SUBDIR"], 255)."', | |
| '".$DB->ForSQL($arFields["FILE_NAME"], 255)."', | |
| '".$DB->ForSQL($arFields["MODULE_ID"], 50)."', | |
| '".$DB->ForSql($arFields["ORIGINAL_NAME"], 255)."', | |
| '".$DB->ForSQL($arFields["DESCRIPTION"], 255)."', | |
| ".($arFields["HANDLER_ID"]? "'".$DB->ForSql($arFields["HANDLER_ID"], 50)."'": "null").", | |
| ".($arFields["EXTERNAL_ID"] != ""? "'".$DB->ForSql($arFields["EXTERNAL_ID"], 50)."'": "null").", | |
| ".$DB->GetNowFunction()." | |
| )"; | |
| $DB->Query($strSql); | |
| return $DB->LastID(); | |
| } | |
| public static function CleanCache($ID) | |
| { | |
| if (CACHED_b_file!==false) | |
| { | |
| $bucket_size = intval(CACHED_b_file_bucket_size); | |
| if ($bucket_size <= 0) | |
| $bucket_size = 10; | |
| $bucket = intval($ID/$bucket_size); | |
| $cache = Bitrix\Main\Application::getInstance()->getManagedCache(); | |
| $cache->clean("b_file0".$bucket, "b_file"); | |
| $cache->clean("b_file1".$bucket, "b_file"); | |
| } | |
| } | |
| public static function GetFromCache($FILE_ID) | |
| { | |
| global $DB; | |
| $cache = Bitrix\Main\Application::getInstance()->getManagedCache(); | |
| $bucket_size = intval(CACHED_b_file_bucket_size); | |
| if($bucket_size <= 0) | |
| $bucket_size = 10; | |
| $bucket = intval($FILE_ID/$bucket_size); | |
| $cache_id = "b_file".intval(CMain::IsHTTPS()).$bucket; | |
| if($cache->read(CACHED_b_file, $cache_id, "b_file")) | |
| { | |
| $arFiles = $cache->get($cache_id); | |
| } | |
| else | |
| { | |
| $arFiles = array(); | |
| $rs = $DB->Query(" | |
| SELECT f.*,".$DB->DateToCharFunction("f.TIMESTAMP_X")." as TIMESTAMP_X FROM b_file f | |
| WHERE f.ID between ".($bucket*$bucket_size)." AND ".(($bucket+1)*$bucket_size-1) | |
| ); | |
| while($ar = $rs->Fetch()) | |
| { | |
| $ar["~src"] = ''; | |
| foreach(GetModuleEvents("main", "OnGetFileSRC", true) as $arEvent) | |
| { | |
| $ar["~src"] = ExecuteModuleEventEx($arEvent, array($ar)); | |
| if($ar["~src"]) | |
| break; | |
| } | |
| $arFiles[$ar["ID"]] = $ar; | |
| } | |
| $cache->setImmediate($cache_id, $arFiles); | |
| } | |
| return $arFiles; | |
| } | |
| public static function GetByID($FILE_ID) | |
| { | |
| global $DB; | |
| $FILE_ID = intval($FILE_ID); | |
| if(CACHED_b_file===false) | |
| { | |
| $strSql = "SELECT f.*,".$DB->DateToCharFunction("f.TIMESTAMP_X")." as TIMESTAMP_X FROM b_file f WHERE f.ID=".$FILE_ID; | |
| $z = $DB->Query($strSql, false, "FILE: ".__FILE__."<br>LINE: ".__LINE__); | |
| } | |
| else | |
| { | |
| $arFiles = CFile::GetFromCache($FILE_ID); | |
| $z = new CDBResult; | |
| $z->InitFromArray(array_key_exists($FILE_ID, $arFiles)? array($arFiles[$FILE_ID]) : array()); | |
| } | |
| return $z; | |
| } | |
| public static function GetList($arOrder = array(), $arFilter = array()) | |
| { | |
| global $DB; | |
| $arSqlSearch = array(); | |
| $arSqlOrder = array(); | |
| $strSqlSearch = $strSqlOrder = ""; | |
| if(is_array($arFilter)) | |
| { | |
| foreach($arFilter as $key => $val) | |
| { | |
| $key = strtoupper($key); | |
| $strOperation = ''; | |
| if(substr($key, 0, 1)=="@") | |
| { | |
| $key = substr($key, 1); | |
| $strOperation = "IN"; | |
| $arIn = is_array($val)? $val: explode(',', $val); | |
| $val = ''; | |
| foreach($arIn as $v) | |
| { | |
| $val .= ($val <> ''? ',':'')."'".$DB->ForSql(trim($v))."'"; | |
| } | |
| } | |
| else | |
| { | |
| $val = $DB->ForSql($val); | |
| } | |
| if($val == '') | |
| continue; | |
| switch($key) | |
| { | |
| case "MODULE_ID": | |
| case "ID": | |
| case "EXTERNAL_ID": | |
| case "SUBDIR": | |
| case "FILE_NAME": | |
| case "ORIGINAL_NAME": | |
| case "CONTENT_TYPE": | |
| if ($strOperation == "IN") | |
| $arSqlSearch[] = "f.".$key." IN (".$val.")"; | |
| else | |
| $arSqlSearch[] = "f.".$key." = '".$val."'"; | |
| break; | |
| } | |
| } | |
| } | |
| if(!empty($arSqlSearch)) | |
| $strSqlSearch = " WHERE (".implode(") AND (", $arSqlSearch).")"; | |
| if(is_array($arOrder)) | |
| { | |
| static $aCols = array( | |
| "ID" => 1, | |
| "TIMESTAMP_X" => 1, | |
| "MODULE_ID" => 1, | |
| "HEIGHT" => 1, | |
| "WIDTH" => 1, | |
| "FILE_SIZE" => 1, | |
| "CONTENT_TYPE" => 1, | |
| "SUBDIR" => 1, | |
| "FILE_NAME" => 1, | |
| "ORIGINAL_NAME" => 1, | |
| "EXTERNAL_ID" => 1, | |
| ); | |
| foreach($arOrder as $by => $ord) | |
| { | |
| $by = strtoupper($by); | |
| if(array_key_exists($by, $aCols)) | |
| $arSqlOrder[] = "f.".$by." ".(strtoupper($ord) == "DESC"? "DESC":"ASC"); | |
| } | |
| } | |
| if(empty($arSqlOrder)) | |
| $arSqlOrder[] = "f.ID ASC"; | |
| $strSqlOrder = " ORDER BY ".implode(", ", $arSqlOrder); | |
| $strSql = | |
| "SELECT f.*, ".$DB->DateToCharFunction("f.TIMESTAMP_X")." as TIMESTAMP_X ". | |
| "FROM b_file f ". | |
| $strSqlSearch. | |
| $strSqlOrder; | |
| $res = $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__); | |
| return $res; | |
| } | |
| public static function GetFileSRC($arFile, $upload_dir = false, $external = true) | |
| { | |
| $src = ''; | |
| if($external) | |
| { | |
| foreach(GetModuleEvents("main", "OnGetFileSRC", true) as $arEvent) | |
| { | |
| $src = ExecuteModuleEventEx($arEvent, array($arFile)); | |
| if($src) | |
| break; | |
| } | |
| } | |
| if(!$src) | |
| { | |
| if($upload_dir === false) | |
| $upload_dir = COption::GetOptionString("main", "upload_dir", "upload"); | |
| $src = "/".$upload_dir."/".$arFile["SUBDIR"]."/".$arFile["FILE_NAME"]; | |
| $src = str_replace("//", "/", $src); | |
| if(defined("BX_IMG_SERVER")) | |
| $src = BX_IMG_SERVER.$src; | |
| } | |
| return $src; | |
| } | |
| public static function GetFileArray($FILE_ID, $upload_dir = false) | |
| { | |
| if(!is_array($FILE_ID) && intval($FILE_ID) > 0) | |
| { | |
| if(CACHED_b_file===false) | |
| { | |
| $res = CFile::GetByID($FILE_ID, true); | |
| $arFile = $res->Fetch(); | |
| } | |
| else | |
| { | |
| $res = CFile::GetFromCache($FILE_ID); | |
| $arFile = $res[$FILE_ID]; | |
| } | |
| if($arFile) | |
| { | |
| if(array_key_exists("~src", $arFile)) | |
| { | |
| if($arFile["~src"]) | |
| $arFile["SRC"] = $arFile["~src"]; | |
| else | |
| $arFile["SRC"] = CFile::GetFileSRC($arFile, $upload_dir, false/*It is known file is local*/); | |
| } | |
| else | |
| { | |
| $arFile["SRC"] = CFile::GetFileSRC($arFile, $upload_dir); | |
| } | |
| return $arFile; | |
| } | |
| } | |
| return false; | |
| } | |
| public static function ConvertFilesToPost($source, &$target, $field=false) | |
| { | |
| if($field === false) | |
| { | |
| foreach($source as $field => $sub_source) | |
| { | |
| CAllFile::ConvertFilesToPost($sub_source, $target, $field); | |
| } | |
| } | |
| else | |
| { | |
| foreach($source as $id => $sub_source) | |
| { | |
| if(!array_key_exists($id, $target)) | |
| $target[$id] = array(); | |
| if(is_array($sub_source)) | |
| CAllFile::ConvertFilesToPost($sub_source, $target[$id], $field); | |
| else | |
| $target[$id][$field] = $sub_source; | |
| } | |
| } | |
| } | |
| public static function CopyFile($FILE_ID, $bRegister = true, $newPath = "") | |
| { | |
| global $DB; | |
| $err_mess = "FILE: ".__FILE__."<br>LINE: "; | |
| $z = CFile::GetByID($FILE_ID); | |
| if($zr = $z->Fetch()) | |
| { | |
| /****************************** QUOTA ******************************/ | |
| if (COption::GetOptionInt("main", "disk_space") > 0) | |
| { | |
| $quota = new CDiskQuota(); | |
| if (!$quota->checkDiskQuota($zr)) | |
| return false; | |
| } | |
| /****************************** QUOTA ******************************/ | |
| $strNewFile = ''; | |
| $bSaved = false; | |
| $bExternalStorage = false; | |
| foreach(GetModuleEvents("main", "OnFileCopy", true) as $arEvent) | |
| { | |
| if($bSaved = ExecuteModuleEventEx($arEvent, array(&$zr, $newPath))) | |
| { | |
| $bExternalStorage = true; | |
| break; | |
| } | |
| } | |
| $io = CBXVirtualIo::GetInstance(); | |
| if(!$bExternalStorage) | |
| { | |
| $strDirName = $_SERVER["DOCUMENT_ROOT"]."/".(COption::GetOptionString("main", "upload_dir", "upload")); | |
| $strDirName = rtrim(str_replace("//","/",$strDirName), "/"); | |
| $zr["SUBDIR"] = trim($zr["SUBDIR"], "/"); | |
| $zr["FILE_NAME"] = ltrim($zr["FILE_NAME"], "/"); | |
| $strOldFile = $strDirName."/".$zr["SUBDIR"]."/".$zr["FILE_NAME"]; | |
| if(strlen($newPath)) | |
| $strNewFile = $strDirName."/".ltrim($newPath, "/"); | |
| else | |
| $strNewFile = $strDirName."/".$zr["SUBDIR"]."/".md5(uniqid(mt_rand())).strrchr($zr["FILE_NAME"], "."); | |
| $zr["FILE_NAME"] = bx_basename($strNewFile); | |
| $zr["SUBDIR"] = substr($strNewFile, strlen($strDirName)+1, -(strlen(bx_basename($strNewFile)) + 1)); | |
| if(strlen($newPath)) | |
| CheckDirPath($strNewFile); | |
| $bSaved = copy($io->GetPhysicalName($strOldFile), $io->GetPhysicalName($strNewFile)); | |
| } | |
| if($bSaved) | |
| { | |
| if($bRegister) | |
| { | |
| $arFields = array( | |
| "TIMESTAMP_X" => $DB->GetNowFunction(), | |
| "MODULE_ID" => "'".$DB->ForSql($zr["MODULE_ID"], 50)."'", | |
| "HEIGHT" => intval($zr["HEIGHT"]), | |
| "WIDTH" => intval($zr["WIDTH"]), | |
| "FILE_SIZE" => intval($zr["FILE_SIZE"]), | |
| "ORIGINAL_NAME" => "'".$DB->ForSql($zr["ORIGINAL_NAME"], 255)."'", | |
| "DESCRIPTION" => "'".$DB->ForSql($zr["DESCRIPTION"], 255)."'", | |
| "CONTENT_TYPE" => "'".$DB->ForSql($zr["CONTENT_TYPE"], 255)."'", | |
| "SUBDIR" => "'".$DB->ForSql($zr["SUBDIR"], 255)."'", | |
| "FILE_NAME" => "'".$DB->ForSql($zr["FILE_NAME"], 255)."'", | |
| "HANDLER_ID" => $zr["HANDLER_ID"]? intval($zr["HANDLER_ID"]): "null", | |
| "EXTERNAL_ID" => $zr["EXTERNAL_ID"] != ""? "'".$DB->ForSql($zr["EXTERNAL_ID"], 50)."'": "null", | |
| ); | |
| $NEW_FILE_ID = $DB->Insert("b_file",$arFields, $err_mess.__LINE__); | |
| if (COption::GetOptionInt("main", "disk_space") > 0) | |
| CDiskQuota::updateDiskQuota("file", $zr["FILE_SIZE"], "copy"); | |
| CFile::CleanCache($NEW_FILE_ID); | |
| return $NEW_FILE_ID; | |
| } | |
| else | |
| { | |
| if(!$bExternalStorage) | |
| return substr($strNewFile, strlen(rtrim($_SERVER["DOCUMENT_ROOT"], "/"))); | |
| else | |
| return $bSaved; | |
| } | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| } | |
| return 0; | |
| } | |
| public static function UpdateDesc($ID, $desc) | |
| { | |
| global $DB; | |
| $DB->Query( | |
| "UPDATE b_file SET | |
| DESCRIPTION = '".$DB->ForSql($desc, 255)."', | |
| TIMESTAMP_X = ".$DB->GetNowFunction()." | |
| WHERE ID=".intval($ID) | |
| ); | |
| CFile::CleanCache($ID); | |
| } | |
| public static function UpdateExternalId($ID, $external_id) | |
| { | |
| global $DB; | |
| $external_id = trim($external_id); | |
| $DB->Query( | |
| "UPDATE b_file SET | |
| EXTERNAL_ID = ".($external_id != ""? "'".$DB->ForSql($external_id, 50)."'": "null").", | |
| TIMESTAMP_X = ".$DB->GetNowFunction()." | |
| WHERE ID=".intval($ID) | |
| ); | |
| CFile::CleanCache($ID); | |
| } | |
| public static function InputFile($strFieldName, $int_field_size, $strImageID, $strImageStorePath=false, $int_max_file_size=0, $strFileType="IMAGE", $field_file="class=typefile", $description_size=0, $field_text="class=typeinput", $field_checkbox="", $bShowNotes = true, $bShowFilePath = true) | |
| { | |
| $strReturn1 = ""; | |
| if($int_max_file_size != 0) | |
| $strReturn1 .= "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"".$int_max_file_size."\" /> "; | |
| $strReturn1 .= ' <input name="'.$strFieldName.'" '.$field_file.' size="'.$int_field_size.'" type="file" />'; | |
| $strReturn2 = '<span class="bx-input-file-desc">'; | |
| $strDescription = ""; | |
| $db_img_arr = CFile::GetFileArray($strImageID, $strImageStorePath); | |
| if($db_img_arr) | |
| { | |
| $strDescription = $db_img_arr["DESCRIPTION"]; | |
| if(($p=strpos($strFieldName, "["))>0) | |
| { | |
| $strDelName = substr($strFieldName, 0, $p)."_del".substr($strFieldName, $p); | |
| } | |
| else | |
| { | |
| $strDelName = $strFieldName."_del"; | |
| } | |
| if($bShowNotes) | |
| { | |
| if($bShowFilePath) | |
| { | |
| $filePath = $db_img_arr["SRC"]; | |
| } | |
| else | |
| { | |
| $filePath = $db_img_arr['ORIGINAL_NAME']; | |
| } | |
| $io = CBXVirtualIo::GetInstance(); | |
| if($io->FileExists($_SERVER["DOCUMENT_ROOT"].$db_img_arr["SRC"]) || $db_img_arr["HANDLER_ID"]) | |
| { | |
| $strReturn2 .= "<br> ".GetMessage("FILE_TEXT").": ".htmlspecialcharsEx($filePath); | |
| if(strtoupper($strFileType)=="IMAGE") | |
| { | |
| $intWidth = intval($db_img_arr["WIDTH"]); | |
| $intHeight = intval($db_img_arr["HEIGHT"]); | |
| if($intWidth>0 && $intHeight>0) | |
| { | |
| $strReturn2 .= "<br> ".GetMessage("FILE_WIDTH").": $intWidth"; | |
| $strReturn2 .= "<br> ".GetMessage("FILE_HEIGHT").": $intHeight"; | |
| } | |
| } | |
| $strReturn2 .= "<br> ".GetMessage("FILE_SIZE").": ".CFile::FormatSize($db_img_arr["FILE_SIZE"]); | |
| } | |
| else | |
| { | |
| $strReturn2 .= "<br>".GetMessage("FILE_NOT_FOUND").": ".htmlspecialcharsEx($filePath); | |
| } | |
| } | |
| $strReturn2 .= "<br><input ".$field_checkbox." type=\"checkbox\" name=\"".$strDelName."\" value=\"Y\" id=\"".$strDelName."\" /> <label for=\"".$strDelName."\">".GetMessage("FILE_DELETE")."</label>"; | |
| } | |
| $strReturn2 .= '</span>'; | |
| return $strReturn1.( | |
| $description_size > 0? | |
| '<br><input type="text" value="'.htmlspecialcharsbx($strDescription).'" name="'.$strFieldName.'_descr" '.$field_text.' size="'.$description_size.'" title="'.GetMessage("MAIN_FIELD_FILE_DESC").'" />' | |
| :'' | |
| ).$strReturn2; | |
| } | |
| /** | |
| * @param float $size | |
| * @param int $precision | |
| * @return string | |
| */ | |
| public static function FormatSize($size, $precision = 2) | |
| { | |
| static $a = array("b", "Kb", "Mb", "Gb", "Tb"); | |
| $pos = 0; | |
| while($size >= 1024 && $pos < 4) | |
| { | |
| $size /= 1024; | |
| $pos++; | |
| } | |
| return round($size, $precision)." ".GetMessage("FILE_SIZE_".$a[$pos]); | |
| } | |
| public static function GetImageExtensions() | |
| { | |
| return "jpg,bmp,jpeg,jpe,gif,png"; | |
| } | |
| public static function GetFlashExtensions() | |
| { | |
| return "swf"; | |
| } | |
| public static function IsImage($filename, $mime_type=false) | |
| { | |
| $ext = strtolower(GetFileExtension($filename)); | |
| if($ext <> '') | |
| { | |
| if(in_array($ext, explode(",", CFile::GetImageExtensions()))) | |
| { | |
| if($mime_type === false || strpos($mime_type, "image/") === 0) | |
| { | |
| return true; | |
| } | |
| } | |
| } | |
| return false; | |
| } | |
| public static function CheckImageFile($arFile, $iMaxSize=0, $iMaxWidth=0, $iMaxHeight=0, $access_typies=array(), $bForceMD5=false, $bSkipExt=false) | |
| { | |
| if($arFile["name"] == "") | |
| { | |
| return ""; | |
| } | |
| if(preg_match("#^php://filter#i", $arFile["tmp_name"])) | |
| { | |
| return GetMessage("FILE_BAD_FILE_TYPE").".<br>"; | |
| } | |
| $file_type = GetFileType($arFile["name"]); | |
| // IMAGE by default | |
| $flashEnabled = false; | |
| if(!in_array($file_type, $access_typies)) | |
| { | |
| $file_type = "IMAGE"; | |
| } | |
| if($file_type == "FLASH") | |
| { | |
| $flashEnabled = true; | |
| static $flashMime = array("application/x-shockwave-flash", "application/vnd.adobe.flash.movie"); | |
| $res = CFile::CheckFile($arFile, $iMaxSize, $flashMime, CFile::GetFlashExtensions(), $bForceMD5, $bSkipExt); | |
| } | |
| else | |
| { | |
| $res = CFile::CheckFile($arFile, $iMaxSize, "image/", CFile::GetImageExtensions(), $bForceMD5, $bSkipExt); | |
| } | |
| if($res <> '') | |
| { | |
| return $res; | |
| } | |
| $imgArray = CFile::GetImageSize($arFile["tmp_name"], true, $flashEnabled); | |
| if(is_array($imgArray)) | |
| { | |
| $intWIDTH = $imgArray[0]; | |
| $intHEIGHT = $imgArray[1]; | |
| } | |
| else | |
| { | |
| return GetMessage("FILE_BAD_FILE_TYPE").".<br>"; | |
| } | |
| //check for dimensions | |
| if($iMaxWidth > 0 && ($intWIDTH > $iMaxWidth || $intWIDTH == 0) || $iMaxHeight > 0 && ($intHEIGHT > $iMaxHeight || $intHEIGHT == 0)) | |
| { | |
| return GetMessage("FILE_BAD_MAX_RESOLUTION")." (".$iMaxWidth." * ".$iMaxHeight." ".GetMessage("main_include_dots").").<br>"; | |
| } | |
| return null; | |
| } | |
| public static function CheckFile($arFile, $intMaxSize=0, $mimeType=false, $strExt=false, $bForceMD5=false, $bSkipExt=false) | |
| { | |
| if($arFile["name"] == "") | |
| { | |
| return ""; | |
| } | |
| //translit, replace unsafe chars, etc. | |
| $strFileName = self::transformName($arFile["name"], $bForceMD5, $bSkipExt); | |
| //transformed name must be valid, check disk quota, etc. | |
| if(($error = self::validateFile($strFileName, $arFile)) <> '') | |
| { | |
| return $error; | |
| } | |
| if($intMaxSize > 0 && $arFile["size"] > $intMaxSize) | |
| { | |
| return GetMessage("FILE_BAD_SIZE")." (".CFile::FormatSize($intMaxSize).")."; | |
| } | |
| $strFileExt = ''; | |
| if($strExt) | |
| { | |
| $strFileExt = GetFileExtension($strFileName); | |
| if($strFileExt == '') | |
| { | |
| return GetMessage("FILE_BAD_TYPE"); | |
| } | |
| } | |
| //Check mime type | |
| if($mimeType !== false) | |
| { | |
| if(!is_array($mimeType)) | |
| { | |
| $mimeType = array($mimeType); | |
| } | |
| $goodMime = false; | |
| foreach($mimeType as $strMimeType) | |
| { | |
| if(substr($arFile["type"], 0, strlen($strMimeType)) == $strMimeType) | |
| { | |
| $goodMime = true; | |
| break; | |
| } | |
| } | |
| if(!$goodMime) | |
| { | |
| return GetMessage("FILE_BAD_TYPE"); | |
| } | |
| } | |
| //Check extension | |
| if($strExt === false) | |
| { | |
| return ""; | |
| } | |
| $IsExtCorrect = true; | |
| if($strExt) | |
| { | |
| $IsExtCorrect = false; | |
| $tok = strtok($strExt,","); | |
| while($tok) | |
| { | |
| if(strtolower(trim($tok)) == strtolower($strFileExt)) | |
| { | |
| $IsExtCorrect = true; | |
| break; | |
| } | |
| $tok = strtok(","); | |
| } | |
| } | |
| if($IsExtCorrect) | |
| { | |
| return ""; | |
| } | |
| return GetMessage("FILE_BAD_TYPE")." (".strip_tags($strFileExt).")"; | |
| } | |
| public static function ShowFile($iFileID, $max_file_size=0, $iMaxW=0, $iMaxH=0, $bPopup=false, $sParams=false, $sPopupTitle=false, $iSizeWHTTP=0, $iSizeHHTTP=0) | |
| { | |
| $strResult = ""; | |
| $arFile = CFile::GetFileArray($iFileID); | |
| if($arFile) | |
| { | |
| $max_file_size = intval($max_file_size); | |
| if($max_file_size <= 0) | |
| $max_file_size = 1000000000; | |
| $ct = $arFile["CONTENT_TYPE"]; | |
| if($arFile["FILE_SIZE"] <= $max_file_size && CFile::IsImage($arFile["SRC"], $ct)) | |
| { | |
| $strResult = CFile::ShowImage($arFile, $iMaxW, $iMaxH, $sParams, "", $bPopup, $sPopupTitle, $iSizeWHTTP, $iSizeHHTTP); | |
| } | |
| else | |
| { | |
| $strResult = '<a href="'.htmlspecialcharsbx($arFile["SRC"]).'" title="'.GetMessage("FILE_FILE_DOWNLOAD").'">'.htmlspecialcharsbx($arFile["FILE_NAME"]).'</a>'; | |
| } | |
| } | |
| return $strResult; | |
| } | |
| public static function DisableJSFunction($b=true) | |
| { | |
| global $SHOWIMAGEFIRST; | |
| $SHOWIMAGEFIRST = $b; | |
| } | |
| public static function OutputJSImgShw() | |
| { | |
| global $SHOWIMAGEFIRST; | |
| if(!defined("ADMIN_SECTION") && $SHOWIMAGEFIRST!==true) | |
| { | |
| echo | |
| '<script type="text/javascript"> | |
| function ImgShw(ID, width, height, alt) | |
| { | |
| var scroll = "no"; | |
| var top=0, left=0; | |
| var w, h; | |
| if(navigator.userAgent.toLowerCase().indexOf("opera") != -1) | |
| { | |
| w = document.body.offsetWidth; | |
| h = document.body.offsetHeight; | |
| } | |
| else | |
| { | |
| w = screen.width; | |
| h = screen.height; | |
| } | |
| if(width > w-10 || height > h-28) | |
| scroll = "yes"; | |
| if(height < h-28) | |
| top = Math.floor((h - height)/2-14); | |
| if(width < w-10) | |
| left = Math.floor((w - width)/2-5); | |
| width = Math.min(width, w-10); | |
| height = Math.min(height, h-28); | |
| var wnd = window.open("","","scrollbars="+scroll+",resizable=yes,width="+width+",height="+height+",left="+left+",top="+top); | |
| wnd.document.write( | |
| "<html><head>"+ | |
| "<"+"script type=\"text/javascript\">"+ | |
| "function KeyPress(e)"+ | |
| "{"+ | |
| " if (!e) e = window.event;"+ | |
| " if(e.keyCode == 27) "+ | |
| " window.close();"+ | |
| "}"+ | |
| "</"+"script>"+ | |
| "<title>"+(alt == ""? "'.GetMessage("main_js_img_title").'":alt)+"</title></head>"+ | |
| "<body topmargin=\"0\" leftmargin=\"0\" marginwidth=\"0\" marginheight=\"0\" onKeyDown=\"KeyPress(arguments[0])\">"+ | |
| "<img src=\""+ID+"\" border=\"0\" alt=\""+alt+"\" />"+ | |
| "</body></html>" | |
| ); | |
| wnd.document.close(); | |
| wnd.focus(); | |
| } | |
| </script>'; | |
| $SHOWIMAGEFIRST=true; | |
| } | |
| } | |
| public static function _GetImgParams($strImage, $iSizeWHTTP=0, $iSizeHHTTP=0) | |
| { | |
| global $arCloudImageSizeCache; | |
| $io = CBXVirtualIo::GetInstance(); | |
| if(strlen($strImage) <= 0) | |
| return false; | |
| $strAlt = ''; | |
| if(intval($strImage)>0) | |
| { | |
| $db_img_arr = CFile::GetFileArray($strImage); | |
| if($db_img_arr) | |
| { | |
| $strImage = $db_img_arr["SRC"]; | |
| $intWidth = intval($db_img_arr["WIDTH"]); | |
| $intHeight = intval($db_img_arr["HEIGHT"]); | |
| $strAlt = $db_img_arr["DESCRIPTION"]; | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| } | |
| else | |
| { | |
| if(!preg_match("#^https?://#", $strImage)) | |
| { | |
| if($io->FileExists($_SERVER["DOCUMENT_ROOT"].$strImage)) | |
| { | |
| $arSize = CFile::GetImageSize($_SERVER["DOCUMENT_ROOT"].$strImage); | |
| $intWidth = intval($arSize[0]); | |
| $intHeight = intval($arSize[1]); | |
| $strAlt = ""; | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| } | |
| elseif(array_key_exists($strImage, $arCloudImageSizeCache)) | |
| { | |
| $intWidth = $arCloudImageSizeCache[$strImage][0]; | |
| $intHeight = $arCloudImageSizeCache[$strImage][1]; | |
| } | |
| else | |
| { | |
| $intWidth = intval($iSizeWHTTP); | |
| $intHeight = intval($iSizeHHTTP); | |
| $strAlt = ""; | |
| } | |
| } | |
| return array( | |
| "SRC"=>$strImage, | |
| "WIDTH"=>$intWidth, | |
| "HEIGHT"=>$intHeight, | |
| "ALT"=>$strAlt, | |
| ); | |
| } | |
| /** | |
| * Retuns the path from the root by a file ID. | |
| * | |
| * @param int $img_id File ID | |
| * @return string|null | |
| */ | |
| public static function GetPath($img_id) | |
| { | |
| $img_id = intval($img_id); | |
| if($img_id > 0) | |
| { | |
| $res = CFile::_GetImgParams($img_id); | |
| return $res["SRC"]; | |
| } | |
| return null; | |
| } | |
| public static function ShowImage($strImage, $iMaxW=0, $iMaxH=0, $sParams=null, $strImageUrl="", $bPopup=false, $sPopupTitle=false, $iSizeWHTTP=0, $iSizeHHTTP=0, $strImageUrlTemplate="") | |
| { | |
| if(is_array($strImage)) | |
| { | |
| $arImgParams = $strImage; | |
| $iImageID = isset($arImgParams['ID']) ? intval($arImgParams['ID']) : 0; | |
| } | |
| else | |
| { | |
| $arImgParams = CFile::_GetImgParams($strImage, $iSizeWHTTP, $iSizeHHTTP); | |
| $iImageID = intval($strImage); | |
| } | |
| if(!$arImgParams) | |
| return ""; | |
| $iMaxW = intval($iMaxW); | |
| $iMaxH = intval($iMaxH); | |
| $intWidth = $arImgParams['WIDTH']; | |
| $intHeight = $arImgParams['HEIGHT']; | |
| if( | |
| $iMaxW > 0 && $iMaxH > 0 | |
| && ($intWidth > $iMaxW || $intHeight > $iMaxH) | |
| ) | |
| { | |
| $coeff = ($intWidth/$iMaxW > $intHeight/$iMaxH? $intWidth/$iMaxW : $intHeight/$iMaxH); | |
| $iHeight = intval(roundEx($intHeight/$coeff)); | |
| $iWidth = intval(roundEx($intWidth/$coeff)); | |
| } | |
| else | |
| { | |
| $coeff = 1; | |
| $iHeight = $intHeight; | |
| $iWidth = $intWidth; | |
| } | |
| $strImageUrlTemplate = strval($strImageUrlTemplate); | |
| if($strImageUrlTemplate === '' || $iImageID <= 0) | |
| { | |
| $strImage = $arImgParams['SRC']; | |
| } | |
| else | |
| { | |
| $strImage = CComponentEngine::MakePathFromTemplate($strImageUrlTemplate, array('file_id' => $iImageID)); | |
| } | |
| if (!preg_match("/^https?:/i", $strImage)) | |
| $strImage = CHTTP::urnEncode($strImage, "UTF-8"); | |
| if(GetFileType($strImage) == "FLASH") | |
| { | |
| $strReturn = ' | |
| <object | |
| classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" | |
| codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" | |
| id="banner" | |
| WIDTH="'.$iWidth.'" | |
| HEIGHT="'.$iHeight.'" | |
| ALIGN=""> | |
| <PARAM NAME="movie" VALUE="'.$strImage.'" /> | |
| <PARAM NAME="quality" VALUE="high" /> | |
| <PARAM NAME="bgcolor" VALUE="#FFFFFF" /> | |
| <embed | |
| src="'.$strImage.'" | |
| quality="high" | |
| bgcolor="#FFFFFF" | |
| WIDTH="'.$iWidth.'" | |
| HEIGHT="'.$iHeight.'" | |
| NAME="banner" | |
| ALIGN="" | |
| TYPE="application/x-shockwave-flash" | |
| PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer"> | |
| </embed> | |
| </object> | |
| '; | |
| } | |
| else | |
| { | |
| $strAlt = $arImgParams['ALT']? $arImgParams['ALT']: $arImgParams['DESCRIPTION']; | |
| if($sParams === null || $sParams === false) | |
| $sParams = 'border="0" alt="'.htmlspecialcharsEx($strAlt).'"'; | |
| elseif(!preg_match('/(^|\\s)alt\\s*=\\s*(["\']?)(.*?)(\\2)/is', $sParams)) | |
| $sParams .= ' alt="'.htmlspecialcharsEx($strAlt).'"'; | |
| if($coeff === 1 || !$bPopup) | |
| { | |
| $strReturn = '<img src="'.$strImage.'" '.$sParams.' width="'.$iWidth.'" height="'.$iHeight.'" />'; | |
| } | |
| else | |
| { | |
| if($sPopupTitle === false) | |
| $sPopupTitle = GetMessage('FILE_ENLARGE'); | |
| if(strlen($strImageUrl)>0) | |
| { | |
| $strReturn = | |
| '<a href="'.$strImageUrl.'" title="'.$sPopupTitle.'" target="_blank">'. | |
| '<img src="'.$strImage.'" '.$sParams.' width="'.$iWidth.'" height="'.$iHeight.'" title="'.htmlspecialcharsEx($sPopupTitle).'" />'. | |
| '</a>'; | |
| } | |
| else | |
| { | |
| CFile::OutputJSImgShw(); | |
| $strReturn = | |
| '<a title="'.$sPopupTitle.'" onclick="ImgShw(\''.CUtil::addslashes($strImage).'\', '.$intWidth.', '.$intHeight.', \''.CUtil::addslashes(htmlspecialcharsEx(htmlspecialcharsEx($strAlt))).'\'); return false;" href="'.$strImage.'" target="_blank">'. | |
| '<img src="'.$strImage.'" '.$sParams.' width="'.$iWidth.'" height="'.$iHeight.'" />'. | |
| '</a>'; | |
| } | |
| } | |
| } | |
| return $bPopup? $strReturn : print_url($strImageUrl, $strReturn); | |
| } | |
| public static function Show2Images($strImage1, $strImage2, $iMaxW=0, $iMaxH=0, $sParams=false, $sPopupTitle=false, $iSizeWHTTP=0, $iSizeHHTTP=0) | |
| { | |
| if(!($arImgParams = CFile::_GetImgParams($strImage1, $iSizeWHTTP, $iSizeHHTTP))) | |
| return ""; | |
| if (!preg_match("/^https?:/i", $strImage1)) | |
| $strImage1 = CHTTP::urnEncode($arImgParams["SRC"], "UTF-8"); | |
| $intWidth = $arImgParams["WIDTH"]; | |
| $intHeight = $arImgParams["HEIGHT"]; | |
| $strAlt = $arImgParams["ALT"]; | |
| if($sParams == false) | |
| $sParams = 'border="0" alt="'.htmlspecialcharsEx($strAlt).'"'; | |
| elseif(!preg_match("/(^|\\s)alt\\s*=\\s*([\"']?)(.*?)(\\2)/is", $sParams)) | |
| $sParams .= ' alt="'.htmlspecialcharsEx($strAlt).'"'; | |
| if( | |
| $iMaxW > 0 && $iMaxH > 0 | |
| && ($intWidth > $iMaxW || $intHeight > $iMaxH) | |
| ) | |
| { | |
| $coeff = ($intWidth/$iMaxW > $intHeight/$iMaxH? $intWidth/$iMaxW : $intHeight/$iMaxH); | |
| $iHeight = intval(roundEx($intHeight/$coeff)); | |
| $iWidth = intval(roundEx($intWidth/$coeff)); | |
| } | |
| else | |
| { | |
| $iHeight = $intHeight; | |
| $iWidth = $intWidth; | |
| } | |
| if($arImgParams = CFile::_GetImgParams($strImage2, $iSizeWHTTP, $iSizeHHTTP)) | |
| { | |
| if($sPopupTitle === false) | |
| $sPopupTitle = GetMessage("FILE_ENLARGE"); | |
| if (!preg_match("/^https?:/i", $strImage2)) | |
| $strImage2 = CHTTP::urnEncode($arImgParams["SRC"], "UTF-8"); | |
| $intWidth2 = $arImgParams["WIDTH"]; | |
| $intHeight2 = $arImgParams["HEIGHT"]; | |
| $strAlt2 = $arImgParams["ALT"]; | |
| CFile::OutputJSImgShw(); | |
| $strReturn = | |
| "<a title=\"".$sPopupTitle."\" onclick=\"ImgShw('".CUtil::addslashes($strImage2)."','".$intWidth2."','".$intHeight2."', '".CUtil::addslashes(htmlspecialcharsEx(htmlspecialcharsEx($strAlt2)))."'); return false;\" href=\"".$strImage2."\" target=_blank>". | |
| "<img src=\"".$strImage1."\" ".$sParams." width=".$iWidth." height=".$iHeight." /></a>"; | |
| } | |
| else | |
| { | |
| $strReturn = "<img src=\"".$strImage1."\" ".$sParams." width=".$iWidth." height=".$iHeight." />"; | |
| } | |
| return $strReturn; | |
| } | |
| /** | |
| * Returns an array describing file as if it was $_FILES element. | |
| * | |
| * @param string|int $path May contain ID of the file, absolute path, relative path or an url. | |
| * @param string|bool $mimetype Forces type field of the array | |
| * @param bool $skipInternal Excludes using ID as $path | |
| * @param string $external_id | |
| * @return array|bool|null | |
| */ | |
| public static function MakeFileArray($path, $mimetype = false, $skipInternal = false, $external_id = "") | |
| { | |
| $io = CBXVirtualIo::GetInstance(); | |
| $arFile = array(); | |
| if(intval($path)>0) | |
| { | |
| if ($skipInternal) | |
| return false; | |
| $res = CFile::GetByID($path); | |
| if($ar = $res->Fetch()) | |
| { | |
| $bExternalStorage = false; | |
| foreach(GetModuleEvents("main", "OnMakeFileArray", true) as $arEvent) | |
| { | |
| if(ExecuteModuleEventEx($arEvent, array($ar, &$arFile))) | |
| { | |
| $bExternalStorage = true; | |
| break; | |
| } | |
| } | |
| if(!$bExternalStorage) | |
| { | |
| $arFile["name"] = (strlen($ar['ORIGINAL_NAME'])>0?$ar['ORIGINAL_NAME']:$ar['FILE_NAME']); | |
| $arFile["size"] = $ar['FILE_SIZE']; | |
| $arFile["type"] = $ar['CONTENT_TYPE']; | |
| $arFile["description"] = $ar['DESCRIPTION']; | |
| $arFile["tmp_name"] = $io->GetPhysicalName(preg_replace("#[\\\\\\/]+#", "/", $_SERVER['DOCUMENT_ROOT'].'/'.(COption::GetOptionString('main', 'upload_dir', 'upload')).'/'.$ar['SUBDIR'].'/'.$ar['FILE_NAME'])); | |
| } | |
| if (!isset($arFile["external_id"])) | |
| { | |
| $arFile["external_id"] = $external_id != ""? $external_id: $ar["EXTERNAL_ID"]; | |
| } | |
| return $arFile; | |
| } | |
| } | |
| $path = preg_replace("#(?<!:)[\\\\\\/]+#", "/", $path); | |
| if(strlen($path) == 0 || $path == "/") | |
| { | |
| return NULL; | |
| } | |
| if(preg_match("#^php://filter#i", $path)) | |
| { | |
| return NULL; | |
| } | |
| if(preg_match("#^(http[s]?)://#", $path)) | |
| { | |
| $temp_path = ''; | |
| $bExternalStorage = false; | |
| foreach(GetModuleEvents("main", "OnMakeFileArray", true) as $arEvent) | |
| { | |
| if(ExecuteModuleEventEx($arEvent, array($path, &$temp_path))) | |
| { | |
| $bExternalStorage = true; | |
| break; | |
| } | |
| } | |
| if(!$bExternalStorage) | |
| { | |
| $urlComponents = parse_url($path); | |
| if ($urlComponents && strlen($urlComponents["path"]) > 0) | |
| $temp_path = CFile::GetTempName('', bx_basename($urlComponents["path"])); | |
| else | |
| $temp_path = CFile::GetTempName('', bx_basename($path)); | |
| $ob = new CHTTP; | |
| $ob->follow_redirect = true; | |
| if($ob->Download($path, $temp_path)) | |
| $arFile = CFile::MakeFileArray($temp_path); | |
| } | |
| elseif($temp_path) | |
| { | |
| $arFile = CFile::MakeFileArray($temp_path); | |
| } | |
| } | |
| elseif(preg_match("#^(ftp[s]?|php)://#", $path)) | |
| { | |
| if($fp = fopen($path,"rb")) | |
| { | |
| $content = ""; | |
| while(!feof($fp)) | |
| $content .= fgets($fp, 4096); | |
| if(strlen($content) > 0) | |
| { | |
| $temp_path = CFile::GetTempName('', bx_basename($path)); | |
| if (RewriteFile($temp_path, $content)) | |
| $arFile = CFile::MakeFileArray($temp_path); | |
| } | |
| fclose($fp); | |
| } | |
| } | |
| else | |
| { | |
| if(!file_exists($path)) | |
| { | |
| if (file_exists($_SERVER["DOCUMENT_ROOT"].$path)) | |
| $path = $_SERVER["DOCUMENT_ROOT"].$path; | |
| else | |
| return NULL; | |
| } | |
| if(is_dir($path)) | |
| return NULL; | |
| $arFile["name"] = $io->GetLogicalName(bx_basename($path)); | |
| $arFile["size"] = filesize($path); | |
| $arFile["tmp_name"] = $path; | |
| $arFile["type"] = $mimetype; | |
| if(strlen($arFile["type"])<=0) | |
| $arFile["type"] = CFile::GetContentType($path, true); | |
| } | |
| if(strlen($arFile["type"])<=0) | |
| $arFile["type"] = "unknown"; | |
| if (!isset($arFile["external_id"]) && ($external_id != "")) | |
| { | |
| $arFile["external_id"] = $external_id; | |
| } | |
| return $arFile; | |
| } | |
| public static function GetTempName($dir_name = false, $file_name = '') | |
| { | |
| //accidentally $file_name can contain "?params" | |
| if(($pos = strpos($file_name, "?")) !== false) | |
| { | |
| $file_name = substr($file_name, 0, $pos); | |
| } | |
| return CTempFile::GetFileName($file_name); | |
| } | |
| public static function ChangeSubDir($module_id, $old_subdir, $new_subdir) | |
| { | |
| global $DB; | |
| if ($old_subdir!=$new_subdir) | |
| { | |
| $strSql = " | |
| UPDATE b_file SET | |
| SUBDIR = REPLACE(SUBDIR,'".$DB->ForSQL($old_subdir)."','".$DB->ForSQL($new_subdir)."'), | |
| TIMESTAMP_X = ".$DB->GetNowFunction()." | |
| WHERE MODULE_ID='".$DB->ForSQL($module_id)."' | |
| "; | |
| if($rs = $DB->Query($strSql, false, __LINE__)) | |
| { | |
| $from = "/".COption::GetOptionString("main", "upload_dir", "upload")."/".$old_subdir; | |
| $to = "/".COption::GetOptionString("main", "upload_dir", "upload")."/".$new_subdir; | |
| CopyDirFiles($_SERVER["DOCUMENT_ROOT"].$from, $_SERVER["DOCUMENT_ROOT"].$to, true, true, true); | |
| //Reset All b_file cache | |
| $cache = Bitrix\Main\Application::getInstance()->getManagedCache(); | |
| $cache->cleanDir("b_file"); | |
| } | |
| } | |
| } | |
| public static function ResizeImage(&$arFile, $arSize, $resizeType = BX_RESIZE_IMAGE_PROPORTIONAL) | |
| { | |
| $sourceFile = $arFile["tmp_name"]; | |
| $destinationFile = CTempFile::GetFileName(basename($sourceFile)); | |
| CheckDirPath($destinationFile); | |
| if (CFile::ResizeImageFile($sourceFile, $destinationFile, $arSize, $resizeType)) | |
| { | |
| $arFile["tmp_name"] = $destinationFile; | |
| $arImageSize = CFile::GetImageSize($destinationFile); | |
| $arFile["type"] = $arImageSize["mime"]; | |
| $arFile["size"] = filesize($arFile["tmp_name"]); | |
| return true; | |
| } | |
| return false; | |
| } | |
| public static function ResizeImageDeleteCache($arFile) | |
| { | |
| $temp_dir = CTempFile::GetAbsoluteRoot()."/"; | |
| if(strpos($arFile["tmp_name"], $temp_dir) === 0) | |
| if(file_exists($arFile["tmp_name"])) | |
| unlink($arFile["tmp_name"]); | |
| } | |
| public static function ResizeImageGet($file, $arSize, $resizeType = BX_RESIZE_IMAGE_PROPORTIONAL, $bInitSizes = false, $arFilters = false, $bImmediate = false, $jpgQuality = false) | |
| { | |
| if (!is_array($file) && intval($file) > 0) | |
| { | |
| $file = CFile::GetFileArray($file); | |
| } | |
| if (!is_array($file) || !array_key_exists("FILE_NAME", $file) || strlen($file["FILE_NAME"]) <= 0) | |
| return false; | |
| if ($resizeType !== BX_RESIZE_IMAGE_EXACT && $resizeType !== BX_RESIZE_IMAGE_PROPORTIONAL_ALT) | |
| $resizeType = BX_RESIZE_IMAGE_PROPORTIONAL; | |
| if (!is_array($arSize)) | |
| $arSize = array(); | |
| if (!array_key_exists("width", $arSize) || intval($arSize["width"]) <= 0) | |
| $arSize["width"] = 0; | |
| if (!array_key_exists("height", $arSize) || intval($arSize["height"]) <= 0) | |
| $arSize["height"] = 0; | |
| $arSize["width"] = intval($arSize["width"]); | |
| $arSize["height"] = intval($arSize["height"]); | |
| $uploadDirName = COption::GetOptionString("main", "upload_dir", "upload"); | |
| $imageFile = "/".$uploadDirName."/".$file["SUBDIR"]."/".$file["FILE_NAME"]; | |
| $arImageSize = false; | |
| $bFilters = is_array($arFilters) && !empty($arFilters); | |
| if ( | |
| ($arSize["width"] <= 0 || $arSize["width"] >= $file["WIDTH"]) | |
| && ($arSize["height"] <= 0 || $arSize["height"] >= $file["HEIGHT"]) | |
| ) | |
| { | |
| if($bFilters) | |
| { | |
| //Only filters. Leave size unchanged | |
| $arSize["width"] = $file["WIDTH"]; | |
| $arSize["height"] = $file["HEIGHT"]; | |
| $resizeType = BX_RESIZE_IMAGE_PROPORTIONAL; | |
| } | |
| else | |
| { | |
| global $arCloudImageSizeCache; | |
| $arCloudImageSizeCache[$file["SRC"]] = array($file["WIDTH"], $file["HEIGHT"]); | |
| return array( | |
| "src" => $file["SRC"], | |
| "width" => intval($file["WIDTH"]), | |
| "height" => intval($file["HEIGHT"]), | |
| "size" => $file["FILE_SIZE"], | |
| ); | |
| } | |
| } | |
| $io = CBXVirtualIo::GetInstance(); | |
| $cacheImageFile = "/".$uploadDirName."/resize_cache/".$file["SUBDIR"]."/".$arSize["width"]."_".$arSize["height"]."_".$resizeType.(is_array($arFilters)? md5(serialize($arFilters)): "")."/".$file["FILE_NAME"]; | |
| $cacheImageFileCheck = $cacheImageFile; | |
| if ($file["CONTENT_TYPE"] == "image/bmp") | |
| $cacheImageFileCheck .= ".jpg"; | |
| static $cache = array(); | |
| $cache_id = $cacheImageFileCheck; | |
| if(isset($cache[$cache_id])) | |
| { | |
| return $cache[$cache_id]; | |
| } | |
| elseif (!file_exists($io->GetPhysicalName($_SERVER["DOCUMENT_ROOT"].$cacheImageFileCheck))) | |
| { | |
| /****************************** QUOTA ******************************/ | |
| $bDiskQuota = true; | |
| if (COption::GetOptionInt("main", "disk_space") > 0) | |
| { | |
| $quota = new CDiskQuota(); | |
| $bDiskQuota = $quota->checkDiskQuota($file); | |
| } | |
| /****************************** QUOTA ******************************/ | |
| if ($bDiskQuota) | |
| { | |
| if(!is_array($arFilters)) | |
| $arFilters = array( | |
| array("name" => "sharpen", "precision" => 15), | |
| ); | |
| $sourceImageFile = $_SERVER["DOCUMENT_ROOT"].$imageFile; | |
| $cacheImageFileTmp = $_SERVER["DOCUMENT_ROOT"].$cacheImageFile; | |
| $bNeedResize = true; | |
| $callbackData = null; | |
| foreach(GetModuleEvents("main", "OnBeforeResizeImage", true) as $arEvent) | |
| { | |
| if(ExecuteModuleEventEx($arEvent, array( | |
| $file, | |
| array($arSize, $resizeType, array(), false, $arFilters, $bImmediate), | |
| &$callbackData, | |
| &$bNeedResize, | |
| &$sourceImageFile, | |
| &$cacheImageFileTmp, | |
| ))) | |
| break; | |
| } | |
| if ($bNeedResize && CFile::ResizeImageFile($sourceImageFile, $cacheImageFileTmp, $arSize, $resizeType, array(), $jpgQuality, $arFilters)) | |
| { | |
| $cacheImageFile = substr($cacheImageFileTmp, strlen($_SERVER["DOCUMENT_ROOT"])); | |
| /****************************** QUOTA ******************************/ | |
| if (COption::GetOptionInt("main", "disk_space") > 0) | |
| CDiskQuota::updateDiskQuota("file", filesize($io->GetPhysicalName($cacheImageFileTmp)), "insert"); | |
| /****************************** QUOTA ******************************/ | |
| } | |
| else | |
| { | |
| $cacheImageFile = $imageFile; | |
| } | |
| foreach(GetModuleEvents("main", "OnAfterResizeImage", true) as $arEvent) | |
| { | |
| if(ExecuteModuleEventEx($arEvent, array( | |
| $file, | |
| array($arSize, $resizeType, array(), false, $arFilters), | |
| &$callbackData, | |
| &$cacheImageFile, | |
| &$cacheImageFileTmp, | |
| &$arImageSize, | |
| ))) | |
| break; | |
| } | |
| } | |
| else | |
| { | |
| $cacheImageFile = $imageFile; | |
| } | |
| $cacheImageFileCheck = $cacheImageFile; | |
| } | |
| if ($bInitSizes && !is_array($arImageSize)) | |
| { | |
| $arImageSize = CFile::GetImageSize($_SERVER["DOCUMENT_ROOT"].$cacheImageFileCheck); | |
| $f = $io->GetFile($_SERVER["DOCUMENT_ROOT"].$cacheImageFileCheck); | |
| $arImageSize[2] = $f->GetFileSize(); | |
| } | |
| $cache[$cache_id] = array( | |
| "src" => $cacheImageFileCheck, | |
| "width" => intval($arImageSize[0]), | |
| "height" => intval($arImageSize[1]), | |
| "size" => $arImageSize[2], | |
| ); | |
| return $cache[$cache_id]; | |
| } | |
| public static function ResizeImageDelete($arImage) | |
| { | |
| $io = CBXVirtualIo::GetInstance(); | |
| $upload_dir = COption::GetOptionString("main", "upload_dir", "upload"); | |
| $disk_space = COption::GetOptionInt("main", "disk_space"); | |
| $delete_size = 0; | |
| $d = $io->GetDirectory($_SERVER["DOCUMENT_ROOT"]."/".$upload_dir."/resize_cache/".$arImage["SUBDIR"]); | |
| /** @var CBXVirtualFileFileSystem|CBXVirtualDirectoryFileSystem $dir_entry */ | |
| foreach($d->GetChildren() as $dir_entry) | |
| { | |
| if($dir_entry->IsDirectory()) | |
| { | |
| $f = $io->GetFile($dir_entry->GetPathWithName()."/".$arImage["FILE_NAME"]); | |
| if($f->IsExists()) | |
| { | |
| if ($disk_space > 0) | |
| { | |
| $fileSizeTmp = $f->GetFileSize(); | |
| if ($io->Delete($f->GetPathWithName())) | |
| $delete_size += $fileSizeTmp; | |
| } | |
| else | |
| { | |
| $io->Delete($f->GetPathWithName()); | |
| } | |
| } | |
| @rmdir($io->GetPhysicalName($dir_entry->GetPathWithName())); | |
| } | |
| } | |
| @rmdir($io->GetPhysicalName($d->GetPathWithName())); | |
| return $delete_size; | |
| } | |
| public static function ImageCreateFromBMP($filename) | |
| { | |
| // https://ru.wikipedia.org/wiki/BMP | |
| if(!$f1 = fopen($filename,"rb")) | |
| return false; | |
| //1 : read and parse HEADER | |
| $FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14)); | |
| if ($FILE['file_type'] != 19778) | |
| return false; | |
| $head = unpack('Vheader_size', fread($f1, 4)); | |
| if ($head['header_size'] == 12) | |
| { | |
| //2 : read and parse BMP data (CORE) | |
| $BMP = unpack('vwidth/vheight/vplanes/vbits_per_pixel', fread($f1, 8)); | |
| } | |
| else | |
| { | |
| //2 : read and parse BMP data (3 4 5) | |
| $BMP = unpack('lwidth/lheight/vplanes/vbits_per_pixel'. | |
| '/Vcompression/Vsize_bitmap/Vhoriz_resolution'. | |
| '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1, 36)); | |
| } | |
| if($BMP['width'] < 0) | |
| $BMP['width'] = 0; | |
| if($BMP['height'] < 0) | |
| { | |
| $flip = true; | |
| $BMP['height'] = -$BMP['height']; | |
| } | |
| else | |
| { | |
| $flip = false; | |
| } | |
| $BMP['colors'] = pow(2,$BMP['bits_per_pixel']); | |
| if($BMP['colors_used'] > 0) | |
| $BMP['palette_size'] = $BMP['colors_used']; | |
| else | |
| $BMP['palette_size'] = $BMP['colors']; | |
| if ($BMP['size_bitmap'] == 0) | |
| $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset']; | |
| $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8; | |
| $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']); | |
| $BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4); | |
| $BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4); | |
| $BMP['decal'] = 4-(4*$BMP['decal']); | |
| if ($BMP['decal'] == 4) | |
| $BMP['decal'] = 0; | |
| //3 : Read palette | |
| $PALETTE = array(); | |
| if ($BMP['colors'] < 16777216) | |
| { | |
| $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4)); | |
| } | |
| //4 : Create an image canvas to draw on | |
| $res = imagecreatetruecolor($BMP['width'],$BMP['height']); | |
| $VIDE = chr(0); | |
| if($BMP['bits_per_pixel'] == 32) | |
| { | |
| $dPY = $BMP['decal']; | |
| $width = $BMP['width']; | |
| $Y = $BMP['height'] - 1; | |
| while ($Y >= 0) | |
| { | |
| $X = 0; | |
| while($X < $width) | |
| { | |
| $COLOR = unpack("C4", fread($f1, 4)); | |
| imagesetpixel($res, $X, $Y, ($COLOR[3]<<16) | ($COLOR[2]<<8) | ($COLOR[1])); | |
| $X++; | |
| } | |
| $Y--; | |
| if($dPY > 0) | |
| fread($f1, $dPY); | |
| if (feof($f1)) | |
| break; | |
| } | |
| } | |
| elseif($BMP['bits_per_pixel'] == 24 && $flip) | |
| { | |
| $dPY = $BMP['decal']; | |
| $width = $BMP['width']; | |
| $Y = 0; | |
| while ($Y < $BMP['height']) | |
| { | |
| $X = 0; | |
| while($X < $width) | |
| { | |
| $COLOR = unpack("V", fread($f1, 3).$VIDE); | |
| imagesetpixel($res, $X, $Y, $COLOR[1]); | |
| $X++; | |
| } | |
| $Y++; | |
| if($dPY > 0) | |
| fread($f1, $dPY); | |
| if (feof($f1)) | |
| break; | |
| } | |
| } | |
| elseif($BMP['bits_per_pixel'] == 24) | |
| { | |
| $dPY = $BMP['decal']; | |
| $width = $BMP['width']; | |
| $Y = $BMP['height'] - 1; | |
| while ($Y >= 0) | |
| { | |
| $X = 0; | |
| while($X < $width) | |
| { | |
| $COLOR = unpack("V", fread($f1, 3).$VIDE); | |
| imagesetpixel($res, $X, $Y, $COLOR[1]); | |
| $X++; | |
| } | |
| $Y--; | |
| if($dPY > 0) | |
| fread($f1, $dPY); | |
| if (feof($f1)) | |
| break; | |
| } | |
| } | |
| elseif($BMP['bits_per_pixel'] == 16 && $BMP['compression'] == 0) | |
| { | |
| fseek($f1, $FILE['bitmap_offset'], SEEK_SET); | |
| $dPY = $BMP['decal']; | |
| $width = $BMP['width']; | |
| $Y = $BMP['height'] - 1; | |
| while ($Y >= 0) | |
| { | |
| $X = 0; | |
| while($X < $width) | |
| { | |
| $COLOR = unpack("C2", fread($f1, 2)); | |
| $R = ($COLOR[2] >> 2) & 0x1f; | |
| $G = (($COLOR[2] & 0x03) << 3) | ($COLOR[1] >> 5); | |
| $B = $COLOR[1] & 0x1f; | |
| imagesetpixel($res, $X, $Y, (($R*8)<<16) | (($G*8)<<8) | ($B*8)); | |
| $X++; | |
| } | |
| $Y--; | |
| if($dPY > 0) | |
| fread($f1, $dPY); | |
| if (feof($f1)) | |
| break; | |
| } | |
| } | |
| elseif($BMP['bits_per_pixel'] == 16) | |
| { | |
| fseek($f1, $FILE['bitmap_offset'], SEEK_SET); | |
| $dPY = $BMP['decal']; | |
| $width = $BMP['width']; | |
| $Y = $BMP['height'] - 1; | |
| while ($Y >= 0) | |
| { | |
| $X = 0; | |
| while($X < $width) | |
| { | |
| $COLOR = unpack("C2", fread($f1, 2)); | |
| $R = $COLOR[2] >> 3; | |
| $G = ($COLOR[2] & 0x07) << 3 | ($COLOR[1] >> 5); | |
| $B = $COLOR[1] & 0x1f; | |
| imagesetpixel($res, $X, $Y, (($R*8)<<16) | (($G*4)<<8) | ($B*8)); | |
| $X++; | |
| } | |
| $Y--; | |
| if($dPY > 0) | |
| fread($f1, $dPY); | |
| if (feof($f1)) | |
| break; | |
| } | |
| } | |
| elseif($BMP['bits_per_pixel'] == 8) | |
| { | |
| fseek($f1, $FILE['bitmap_offset'], SEEK_SET); | |
| $dPY = $BMP['decal']; | |
| $width = $BMP['width']; | |
| $Y = $BMP['height'] - 1; | |
| while ($Y >= 0) | |
| { | |
| $X = 0; | |
| while($X < $width) | |
| { | |
| $COLOR = unpack("n", $VIDE.fread($f1, 1)); | |
| imagesetpixel($res, $X, $Y, $PALETTE[$COLOR[1]+1]); | |
| $X++; | |
| } | |
| $Y--; | |
| if($dPY > 0) | |
| fread($f1, $dPY); | |
| if (feof($f1)) | |
| break; | |
| } | |
| } | |
| elseif ($BMP['bits_per_pixel'] == 4) | |
| { | |
| $IMG = fread($f1, $BMP['size_bitmap']); | |
| $P = 0; | |
| $Y = $BMP['height']-1; | |
| while ($Y >= 0) | |
| { | |
| $X = 0; | |
| $COLORS = unpack("H*", cutil::binsubstr($IMG, floor($P), floor($P)+$BMP['width']*$BMP['bytes_per_pixel'])); | |
| while ($X < $BMP['width']) | |
| { | |
| $C = hexdec($COLORS[1][$X]); | |
| imagesetpixel($res, $X, $Y, $PALETTE[$C+1]); | |
| $X++; | |
| $P += $BMP['bytes_per_pixel']; | |
| } | |
| $Y--; | |
| $P += $BMP['decal']; | |
| if (feof($f1)) | |
| break; | |
| } | |
| } | |
| elseif ($BMP['bits_per_pixel'] == 1) | |
| { | |
| $COLORS = unpack("H*", fread($f1,$BMP['size_bitmap'])); | |
| $P = 0; | |
| $Y = $BMP['height']-1; | |
| while ($Y >= 0) | |
| { | |
| $i = (int)floor($P)*2; | |
| $X = 0; | |
| while ($X < $BMP['width']) | |
| { | |
| $C = hexdec($COLORS[1][$i]); | |
| imagesetpixel($res, $X, $Y, $PALETTE[$C & 8? 2: 1]); | |
| $X++; | |
| $P += $BMP['bytes_per_pixel']; | |
| if ($X < $BMP['width']) | |
| { | |
| imagesetpixel($res, $X, $Y, $PALETTE[$C & 4? 2: 1]); | |
| $X++; | |
| $P += $BMP['bytes_per_pixel']; | |
| if ($X < $BMP['width']) | |
| { | |
| imagesetpixel($res, $X, $Y, $PALETTE[$C & 2? 2: 1]); | |
| $X++; | |
| $P += $BMP['bytes_per_pixel']; | |
| if ($X < $BMP['width']) | |
| { | |
| imagesetpixel($res, $X, $Y, $PALETTE[$C & 1? 2: 1]); | |
| $X++; | |
| $P += $BMP['bytes_per_pixel']; | |
| } | |
| } | |
| } | |
| $i++; | |
| } | |
| $Y--; | |
| $P += $BMP['decal']; | |
| } | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| fclose($f1); | |
| return $res; | |
| } | |
| public static function ScaleImage($sourceImageWidth, $sourceImageHeight, $arSize, $resizeType, &$bNeedCreatePicture, &$arSourceSize, &$arDestinationSize) | |
| { | |
| if (!is_array($arSize)) | |
| $arSize = array(); | |
| if (!array_key_exists("width", $arSize) || intval($arSize["width"]) <= 0) | |
| $arSize["width"] = 0; | |
| if (!array_key_exists("height", $arSize) || intval($arSize["height"]) <= 0) | |
| $arSize["height"] = 0; | |
| $arSize["width"] = intval($arSize["width"]); | |
| $arSize["height"] = intval($arSize["height"]); | |
| $bNeedCreatePicture = false; | |
| $arSourceSize = array("x" => 0, "y" => 0, "width" => 0, "height" => 0); | |
| $arDestinationSize = array("x" => 0, "y" => 0, "width" => 0, "height" => 0); | |
| if ($sourceImageWidth > 0 && $sourceImageHeight > 0) | |
| { | |
| if ($arSize["width"] > 0 && $arSize["height"] > 0) | |
| { | |
| switch ($resizeType) | |
| { | |
| case BX_RESIZE_IMAGE_EXACT: | |
| $bNeedCreatePicture = true; | |
| $ratio = (($sourceImageWidth / $sourceImageHeight) < ($arSize["width"] / $arSize["height"])) ? | |
| $arSize["width"] / $sourceImageWidth : $arSize["height"] / $sourceImageHeight; | |
| $x = max(0, round($sourceImageWidth / 2 - ($arSize["width"] / 2) / $ratio)); | |
| $y = max(0, round($sourceImageHeight / 2 - ($arSize["height"] / 2) / $ratio)); | |
| $arDestinationSize["width"] = $arSize["width"]; | |
| $arDestinationSize["height"] = $arSize["height"]; | |
| $arSourceSize["x"] = $x; | |
| $arSourceSize["y"] = $y; | |
| $arSourceSize["width"] = round($arSize["width"] / $ratio, 0); | |
| $arSourceSize["height"] = round($arSize["height"] / $ratio, 0); | |
| break; | |
| default: | |
| if ($resizeType == BX_RESIZE_IMAGE_PROPORTIONAL_ALT) | |
| { | |
| $width = max($sourceImageWidth, $sourceImageHeight); | |
| $height = min($sourceImageWidth, $sourceImageHeight); | |
| } | |
| else | |
| { | |
| $width = $sourceImageWidth; | |
| $height = $sourceImageHeight; | |
| } | |
| $ResizeCoeff["width"] = $arSize["width"] / $width; | |
| $ResizeCoeff["height"] = $arSize["height"] / $height; | |
| $iResizeCoeff = min($ResizeCoeff["width"], $ResizeCoeff["height"]); | |
| $iResizeCoeff = ((0 < $iResizeCoeff) && ($iResizeCoeff < 1) ? $iResizeCoeff : 1); | |
| $bNeedCreatePicture = ($iResizeCoeff != 1 ? true : false); | |
| $arDestinationSize["width"] = max(1, intval($iResizeCoeff * $sourceImageWidth)); | |
| $arDestinationSize["height"] = max(1, intval($iResizeCoeff * $sourceImageHeight)); | |
| $arSourceSize["x"] = 0; | |
| $arSourceSize["y"] = 0; | |
| $arSourceSize["width"] = $sourceImageWidth; | |
| $arSourceSize["height"] = $sourceImageHeight; | |
| break; | |
| } | |
| } | |
| else | |
| { | |
| $arSourceSize = array("x" => 0, "y" => 0, "width" => $sourceImageWidth, "height" => $sourceImageHeight); | |
| $arDestinationSize = array("x" => 0, "y" => 0, "width" => $sourceImageWidth, "height" => $sourceImageHeight); | |
| } | |
| } | |
| } | |
| public static function IsGD2() | |
| { | |
| static $bGD2 = false; | |
| static $bGD2Initial = false; | |
| if (!$bGD2Initial && function_exists("gd_info")) | |
| { | |
| $arGDInfo = gd_info(); | |
| $bGD2 = ((StrPos($arGDInfo['GD Version'], "2.") !== false) ? true : false); | |
| $bGD2Initial = true; | |
| } | |
| return $bGD2; | |
| } | |
| public static function ResizeImageFile($sourceFile, &$destinationFile, $arSize, $resizeType = BX_RESIZE_IMAGE_PROPORTIONAL, $arWaterMark = array(), $jpgQuality=false, $arFilters=false) | |
| { | |
| $io = CBXVirtualIo::GetInstance(); | |
| if (!$io->FileExists($sourceFile)) | |
| return false; | |
| $bNeedCreatePicture = false; | |
| if ($resizeType !== BX_RESIZE_IMAGE_EXACT && $resizeType !== BX_RESIZE_IMAGE_PROPORTIONAL_ALT) | |
| $resizeType = BX_RESIZE_IMAGE_PROPORTIONAL; | |
| if (!is_array($arSize)) | |
| $arSize = array(); | |
| if (!array_key_exists("width", $arSize) || intval($arSize["width"]) <= 0) | |
| $arSize["width"] = 0; | |
| if (!array_key_exists("height", $arSize) || intval($arSize["height"]) <= 0) | |
| $arSize["height"] = 0; | |
| $arSize["width"] = intval($arSize["width"]); | |
| $arSize["height"] = intval($arSize["height"]); | |
| $arSourceSize = array("x" => 0, "y" => 0, "width" => 0, "height" => 0); | |
| $arDestinationSize = array("x" => 0, "y" => 0, "width" => 0, "height" => 0); | |
| $arSourceFileSizeTmp = CFile::GetImageSize($sourceFile); | |
| if (!in_array($arSourceFileSizeTmp[2], array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_BMP))) | |
| return false; | |
| $orientation = 0; | |
| if($arSourceFileSizeTmp[2] == IMAGETYPE_JPEG) | |
| { | |
| $exifData = CFile::ExtractImageExif($io->GetPhysicalName($sourceFile)); | |
| if ($exifData && isset($exifData['Orientation'])) | |
| { | |
| $orientation = $exifData['Orientation']; | |
| //swap width and height | |
| if ($orientation >= 5 && $orientation <= 8) | |
| { | |
| $tmp = $arSourceFileSizeTmp[1]; | |
| $arSourceFileSizeTmp[1] = $arSourceFileSizeTmp[0]; | |
| $arSourceFileSizeTmp[0] = $tmp; | |
| } | |
| } | |
| } | |
| //Фикс для ресайза на OPEN SERVER | |
| /*$hLock = $io->OpenFile($sourceFile, "r+"); | |
| if ($hLock) | |
| { | |
| flock($hLock, LOCK_EX); | |
| if ($io->FileExists($destinationFile)) | |
| { | |
| CFile::ScaleImage($arSourceFileSizeTmp[0], $arSourceFileSizeTmp[1], $arSize, $resizeType, $bNeedCreatePicture, $arSourceSize, $arDestinationSize); | |
| $arDestinationSizeTmp = CFile::GetImageSize($destinationFile); | |
| if ( | |
| is_array($arDestinationSizeTmp) | |
| && $arDestinationSizeTmp[0] == $arDestinationSize["width"] | |
| && $arDestinationSizeTmp[1] == $arDestinationSize["height"] | |
| ) | |
| { | |
| flock($hLock, LOCK_UN); | |
| fclose($hLock); | |
| return true; | |
| } | |
| } | |
| }*/ | |
| if(CFile::isEnabledTrackingResizeImage()) | |
| { | |
| header("X-Bitrix-Resize-Image: {$arSize["width"]}_{$arSize["height"]}_{$resizeType}"); | |
| } | |
| if (class_exists("imagick") && function_exists('memory_get_usage')) | |
| { | |
| //When memory limit reached we'll try to use ImageMagic | |
| $memoryNeeded = $arSourceFileSizeTmp[0] * $arSourceFileSizeTmp[1] * 4 * 3; | |
| $memoryLimit = CUtil::Unformat(ini_get('memory_limit')); | |
| if ((memory_get_usage() + $memoryNeeded) > $memoryLimit) | |
| { | |
| if ($arSize["width"] <= 0 || $arSize["height"] <= 0) | |
| { | |
| $arSize["width"] = $arSourceFileSizeTmp[0]; | |
| $arSize["height"] = $arSourceFileSizeTmp[1]; | |
| } | |
| CFile::ScaleImage($arSourceFileSizeTmp[0], $arSourceFileSizeTmp[1], $arSize, $resizeType, $bNeedCreatePicture, $arSourceSize, $arDestinationSize); | |
| if ($bNeedCreatePicture) | |
| { | |
| $new_image = CTempFile::GetFileName(bx_basename($sourceFile)); | |
| CheckDirPath($new_image); | |
| $im = new Imagick(); | |
| try | |
| { | |
| $im->setOption('jpeg:size', $arDestinationSize["width"].'x'.$arDestinationSize["height"]); | |
| $im->setSize($arDestinationSize["width"], $arDestinationSize["height"]); | |
| $im->readImage($io->GetPhysicalName($sourceFile)); | |
| $im->setImageFileName($new_image); | |
| $im->thumbnailImage($arDestinationSize["width"], $arDestinationSize["height"], true); | |
| $im->writeImage(); | |
| $im->destroy(); | |
| } | |
| catch (ImagickException $e) | |
| { | |
| $new_image = ""; | |
| } | |
| if($new_image != "") | |
| { | |
| $sourceFile = $new_image; | |
| $arSourceFileSizeTmp = CFile::GetImageSize($io->GetPhysicalName($sourceFile)); | |
| } | |
| } | |
| } | |
| } | |
| if ($io->Copy($sourceFile, $destinationFile)) | |
| { | |
| switch ($arSourceFileSizeTmp[2]) | |
| { | |
| case IMAGETYPE_GIF: | |
| $sourceImage = imagecreatefromgif($io->GetPhysicalName($sourceFile)); | |
| $bHasAlpha = true; | |
| break; | |
| case IMAGETYPE_PNG: | |
| $sourceImage = imagecreatefrompng($io->GetPhysicalName($sourceFile)); | |
| $bHasAlpha = true; | |
| break; | |
| case IMAGETYPE_BMP: | |
| $sourceImage = CFile::ImageCreateFromBMP($io->GetPhysicalName($sourceFile)); | |
| $bHasAlpha = false; | |
| break; | |
| default: | |
| $sourceImage = imagecreatefromjpeg($io->GetPhysicalName($sourceFile)); | |
| if ($sourceImage === false) | |
| { | |
| ini_set('gd.jpeg_ignore_warning', 1); | |
| $sourceImage = imagecreatefromjpeg($io->GetPhysicalName($sourceFile)); | |
| } | |
| if ($orientation > 1) | |
| { | |
| $properlyOriented = CFile::ImageHandleOrientation($orientation, $sourceImage); | |
| if($jpgQuality === false) | |
| $jpgQuality = intval(COption::GetOptionString('main', 'image_resize_quality', '95')); | |
| if($jpgQuality <= 0 || $jpgQuality > 100) | |
| $jpgQuality = 95; | |
| if ($properlyOriented) | |
| { | |
| imagejpeg($properlyOriented, $io->GetPhysicalName($destinationFile), $jpgQuality); | |
| $sourceImage = $properlyOriented; | |
| } | |
| } | |
| $bHasAlpha = false; | |
| break; | |
| } | |
| $sourceImageWidth = intval(imagesx($sourceImage)); | |
| $sourceImageHeight = intval(imagesy($sourceImage)); | |
| if ($sourceImageWidth > 0 && $sourceImageHeight > 0) | |
| { | |
| if ($arSize["width"] <= 0 || $arSize["height"] <= 0) | |
| { | |
| $arSize["width"] = $sourceImageWidth; | |
| $arSize["height"] = $sourceImageHeight; | |
| } | |
| CFile::ScaleImage($sourceImageWidth, $sourceImageHeight, $arSize, $resizeType, $bNeedCreatePicture, $arSourceSize, $arDestinationSize); | |
| if ($bNeedCreatePicture) | |
| { | |
| if (CFile::IsGD2()) | |
| { | |
| $picture = ImageCreateTrueColor($arDestinationSize["width"], $arDestinationSize["height"]); | |
| if($arSourceFileSizeTmp[2] == IMAGETYPE_PNG) | |
| { | |
| $transparentcolor = imagecolorallocatealpha($picture, 0, 0, 0, 127); | |
| imagefilledrectangle($picture, 0, 0, $arDestinationSize["width"], $arDestinationSize["height"], $transparentcolor); | |
| imagealphablending($picture, false); | |
| imagecopyresampled($picture, $sourceImage, | |
| 0, 0, $arSourceSize["x"], $arSourceSize["y"], | |
| $arDestinationSize["width"], $arDestinationSize["height"], $arSourceSize["width"], $arSourceSize["height"]); | |
| imagealphablending($picture, true); | |
| } | |
| elseif($arSourceFileSizeTmp[2] == IMAGETYPE_GIF) | |
| { | |
| imagepalettecopy($picture, $sourceImage); | |
| //Save transparency for GIFs | |
| $transparentcolor = imagecolortransparent($sourceImage); | |
| if($transparentcolor >= 0 && $transparentcolor < imagecolorstotal($sourceImage)) | |
| { | |
| $RGB = imagecolorsforindex($sourceImage, $transparentcolor); | |
| $transparentcolor = imagecolorallocate($picture, $RGB["red"], $RGB["green"], $RGB["blue"]); | |
| imagecolortransparent($picture, $transparentcolor); | |
| imagefilledrectangle($picture, 0, 0, $arDestinationSize["width"], $arDestinationSize["height"], $transparentcolor); | |
| } | |
| imagecopyresampled($picture, $sourceImage, | |
| 0, 0, $arSourceSize["x"], $arSourceSize["y"], | |
| $arDestinationSize["width"], $arDestinationSize["height"], $arSourceSize["width"], $arSourceSize["height"]); | |
| } | |
| else | |
| { | |
| imagecopyresampled($picture, $sourceImage, | |
| 0, 0, $arSourceSize["x"], $arSourceSize["y"], | |
| $arDestinationSize["width"], $arDestinationSize["height"], $arSourceSize["width"], $arSourceSize["height"]); | |
| } | |
| } | |
| else | |
| { | |
| $picture = ImageCreate($arDestinationSize["width"], $arDestinationSize["height"]); | |
| imagecopyresized($picture, $sourceImage, | |
| 0, 0, $arSourceSize["x"], $arSourceSize["y"], | |
| $arDestinationSize["width"], $arDestinationSize["height"], $arSourceSize["width"], $arSourceSize["height"]); | |
| } | |
| } | |
| else | |
| { | |
| $picture = $sourceImage; | |
| } | |
| if(is_array($arFilters)) | |
| { | |
| foreach($arFilters as $arFilter) | |
| $bNeedCreatePicture |= CFile::ApplyImageFilter($picture, $arFilter, $bHasAlpha); | |
| } | |
| if(is_array($arWaterMark)) | |
| { | |
| $arWaterMark["name"] = "watermark"; | |
| $bNeedCreatePicture |= CFile::ApplyImageFilter($picture, $arWaterMark, $bHasAlpha); | |
| } | |
| if ($bNeedCreatePicture) | |
| { | |
| if($io->FileExists($destinationFile)) | |
| $io->Delete($destinationFile); | |
| switch ($arSourceFileSizeTmp[2]) | |
| { | |
| case IMAGETYPE_GIF: | |
| imagegif($picture, $io->GetPhysicalName($destinationFile)); | |
| break; | |
| case IMAGETYPE_PNG: | |
| imagealphablending($picture, false ); | |
| imagesavealpha($picture, true); | |
| imagepng($picture, $io->GetPhysicalName($destinationFile)); | |
| break; | |
| default: | |
| if ($arSourceFileSizeTmp[2] == IMAGETYPE_BMP) | |
| $destinationFile .= ".jpg"; | |
| if($jpgQuality === false) | |
| $jpgQuality = intval(COption::GetOptionString('main', 'image_resize_quality', '95')); | |
| if($jpgQuality <= 0 || $jpgQuality > 100) | |
| $jpgQuality = 95; | |
| imagejpeg($picture, $io->GetPhysicalName($destinationFile), $jpgQuality); | |
| break; | |
| } | |
| imagedestroy($picture); | |
| } | |
| } | |
| if ($hLock) | |
| { | |
| flock($hLock, LOCK_UN); | |
| fclose($hLock); | |
| } | |
| return true; | |
| } | |
| if ($hLock) | |
| { | |
| flock($hLock, LOCK_UN); | |
| fclose($hLock); | |
| } | |
| return false; | |
| } | |
| public static function ApplyImageFilter($picture, $arFilter, $bHasAlpha = true) | |
| { | |
| switch($arFilter["name"]) | |
| { | |
| case "sharpen": | |
| $precision = intval($arFilter["precision"]); | |
| if($precision > 0) | |
| { | |
| $k = 1/$precision; | |
| $mask = array( | |
| array( -$k, -$k, -$k), | |
| array( -$k, 1+8*$k, -$k), | |
| array( -$k, -$k, -$k) | |
| ); | |
| //Probe corners for transparent pixels | |
| $corner = 0; | |
| if ($bHasAlpha) | |
| { | |
| $corner = imagecolorat($picture, 0, 0) >> 24; | |
| if ($corner == 0) | |
| { | |
| $x = imagesx($picture) - 1; | |
| $corner = imagecolorat($picture, $x, 0) >> 24; | |
| } | |
| if ($corner == 0) | |
| { | |
| $y = imagesy($picture) - 1; | |
| $corner = imagecolorat($picture, 0, $y) >> 24; | |
| } | |
| if ($corner == 0) | |
| { | |
| $corner = imagecolorat($picture, $x, $y) >> 24; | |
| } | |
| } | |
| if(!function_exists("imageconvolution") || ($corner > 0)) | |
| CFile::imageconvolution($picture, $mask, 1, 0); | |
| else | |
| CFile::imageconvolution_fix($picture, $mask, 1, 0); | |
| } | |
| return true; //Image was modified | |
| case "watermark": | |
| return CFile::WaterMark($picture, $arFilter); | |
| } | |
| return null; | |
| } | |
| public static function imageconvolution($picture, $matrix, $div = 1, $offset = 0) | |
| { | |
| $sx = imagesx($picture); | |
| $sy = imagesy($picture); | |
| $backup = imagecreatetruecolor($sx, $sy); | |
| imagealphablending($backup, false); | |
| imagecopy($backup, $picture, 0, 0, 0, 0, $sx, $sy); | |
| for($y = 0; $y < $sy; ++$y) | |
| { | |
| for($x = 0; $x < $sx; ++$x) | |
| { | |
| $alpha = (imagecolorat($backup, $x, $y) >> 24) & 0xFF; | |
| $new_r = $new_g = $new_b = 0; | |
| for ($j = 0; $j < 3; ++$j) | |
| { | |
| $yv = $y - 1 + $j; | |
| if($yv < 0) | |
| $yv = 0; | |
| elseif($yv >= $sy) | |
| $yv = $sy - 1; | |
| for ($i = 0; $i < 3; ++$i) | |
| { | |
| $xv = $x - 1 + $i; | |
| if($xv < 0) | |
| $xv = 0; | |
| elseif($xv >= $sx) | |
| $xv = $sx - 1; | |
| $m = $matrix[$j][$i]; | |
| $rgb = imagecolorat($backup, $xv, $yv); | |
| $new_r += (($rgb >> 16) & 0xFF) * $m; | |
| $new_g += (($rgb >> 8) & 0xFF) * $m; | |
| $new_b += ($rgb & 0xFF) * $m; | |
| } | |
| } | |
| $new_r = ($new_r > 255)? 255 : (($new_r < 0)? 0: $new_r); | |
| $new_g = ($new_g > 255)? 255 : (($new_g < 0)? 0: $new_g); | |
| $new_b = ($new_b > 255)? 255 : (($new_b < 0)? 0: $new_b); | |
| $new_pxl = imagecolorallocatealpha($picture, $new_r, $new_g, $new_b, $alpha); | |
| imagesetpixel($picture, $x, $y, $new_pxl); | |
| } | |
| } | |
| imagedestroy($backup); | |
| } | |
| public static function imageconvolution_fix($picture, $matrix, $div = 1, $offset = 0) | |
| { | |
| $x = 0; | |
| $y = 0; | |
| $sx = imagesx($picture); | |
| $sy = imagesy($picture); | |
| $alpha = (imagecolorat($picture, $x, $y) >> 24) & 0xFF; | |
| $new_r = $new_g = $new_b = 0; | |
| for ($j = 0; $j < 3; ++$j) | |
| { | |
| $yv = $y - 1 + $j; | |
| if($yv < 0) | |
| $yv = 0; | |
| elseif($yv >= $sy) | |
| $yv = $sy - 1; | |
| for ($i = 0; $i < 3; ++$i) | |
| { | |
| $xv = $x - 1 + $i; | |
| if($xv < 0) | |
| $xv = 0; | |
| elseif($xv >= $sx) | |
| $xv = $sx - 1; | |
| $m = $matrix[$j][$i]; | |
| $rgb = imagecolorat($picture, $xv, $yv); | |
| $new_r += (($rgb >> 16) & 0xFF) * $m; | |
| $new_g += (($rgb >> 8) & 0xFF) * $m; | |
| $new_b += ($rgb & 0xFF) * $m; | |
| } | |
| } | |
| $new_r = ($new_r > 255)? 255 : (($new_r < 0)? 0: $new_r); | |
| $new_g = ($new_g > 255)? 255 : (($new_g < 0)? 0: $new_g); | |
| $new_b = ($new_b > 255)? 255 : (($new_b < 0)? 0: $new_b); | |
| $new_pxl = imagecolorallocatealpha($picture, $new_r, $new_g, $new_b, $alpha); | |
| imageconvolution($picture, $matrix, $div, $offset); | |
| //Fix left top corner | |
| imagealphablending($picture, false); | |
| imagesetpixel($picture, $x, $y, $new_pxl); | |
| } | |
| public static function ImageFlipHorizontal($picture) | |
| { | |
| if (function_exists('imageflip')) | |
| { | |
| imageflip($picture, IMG_FLIP_HORIZONTAL); | |
| } | |
| else | |
| { | |
| $sy = imagesy($picture); | |
| $sx = imagesx($picture); | |
| for ($y = 0; $y < $sy; $y++) | |
| { | |
| for ($x = 0; $x < ($sx / 2); $x++) | |
| { | |
| $px1 = imagecolorat($picture, $x, $y); | |
| $px2 = imagecolorat($picture, $sx - $x, $y); | |
| imagesetpixel($picture, $x, $y, $px2); | |
| imagesetpixel($picture, $sx - $x, $y, $px1); | |
| } | |
| } | |
| } | |
| } | |
| public static function ImageHandleOrientation($orientation, $sourceImage) | |
| { | |
| if ($orientation <= 1) | |
| { | |
| return false; | |
| } | |
| if (!is_resource($sourceImage)) | |
| { | |
| if (class_exists("imagick")) | |
| { | |
| $im = new Imagick(); | |
| try | |
| { | |
| $im->readImage($sourceImage); | |
| if ($orientation == 7 || $orientation == 8) | |
| $sourceImage = $im->rotateImage(new ImagickPixel('#00000000'), 270); | |
| elseif ($orientation == 3 || $orientation == 4) | |
| $sourceImage = $im->rotateImage(new ImagickPixel('#00000000'), 180); | |
| elseif ($orientation == 5 || $orientation == 6) | |
| $sourceImage = $im->rotateImage(new ImagickPixel('#00000000'), 90); | |
| if ( | |
| $orientation == 2 || $orientation == 7 | |
| || $orientation == 4 || $orientation == 5 | |
| ) | |
| { | |
| $im->flopImage(); | |
| } | |
| $im->setImageOrientation(0); | |
| $im->writeImage(); | |
| $im->destroy(); | |
| clearstatcache(true, $sourceImage); | |
| return false; | |
| } | |
| catch (ImagickException $e) | |
| { | |
| } | |
| } | |
| $imgArray = CFile::GetImageSize($sourceImage, true, false); | |
| if(is_array($imgArray) && $imgArray[2] == IMAGETYPE_JPEG) | |
| { | |
| $sourceImage = imagecreatefromjpeg($sourceImage); | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| } | |
| if ($orientation == 7 || $orientation == 8) | |
| $sourceImage = imagerotate($sourceImage, 90, null); | |
| elseif ($orientation == 3 || $orientation == 4) | |
| $sourceImage = imagerotate($sourceImage, 180, null); | |
| elseif ($orientation == 5 || $orientation == 6) | |
| $sourceImage = imagerotate($sourceImage, 270, null); | |
| if ( | |
| $orientation == 2 || $orientation == 7 | |
| || $orientation == 4 || $orientation == 5 | |
| ) | |
| { | |
| CFile::ImageFlipHorizontal($sourceImage); | |
| } | |
| return $sourceImage; | |
| } | |
| /** | |
| * @param int|array $arFile | |
| * @param array $arOptions | |
| */ | |
| public static function ViewByUser($arFile, $arOptions = array()) | |
| { | |
| $previewManager = new Viewer\PreviewManager(); | |
| if ($previewManager->isInternalRequest($arFile, $arOptions)) | |
| { | |
| $previewManager->processViewByUserRequest($arFile, $arOptions); | |
| } | |
| /** @global CMain $APPLICATION */ | |
| global $APPLICATION; | |
| $fastDownload = (COption::GetOptionString('main', 'bx_fast_download', 'N') == 'Y'); | |
| $attachment_name = ""; | |
| $content_type = ""; | |
| $specialchars = false; | |
| $force_download = false; | |
| $cache_time = 10800; | |
| $fromClouds = false; | |
| $filename = ''; | |
| $fileWithinDocumentRoot = true; | |
| if(is_array($arOptions)) | |
| { | |
| if(isset($arOptions["content_type"])) | |
| $content_type = $arOptions["content_type"]; | |
| if(isset($arOptions["specialchars"])) | |
| $specialchars = $arOptions["specialchars"]; | |
| if(isset($arOptions["force_download"])) | |
| $force_download = $arOptions["force_download"]; | |
| if(isset($arOptions["cache_time"])) | |
| $cache_time = intval($arOptions["cache_time"]); | |
| if(isset($arOptions["attachment_name"])) | |
| $attachment_name = $arOptions["attachment_name"]; | |
| if(isset($arOptions["fast_download"])) | |
| $fastDownload = (bool)$arOptions["fast_download"]; | |
| } | |
| if($cache_time < 0) | |
| $cache_time = 0; | |
| if(is_array($arFile)) | |
| { | |
| if(isset($arFile["SRC"])) | |
| { | |
| $filename = $arFile["SRC"]; | |
| } | |
| elseif(isset($arFile["tmp_name"])) | |
| { | |
| if (strpos($arFile['tmp_name'], $_SERVER['DOCUMENT_ROOT']) === 0) | |
| { | |
| $filename = '/'. ltrim(substr($arFile['tmp_name'], strlen($_SERVER['DOCUMENT_ROOT'])), '/'); | |
| } | |
| elseif (defined('BX_TEMPORARY_FILES_DIRECTORY') && strpos($arFile['tmp_name'], BX_TEMPORARY_FILES_DIRECTORY) === 0) | |
| { | |
| $fileWithinDocumentRoot = false; | |
| $filename = '/'. $arFile['name']; //nonexistent path | |
| } | |
| } | |
| else | |
| { | |
| $filename = static::GetFileSRC($arFile); | |
| } | |
| } | |
| elseif (($arFile = static::GetFileArray($arFile))) | |
| { | |
| $filename = $arFile['SRC']; | |
| } | |
| if ($filename == '') | |
| { | |
| return false; | |
| } | |
| if($content_type == '' && isset($arFile["CONTENT_TYPE"])) | |
| { | |
| $content_type = $arFile["CONTENT_TYPE"]; | |
| } | |
| //we produce resized jpg for original bmp | |
| if($content_type == '' || $content_type == "image/bmp") | |
| { | |
| if(isset($arFile["tmp_name"])) | |
| { | |
| $content_type = static::GetContentType($arFile["tmp_name"], true); | |
| } | |
| else | |
| { | |
| $content_type = static::GetContentType($_SERVER["DOCUMENT_ROOT"].$filename); | |
| } | |
| } | |
| if($arFile["ORIGINAL_NAME"] <> '') | |
| $name = $arFile["ORIGINAL_NAME"]; | |
| elseif($arFile["name"] <> '') | |
| $name = $arFile["name"]; | |
| else | |
| $name = $arFile["FILE_NAME"]; | |
| if(isset($arFile["EXTENSION_SUFFIX"]) && $arFile["EXTENSION_SUFFIX"] <> '') | |
| $name = substr($name, 0, -strlen($arFile["EXTENSION_SUFFIX"])); | |
| $name = str_replace(array("\n", "\r"), '', $name); | |
| if($attachment_name) | |
| $attachment_name = str_replace(array("\n", "\r"), '', $attachment_name); | |
| else | |
| $attachment_name = $name; | |
| if(!$force_download) | |
| { | |
| if(!static::IsImage($name, $content_type) || $arFile["HEIGHT"] <= 0 || $arFile["WIDTH"] <= 0) | |
| { | |
| //only valid images can be downloaded inline | |
| $force_download = true; | |
| } | |
| } | |
| $content_type = static::NormalizeContentType($content_type); | |
| if($force_download) | |
| { | |
| $specialchars = false; | |
| } | |
| $src = null; | |
| $file = null; | |
| if ((substr($filename, 0, 1) == '/') && $fileWithinDocumentRoot) | |
| { | |
| $file = new IO\File($_SERVER['DOCUMENT_ROOT']. $filename); | |
| } | |
| elseif (isset($arFile['tmp_name'])) | |
| { | |
| $file = new IO\File($arFile['tmp_name']); | |
| } | |
| if ((substr($filename, 0, 1) == '/') && ($file instanceof IO\File)) | |
| { | |
| try | |
| { | |
| $src = $file->open(IO\FileStreamOpenMode::READ); | |
| } | |
| catch(IO\IoException $e) | |
| { | |
| return false; | |
| } | |
| } | |
| else | |
| { | |
| if(!$fastDownload) | |
| { | |
| $src = new \Bitrix\Main\Web\HttpClient(); | |
| } | |
| elseif(intval($arFile['HANDLER_ID']) > 0) | |
| { | |
| $fromClouds = true; | |
| } | |
| } | |
| $APPLICATION->RestartBuffer(); | |
| while(ob_end_clean()); | |
| $cur_pos = 0; | |
| $filesize = ($arFile["FILE_SIZE"] > 0? $arFile["FILE_SIZE"] : $arFile["size"]); | |
| $size = $filesize-1; | |
| $p = strpos($_SERVER["HTTP_RANGE"], "="); | |
| if(intval($p)>0) | |
| { | |
| $bytes = substr($_SERVER["HTTP_RANGE"], $p+1); | |
| $p = strpos($bytes, "-"); | |
| if($p !== false) | |
| { | |
| $cur_pos = floatval(substr($bytes, 0, $p)); | |
| $size = floatval(substr($bytes, $p+1)); | |
| if ($size <= 0) | |
| { | |
| $size = $filesize - 1; | |
| } | |
| if ($cur_pos > $size) | |
| { | |
| $cur_pos = 0; | |
| $size = $filesize - 1; | |
| } | |
| } | |
| } | |
| if ($file instanceof IO\File) | |
| { | |
| $filetime = $file->getModificationTime(); | |
| } | |
| elseif($arFile["tmp_name"] <> '') | |
| { | |
| $tmpFile = new IO\File($arFile["tmp_name"]); | |
| $filetime = $tmpFile->getModificationTime(); | |
| } | |
| else | |
| { | |
| $filetime = intval(MakeTimeStamp($arFile["TIMESTAMP_X"])); | |
| } | |
| if($_SERVER["REQUEST_METHOD"] == "HEAD") | |
| { | |
| CHTTP::SetStatus("200 OK"); | |
| header("Accept-Ranges: bytes"); | |
| header("Content-Type: ".$content_type); | |
| header("Content-Length: ".($size-$cur_pos+1)); | |
| if($filetime > 0) | |
| header("Last-Modified: ".date("r", $filetime)); | |
| } | |
| else | |
| { | |
| $lastModified = ''; | |
| if($cache_time > 0) | |
| { | |
| //Handle ETag | |
| $ETag = md5($filename.$filesize.$filetime); | |
| if(array_key_exists("HTTP_IF_NONE_MATCH", $_SERVER) && ($_SERVER['HTTP_IF_NONE_MATCH'] === $ETag)) | |
| { | |
| CHTTP::SetStatus("304 Not Modified"); | |
| header("Cache-Control: private, max-age=".$cache_time.", pre-check=".$cache_time); | |
| die(); | |
| } | |
| header("ETag: ".$ETag); | |
| //Handle Last Modified | |
| if($filetime > 0) | |
| { | |
| $lastModified = gmdate('D, d M Y H:i:s', $filetime).' GMT'; | |
| if(array_key_exists("HTTP_IF_MODIFIED_SINCE", $_SERVER) && ($_SERVER['HTTP_IF_MODIFIED_SINCE'] === $lastModified)) | |
| { | |
| CHTTP::SetStatus("304 Not Modified"); | |
| header("Cache-Control: private, max-age=".$cache_time.", pre-check=".$cache_time); | |
| die(); | |
| } | |
| } | |
| } | |
| $utfName = CHTTP::urnEncode($attachment_name, "UTF-8"); | |
| $translitName = CUtil::translit($attachment_name, LANGUAGE_ID, array( | |
| "max_len" => 1024, | |
| "safe_chars" => ".", | |
| "replace_space" => '-', | |
| "change_case" => false, | |
| )); | |
| if($force_download) | |
| { | |
| //Disable zlib for old versions of php <= 5.3.0 | |
| //it has broken Content-Length handling | |
| if(ini_get('zlib.output_compression')) | |
| ini_set('zlib.output_compression', 'Off'); | |
| if($cur_pos > 0) | |
| CHTTP::SetStatus("206 Partial Content"); | |
| else | |
| CHTTP::SetStatus("200 OK"); | |
| header("Content-Type: ".$content_type); | |
| header("Content-Disposition: attachment; filename=\"".$translitName."\"; filename*=utf-8''".$utfName); | |
| header("Content-Transfer-Encoding: binary"); | |
| header("Content-Length: ".($size-$cur_pos+1)); | |
| if(is_resource($src)) | |
| { | |
| header("Accept-Ranges: bytes"); | |
| header("Content-Range: bytes ".$cur_pos."-".$size."/".$filesize); | |
| } | |
| } | |
| else | |
| { | |
| header("Content-Type: ".$content_type); | |
| header("Content-Disposition: inline; filename=\"".$translitName."\"; filename*=utf-8''".$utfName); | |
| } | |
| if($cache_time > 0) | |
| { | |
| header("Cache-Control: private, max-age=".$cache_time.", pre-check=".$cache_time); | |
| if($filetime > 0) | |
| header('Last-Modified: '.$lastModified); | |
| } | |
| else | |
| { | |
| header("Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0"); | |
| } | |
| header("Expires: 0"); | |
| header("Pragma: public"); | |
| // Download from front-end | |
| if($fastDownload) | |
| { | |
| if($fromClouds) | |
| { | |
| $filename = preg_replace('~^(http[s]?)(\://)~i', '\\1.' , $filename); | |
| $cloudUploadPath = COption::GetOptionString('main', 'bx_cloud_upload', '/upload/bx_cloud_upload/'); | |
| header('X-Accel-Redirect: '.$cloudUploadPath.$filename); | |
| } | |
| else | |
| { | |
| $filename = CHTTP::urnEncode($filename, "UTF-8"); | |
| header('X-Accel-Redirect: '.$filename); | |
| } | |
| } | |
| else | |
| { | |
| session_write_close(); | |
| if ($specialchars) | |
| { | |
| /** @var IO\File $file */ | |
| echo "<", "pre" ,">"; | |
| if(is_resource($src)) | |
| { | |
| while(!feof($src)) | |
| echo htmlspecialcharsbx(fread($src, 32768)); | |
| $file->close(); | |
| } | |
| else | |
| { | |
| /** @var \Bitrix\Main\Web\HttpClient $src */ | |
| echo htmlspecialcharsbx($src->get($filename)); | |
| } | |
| echo "<", "/pre", ">"; | |
| } | |
| else | |
| { | |
| if(is_resource($src)) | |
| { | |
| /** @var IO\File $file */ | |
| $file->seek($cur_pos); | |
| while(!feof($src) && ($cur_pos <= $size)) | |
| { | |
| $bufsize = 131072; //128K | |
| if($cur_pos + $bufsize > $size) | |
| $bufsize = $size - $cur_pos + 1; | |
| $cur_pos += $bufsize; | |
| echo fread($src, $bufsize); | |
| } | |
| $file->close(); | |
| } | |
| else | |
| { | |
| $fp = fopen("php://output", "wb"); | |
| /** @var \Bitrix\Main\Web\HttpClient $src */ | |
| $src->setOutputStream($fp); | |
| $src->get($filename); | |
| } | |
| } | |
| \CMain::runFinalActionsInternal(); | |
| die(); | |
| } | |
| } | |
| CMain::FinalActions(); | |
| die(); | |
| } | |
| // Params: | |
| // type - text|image | |
| // size - big|medium|small|real, for custom resizing can be used 'coefficient', real - only for images | |
| // position - of the watermark on picture can be in one of two available notifications: | |
| // tl|tc|tr|ml|mc|mr|bl|bc|br or topleft|topcenter|topright|centerleft|center|centerright|bottomleft|bottomcenter|bottomright | |
| public static function Watermark(&$obj, $Params) | |
| { | |
| // Image sizes | |
| $Params["width"] = intval(@imagesx($obj)); | |
| $Params["height"] = intval(@imagesy($obj)); | |
| // Handle position param | |
| $Params["position"] = strtolower(trim($Params["position"])); | |
| $arPositions = array("topleft", "topcenter", "topright", "centerleft", "center", "centerright", "bottomleft", "bottomcenter", "bottomright"); | |
| $arPositions2 = array("tl", "tc", "tr", "ml", "mc", "mr", "bl", "bc", "br"); | |
| $position = array('x' => 'right','y' => 'bottom'); // Default position | |
| if (in_array($Params["position"], $arPositions2)) | |
| $Params["position"] = str_replace($arPositions2, $arPositions, $Params["position"]); | |
| if (in_array($Params["position"], $arPositions)) | |
| { | |
| foreach(array('top', 'center', 'bottom') as $k) | |
| { | |
| $l = strlen($k); | |
| if (substr($Params["position"], 0, $l) == $k) | |
| { | |
| $position['y'] = $k; | |
| $position['x'] = substr($Params["position"], $l); | |
| if ($position['x'] == '') | |
| $position['x'] = ($k == 'center') ? 'center' : 'right'; | |
| } | |
| } | |
| } | |
| $Params["position"] = $position; | |
| // Text | |
| if ($Params['type'] == 'text') | |
| { | |
| if (intval($Params["coefficient"]) <= 0) | |
| { | |
| if ($Params["size"] == "big") | |
| $Params["coefficient"] = 7; | |
| elseif ($Params["size"] == "small") | |
| $Params["coefficient"] = 2; | |
| else | |
| $Params["coefficient"] = 4; | |
| } | |
| if (!$Params["coefficient"]) | |
| $Params["coefficient"] = 1; | |
| $result = CFile::WatermarkText($obj, $Params); | |
| } | |
| else // Image | |
| { | |
| if($Params["fill"] != 'repeat') | |
| { | |
| if($Params["size"] == "real") | |
| { | |
| $Params["fill"] = 'exact'; | |
| $Params["coefficient"] = 1; | |
| } | |
| else | |
| { | |
| $Params["fill"] = 'resize'; | |
| if (floatval($Params["coefficient"]) <= 0) | |
| { | |
| if ($Params["size"] == "big") | |
| $Params["coefficient"] = 0.75; | |
| elseif ($Params["size"] == "small") | |
| $Params["coefficient"] = 0.20; | |
| else | |
| $Params["coefficient"] = 0.5; | |
| } | |
| } | |
| } | |
| $result = CFile::WatermarkImage($obj, $Params); | |
| }; | |
| return $result; | |
| } | |
| public static function WatermarkText(&$obj, $Params = array()) | |
| { | |
| /** @global CMain $APPLICATION */ | |
| global $APPLICATION; | |
| $text = $Params['text']; | |
| $font = $Params['font']; | |
| $color = $Params['color']; | |
| if (!$obj || empty($text) || !file_exists($font) || !function_exists("gd_info")) | |
| return false; | |
| $Params["coefficient"] = intval($Params["coefficient"]); | |
| $Params["width"] = intval(@imagesx($obj)); | |
| $Params["height"] = intval(@imagesy($obj)); | |
| // Color | |
| $color = preg_replace("/[^a-z0-9]/is", "", trim($color)); | |
| if (strlen($color) != 6) | |
| $color = "FF0000"; | |
| $arColor = array("red" => hexdec(substr($color, 0, 2)), "green" => hexdec(substr($color, 2, 2)), "blue" => hexdec(substr($color, 4, 2))); | |
| if (CFile::IsGD2() && $Params["text_width"] > 0) | |
| { | |
| $textBox = imagettfbbox(20, 0, $font, $text); | |
| $scale = $Params["text_width"] / ($textBox[2] - $textBox[0]); | |
| $iSize = 20 * $scale; | |
| $wm_pos = array( | |
| "x" => 1, // Left | |
| "y" => $iSize + 5, // Top | |
| "width" => $Params["text_width"], | |
| "height" => ($textBox[0] - $textBox[7]) * $scale, | |
| ); | |
| } | |
| else | |
| { | |
| $iSize = $Params["width"] * $Params["coefficient"] / 100; | |
| if ($iSize * strlen($text) * 0.7 > $Params["width"]) | |
| $iSize = intval($Params["width"] / (strlen($text) * 0.7)); | |
| $wm_pos = array( | |
| "x" => 5, // Left | |
| "y" => $iSize + 5, // Top | |
| "width" => (strlen($text) * 0.7 + 1) * $iSize, | |
| "height" => $iSize | |
| ); | |
| } | |
| if (!CFile::IsGD2()) | |
| { | |
| $wm_pos["width"] = strlen($text) * imagefontwidth(5); | |
| $wm_pos["height"] = imagefontheight(5); | |
| } | |
| if ($Params["position"]['y'] == 'center') | |
| $wm_pos["y"] = intval(($Params["height"] - $wm_pos["height"]) / 2); | |
| elseif($Params["position"]['y'] == 'bottom') | |
| $wm_pos["y"] = intval(($Params["height"] - $wm_pos["height"])); | |
| if ($Params["position"]['x'] == 'center') | |
| $wm_pos["x"] = intval(($Params["width"] - $wm_pos["width"]) / 2); | |
| elseif ($Params["position"]['x'] == 'right') | |
| $wm_pos["x"] = intval(($Params["width"] - $wm_pos["width"])); | |
| if ($wm_pos["y"] < 2) | |
| $wm_pos["y"] = 2; | |
| if ($wm_pos["x"] < 2) | |
| $wm_pos["x"] = 2; | |
| $text_color = imagecolorallocate($obj, $arColor["red"], $arColor["green"], $arColor["blue"]); | |
| if (CFile::IsGD2()) | |
| { | |
| $text = $APPLICATION->ConvertCharset($text, SITE_CHARSET, "UTF-8"); | |
| if ($Params["use_copyright"] == "Y") | |
| $text = chr(169)." ".$text; | |
| $result = @imagettftext($obj, $iSize, 0, $wm_pos["x"], $wm_pos["y"], $text_color, $font, $text); | |
| } | |
| else | |
| { | |
| $result = @imagestring($obj, 3, $wm_pos["x"], $wm_pos["y"], $text, $text_color); | |
| } | |
| return $result; | |
| } | |
| // Create watermark from image | |
| // $Params: | |
| // file - abs path to file | |
| // alpha_level - opacity | |
| // position - of the watermark | |
| public static function WatermarkImage(&$obj, $Params = array()) | |
| { | |
| $file = $Params['file']; | |
| if (!$obj || empty($file) || !file_exists($file) || !is_file($file) || !function_exists("gd_info")) | |
| return false; | |
| $arFile = array("ext" => GetFileExtension($file)); | |
| $Params["width"] = intval(@imagesx($obj)); | |
| $Params["height"] = intval(@imagesy($obj)); | |
| if (!isset($Params["alpha_level"])) | |
| $Params["alpha_level"] = 100; | |
| $Params["alpha_level"] = intval($Params["alpha_level"]) / 100; | |
| $arFileSizeTmp = CFile::GetImageSize($file); | |
| if (!in_array($arFileSizeTmp[2], array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_BMP))) | |
| return false; | |
| if ($Params["fill"] == 'resize') | |
| { | |
| $Params["coefficient"] = floatval($Params["coefficient"]); | |
| $wmWidth = round($Params["width"] * $Params["coefficient"]); | |
| $wmHeight = round($Params["height"] * $Params["coefficient"]); | |
| $file_obj_1 = CFile::CreateImage($file, $arFileSizeTmp[2]); | |
| $arFile["width"] = intval(imagesx($file_obj_1)); | |
| $arFile["height"] = intval(imagesy($file_obj_1)); | |
| if ($arFile["width"] > $wmWidth || $arFile["height"] > $wmHeight) | |
| { | |
| $file_1 = $file.'_new.tmp'; | |
| CFile::ResizeImageFile($file, $file_1, array('width' => $wmWidth, 'height' => $wmHeight)); | |
| $file_obj = CFile::CreateImage($file_1, $arFileSizeTmp[2]); | |
| @imagedestroy($file_obj_1); | |
| } | |
| else | |
| { | |
| $file_obj = $file_obj_1; | |
| } | |
| } | |
| else | |
| { | |
| $file_obj = CFile::CreateImage($file, $arFileSizeTmp[2]); | |
| if ($Params["fill"] == 'repeat') | |
| $Params["position"] = array('x' => 'top', 'y' => 'left'); | |
| } | |
| if (!$file_obj) | |
| return false; | |
| $arFile["width"] = intval(@imagesx($file_obj)); | |
| $arFile["height"] = intval(@imagesy($file_obj)); | |
| $wm_pos = array( | |
| "x" => 0, // Left | |
| "y" => 0, // Top | |
| "width" => $arFile["width"], | |
| "height" => $arFile["height"] | |
| ); | |
| if ($Params["position"]['y'] == 'center') | |
| $wm_pos["y"] = intval(($Params["height"] - $wm_pos["height"]) / 2); | |
| elseif($Params["position"]['y'] == 'bottom') | |
| $wm_pos["y"] = intval(($Params["height"] - $wm_pos["height"])); | |
| if ($Params["position"]['x'] == 'center') | |
| $wm_pos["x"] = intval(($Params["width"] - $wm_pos["width"]) / 2); | |
| elseif ($Params["position"]['x'] == 'right') | |
| $wm_pos["x"] = intval(($Params["width"] - $wm_pos["width"])); | |
| if ($wm_pos["y"] < 0) | |
| $wm_pos["y"] = 0; | |
| if ($wm_pos["x"] < 0) | |
| $wm_pos["x"] = 0; | |
| for ($y = 0; $y < $arFile["height"]; $y++ ) | |
| { | |
| for ($x = 0; $x < $arFile["width"]; $x++ ) | |
| { | |
| $watermark_y = $wm_pos["y"] + $y; | |
| while (true) | |
| { | |
| $watermark_x = $wm_pos["x"] + $x; | |
| while (true) | |
| { | |
| $return_color = NULL; | |
| $watermark_alpha = $Params["alpha_level"]; | |
| $main_rgb = imagecolorsforindex($obj, imagecolorat($obj, $watermark_x, $watermark_y)); | |
| $watermark_rbg = imagecolorsforindex($file_obj, imagecolorat($file_obj, $x, $y)); | |
| if ($watermark_rbg['alpha'] == 127) | |
| { | |
| $res = $main_rgb; | |
| } | |
| else | |
| { | |
| if ($watermark_rbg['alpha']) | |
| { | |
| $watermark_alpha = round((( 127 - $watermark_rbg['alpha']) / 127), 2); | |
| $watermark_alpha = $watermark_alpha * $Params["alpha_level"]; | |
| } | |
| $res = array(); | |
| foreach(array('red', 'green', 'blue', 'alpha') as $k) | |
| $res[$k] = round(($main_rgb[$k] * (1 - $watermark_alpha)) + ($watermark_rbg[$k] * $watermark_alpha)); | |
| } | |
| $return_color = imagecolorexactalpha($obj, $res["red"], $res["green"], $res["blue"], $res["alpha"]); | |
| if ($return_color == -1) | |
| { | |
| $return_color = imagecolorallocatealpha($obj, $res["red"], $res["green"], $res["blue"], $res["alpha"]); | |
| if ($return_color === false) | |
| $return_color = imagecolorclosestalpha($obj, $res["red"], $res["green"], $res["blue"], $res["alpha"]); | |
| } | |
| imagesetpixel($obj, $watermark_x, $watermark_y, $return_color); | |
| $watermark_x += $arFile["width"]; | |
| if ($Params["fill"] != 'repeat' || $watermark_x > $Params["width"]) | |
| break; | |
| } | |
| $watermark_y += $arFile["height"]; | |
| if ($Params["fill"] != 'repeat' || $watermark_y > $Params["height"]) | |
| break; | |
| } | |
| } | |
| } | |
| @imagedestroy($file_obj); | |
| return true; | |
| } | |
| public static function ImageRotate($sourceFile, $angle) | |
| { | |
| if (!file_exists($sourceFile) || !is_file($sourceFile)) | |
| return false; | |
| if (!CFile::IsGD2()) | |
| return false; | |
| $angle = 360 - $angle; | |
| $arSourceFileSizeTmp = CFile::GetImageSize($sourceFile); | |
| if (!in_array($arSourceFileSizeTmp[2], array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_BMP))) | |
| return false; | |
| $sourceImage = CFile::CreateImage($sourceFile, $arSourceFileSizeTmp[2]); | |
| // Rotate image | |
| $sourceImage = imagerotate($sourceImage, $angle, 0); | |
| // Delete old file | |
| unlink($sourceFile); | |
| switch ($arSourceFileSizeTmp[2]) | |
| { | |
| case IMAGETYPE_GIF: | |
| imagegif($sourceImage, $sourceFile); | |
| break; | |
| case IMAGETYPE_PNG: | |
| imagealphablending($sourceImage, false ); | |
| imagesavealpha($sourceImage, true); | |
| imagepng($sourceImage, $sourceFile); | |
| break; | |
| default: | |
| if ($arSourceFileSizeTmp[2] == IMAGETYPE_BMP) | |
| $sourceFile .= ".jpg"; | |
| $jpgQuality = intval(COption::GetOptionString('main', 'image_resize_quality', '100')); | |
| if($jpgQuality <= 0 || $jpgQuality > 100) | |
| $jpgQuality = 100; | |
| imagejpeg($sourceImage, $sourceFile, $jpgQuality); | |
| break; | |
| } | |
| imagedestroy($sourceImage); | |
| return true; | |
| } | |
| public static function CreateImage($path, $type = false) | |
| { | |
| $sourceImage = false; | |
| if ($type === false) | |
| { | |
| $arSourceFileSizeTmp = CFile::GetImageSize($path); | |
| $type = $arSourceFileSizeTmp[2]; | |
| } | |
| if (in_array($type, array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_BMP))) | |
| { | |
| switch ($type) | |
| { | |
| case IMAGETYPE_GIF: | |
| $sourceImage = imagecreatefromgif($path); | |
| break; | |
| case IMAGETYPE_PNG: | |
| $sourceImage = imagecreatefrompng($path); | |
| break; | |
| case IMAGETYPE_BMP: | |
| $sourceImage = CFile::ImageCreateFromBMP($path); | |
| break; | |
| default: | |
| $sourceImage = imagecreatefromjpeg($path); | |
| break; | |
| } | |
| } | |
| return $sourceImage; | |
| } | |
| public static function ExtractImageExif($src) | |
| { | |
| /** @global CMain $APPLICATION */ | |
| global $APPLICATION; | |
| $arr = array(); | |
| if (function_exists("exif_read_data")) | |
| { | |
| if($arr = @exif_read_data($src)) | |
| { | |
| foreach ($arr as $k => $val) | |
| if (is_string($val) && $val != '') | |
| $arr[strtolower($k)] = $APPLICATION->ConvertCharset($val, ini_get('exif.encode_unicode'), SITE_CHARSET); | |
| } | |
| } | |
| elseif (class_exists("imagick")) | |
| { | |
| $im = new Imagick(); | |
| try | |
| { | |
| $im->readImage($src); | |
| $arr['Orientation'] = $im->getImageOrientation(); | |
| $im->destroy(); | |
| } | |
| catch (ImagickException $e) | |
| { | |
| $new_image = ""; | |
| } | |
| } | |
| return $arr; | |
| } | |
| public static function ExtractImageIPTC($src) | |
| { | |
| /* Not implemented yet | |
| $arr = array(); | |
| if (isset($info["APP13"])) | |
| { | |
| if($iptc = iptcparse($info["APP13"])) | |
| { | |
| $arr['caption'] = $iptc["2#120"][0]; | |
| $arr['graphic_name'] = $iptc["2#005"][0]; | |
| $arr['urgency'] = $iptc["2#010"][0]; | |
| $arr['category'] = $iptc["2#015"][0]; | |
| $arr['supp_categories'] = $iptc["2#020"][0]; | |
| $arr['spec_instr'] = $iptc["2#040"][0]; | |
| $arr['creation_date'] = $iptc["2#055"][0]; | |
| $arr['photog'] = $iptc["2#080"][0]; | |
| $arr['credit_byline_title'] = $iptc["2#085"][0]; | |
| $arr['city'] = $iptc["2#090"][0]; | |
| $arr['state'] = $iptc["2#095"][0]; | |
| $arr['country'] = $iptc["2#101"][0]; | |
| $arr['otr'] = $iptc["2#103"][0]; | |
| $arr['headline'] = $iptc["2#105"][0]; | |
| $arr['source'] = $iptc["2#110"][0]; | |
| $arr['photo_source'] = $iptc["2#115"][0]; | |
| $arr['caption'] = str_replace("\000", "", $arr['caption']); | |
| if(isset($iptc["1#090"]) && $iptc["1#090"][0] == "\x1B%G") | |
| $arr['caption'] = utf8_decode($arr['caption']); | |
| } | |
| } | |
| return $arr; | |
| */ | |
| } | |
| public static function NormalizeContentType($contentType) | |
| { | |
| $ct = strtolower($contentType); | |
| $ct = str_replace(array("\r", "\n", "\0"), "", $ct); | |
| if (strpos($ct, "excel") !== false) | |
| { | |
| $ct = "application/vnd.ms-excel"; | |
| } | |
| elseif (strpos($ct, "word") !== false && strpos($ct, "vnd.openxmlformats") === false) | |
| { | |
| $ct = "application/msword"; | |
| } | |
| return $ct; | |
| } | |
| public static function GetContentType($path, $bPhysicalName = false) | |
| { | |
| if($bPhysicalName) | |
| { | |
| $pathX = $path; | |
| } | |
| else | |
| { | |
| $io = CBXVirtualIo::GetInstance(); | |
| $pathX = $io->GetPhysicalName($path); | |
| } | |
| if (function_exists("mime_content_type")) | |
| $type = mime_content_type($pathX); | |
| else | |
| $type = ""; | |
| if ($type == "" && function_exists("image_type_to_mime_type")) | |
| { | |
| $arTmp = CFile::GetImageSize($pathX, true); | |
| $type = $arTmp["mime"]; | |
| } | |
| if ($type == "") | |
| { | |
| static $arTypes = array( | |
| "jpeg" => "image/jpeg", | |
| "jpe" => "image/jpeg", | |
| "jpg" => "image/jpeg", | |
| "png" => "image/png", | |
| "gif" => "image/gif", | |
| "bmp" => "image/bmp", | |
| "xla" => "application/vnd.ms-excel", | |
| "xlb" => "application/vnd.ms-excel", | |
| "xlc" => "application/vnd.ms-excel", | |
| "xll" => "application/vnd.ms-excel", | |
| "xlm" => "application/vnd.ms-excel", | |
| "xls" => "application/vnd.ms-excel", | |
| "xlsx" => "application/vnd.ms-excel", | |
| "xlt" => "application/vnd.ms-excel", | |
| "xlw" => "application/vnd.ms-excel", | |
| "dbf" => "application/vnd.ms-excel", | |
| "csv" => "application/vnd.ms-excel", | |
| "doc" => "application/msword", | |
| "docx" => "application/msword", | |
| "dot" => "application/msword", | |
| "rtf" => "application/msword", | |
| "rar" => "application/x-rar-compressed", | |
| "zip" => "application/zip", | |
| "pdf" => "application/pdf", | |
| "ogv" => "video/ogg", | |
| "mp4" => "video/mp4", | |
| "mp4v" => "video/mp4", | |
| "mpg4" => "video/mp4", | |
| "mpeg" => "video/mpeg", | |
| "mpg" => "video/mpeg", | |
| "mpe" => "video/mpeg", | |
| "m1v" => "video/mpeg", | |
| "m2v" => "video/mpeg", | |
| "webm" => "video/webm", | |
| "3gp" => "video/3gpp", | |
| "3g2" => "video/3gpp2", | |
| "h264" => "video/h264", | |
| "jpgv" => "video/jpeg", | |
| "qt" => "video/quicktime", | |
| "mov" => "video/quicktime", | |
| "dvb" => "video/vnd.dvb.file", | |
| "fvt" => "video/vnd.fvt", | |
| "mxu" => "video/vnd.mpegurl", | |
| "m4u" => "video/vnd.mpegurl", | |
| "pyv" => "video/vnd.ms-playready.media.pyv", | |
| "uvu" => "video/vnd.uvvu.mp4", | |
| "uvvu" => "video/vnd.uvvu.mp4", | |
| "viv" => "video/vnd.vivo", | |
| "f4v" => "video/x-f4v", | |
| "fli" => "video/x-fli", | |
| "flv" => "video/x-flv", | |
| "m4v" => "video/x-m4v", | |
| "mkv" => "video/x-matroska", | |
| "mk3d" => "video/x-matroska", | |
| "mks" => "video/x-matroska", | |
| "mng" => "video/x-mng", | |
| "asf" => "video/x-ms-asf", | |
| "asx" => "video/x-ms-asf", | |
| "vob" => "video/x-ms-vob", | |
| "wm" => "video/x-ms-wm", | |
| "wmv" => "video/x-ms-wmv", | |
| "wmx" => "video/x-ms-wmx", | |
| "wvx" => "video/x-ms-wvx", | |
| "avi" => "video/x-msvideo", | |
| "movie" => "video/x-sgi-movie", | |
| "smv" => "video/x-smv", | |
| "mpga" => "audio/mpeg", | |
| "mp2" => "audio/mpeg", | |
| "mp2a" => "audio/mpeg", | |
| "mp3" => "audio/mpeg", | |
| "m2a" => "audio/mpeg", | |
| "m3a" => "audio/mpeg", | |
| "ogg" => "audio/ogg", | |
| "oga" => "audio/ogg", | |
| "spx" => "audio/ogg", | |
| "weba" => "audio/webm", | |
| "aac" => "audio/aacp", | |
| "flac" => "audio/x-flac", | |
| "m3u" => "audio/x-mpegurl", | |
| "m3u8" => "application/vnd.apple.mpegurl", | |
| "ts" => "video/MP2T", | |
| "wav" => "audio/x-wav", | |
| "m4a" => "audio/mp4", | |
| ); | |
| $type = $arTypes[strtolower(substr($pathX, bxstrrpos($pathX, ".") + 1))]; | |
| } | |
| if ($type == "") | |
| { | |
| $type = "application/octet-stream"; | |
| } | |
| return $type; | |
| } | |
| /* | |
| This function will protect us from | |
| scan the whole file in order to | |
| findout size of the xbm image | |
| ext/standard/image.c php_getimagetype | |
| */ | |
| public static function GetImageSize($path, $bPhysicalName = false, $flashEnabled = false) | |
| { | |
| if($bPhysicalName) | |
| { | |
| $pathX = $path; | |
| } | |
| else | |
| { | |
| $io = CBXVirtualIo::GetInstance(); | |
| $pathX = $io->GetPhysicalName($path); | |
| } | |
| if(!file_exists($pathX)) | |
| { | |
| return false; | |
| } | |
| $file_handler = fopen($pathX, "rb"); | |
| if(!is_resource($file_handler)) | |
| return false; | |
| $signature = fread($file_handler, 12); | |
| fclose($file_handler); | |
| if($flashEnabled) | |
| { | |
| $flashPattern = " | |
| |FWS # php_sig_swf | |
| |CWS # php_sig_swc | |
| "; | |
| } | |
| else | |
| { | |
| $flashPattern = ""; | |
| } | |
| if(preg_match("/^( | |
| GIF # php_sig_gif | |
| |\\xff\\xd8\\xff # php_sig_jpg | |
| |\\x89\\x50\\x4e # php_sig_png | |
| ".$flashPattern." | |
| |8BPS # php_sig_psd | |
| |BM # php_sig_bmp | |
| |\\xff\\x4f\\xff # php_sig_jpc | |
| |II\\x2a\\x00 # php_sig_tif_ii | |
| |MM\\x00\\x2a # php_sig_tif_mm | |
| |FORM # php_sig_iff | |
| |\\x00\\x00\\x01\\x00 # php_sig_ico | |
| |\\x00\\x00\\x00\\x0c | |
| \\x6a\\x50\\x20\\x20 | |
| \\x0d\\x0a\\x87\\x0a # php_sig_jp2 | |
| )/x", | |
| $signature | |
| )) | |
| { | |
| /*php_get_wbmp to be added*/ | |
| return getimagesize($pathX); | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| } | |
| public static function isEnabledTrackingResizeImage() | |
| { | |
| return static::$enableTrackingResizeImage; | |
| } | |
| public static function enableTrackingResizeImage() | |
| { | |
| static::$enableTrackingResizeImage = true; | |
| } | |
| public static function disableTrackingResizeImage() | |
| { | |
| static::$enableTrackingResizeImage = false; | |
| } | |
| } | |
| global $arCloudImageSizeCache; | |
| $arCloudImageSizeCache = array(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment