Your IP : 18.117.75.102
<?php
// Функция трассировки
function dump($var, $varDump = false, $return = false){
static $dumpCnt;
if(is_null($dumpCnt)){
$dumpCnt = 0;
}
ob_start();
echo '<p>';
$style = "
border: 1px solid #696969;
background: #eee;
border-radius: 3px;
font-size: 14px;
font-family: calibri, arial, sans-serif;
padding: 20px;
";
echo '<b>DUMP #'.$dumpCnt.':</b> ';
echo '<pre style="'.$style.'">';
if($varDump){
var_dump($var);
}else{
print_r($var);
}
echo '</pre>';
echo '</p>';
$cnt = ob_get_contents();
ob_end_clean();
$dumpCnt++;
if($return){
return $cnt;
}else{
echo $cnt;
}
return true;
}
function cdump($var){
echo "<script>";
echo "console.log(".json_encode($var).");";
echo "</script>";
}
/**
* @param $n
* @param $forms
* @return mixed
* Возвращает слово с нужным окончанием в зависимости от числа перед словом
*/
function plural($n, $forms){
return $n % 10 == 1 && $n % 100 != 11 ? $forms[0] : ($n % 10 >= 2 && $n % 10 <= 4 &&
($n % 100 < 10 || $n % 100 >= 20) ? $forms[1] : $forms[2]);
}
/* Аналог ResizeImageGet, только с Upscale */
class CWPFile extends CAllFile {
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];
}
}
// Возвращает уменьшенную картинку. Размеры картинок задаются в settings.php
// Пример: $arImage = resizeImageGet($arProperties['IMAGE'], 'CATALOG_ITEM_LIST');
// В ответе массив из 'SRC', 'WIDTH', 'HEIGHT';
function resizeImageGet($file, $sizeName){
global $arImageSizes;
if(isset($arImageSizes[$sizeName])){
if(is_array($arImageSizes[$sizeName]['FILTER'])){
$filters = $arImageSizes[$sizeName]['FILTER'];
}else{
switch ($arImageSizes[$sizeName]['FILTER']){
case 'nosharp':
$filters = Array(
"name" => "sharpen",
"precision" => 0
);
break;
default:
$filters = false;
}
}
return CWPFile::ResizeImageGet(
$file,
array("width" => $arImageSizes[$sizeName]['WIDTH'], "height" => $arImageSizes[$sizeName]['HEIGHT']),
$arImageSizes[$sizeName]['RESIZE'],
true,
$filters
);
}else{
return CWPFile::ResizeImageGet(
$file,
array("width" => "1000", "height" => "1000"),
BX_RESIZE_IMAGE_PROPORTIONAL,
true
);
}
}
function resizeImageGetSrc($file, $sizeName){
$file = resizeImageGet($file, $sizeName);
if(!$file['src'] || !file_exists($_SERVER['DOCUMENT_ROOT'].$file['src'])){
return SITE_TEMPLATE_PATH.NO_PHOTO_SRC;
}
return $file['src'];
}
/**
* @param $file
* @param $sizeName
* @return array
* Шаг 1. Обрезает/Уменьшает картинку по параметрам
* При отсутствии картинки действие из шага 1 будет применено к стандартной картинке no_photo.png
* Используется класс CWPFile, в котором переопределена функция ResizeImageGet, которая умеет увеличивать.
*/
function resizeImgInfo($file, $sizeName){
global $arImageSizes;
if (!is_array($file))
$file = CFile::GetFileArray($file);
$size = $arImageSizes[$sizeName];
if(empty($file) || !file_exists($_SERVER['DOCUMENT_ROOT'].urldecode($file['SRC']))) {
$filePath = $_SERVER['DOCUMENT_ROOT'].SITE_TEMPLATE_PATH.NO_PHOTO_SRC;
$fileName = $size['WIDTH'] . 'x' . $size['HEIGHT'] . $size['RESIZE'] . basename($filePath);
$fileNameRetina = $size['WIDTH'] . 'x' . $size['HEIGHT'] . $size['RESIZE'] . '@2x' . basename($filePath);
$tmpImage = $_SERVER['DOCUMENT_ROOT'] . '/upload/tmp/' . $fileName;
$tmpImageRetina = $_SERVER['DOCUMENT_ROOT'] . '/upload/tmp/' . $fileNameRetina;
if(!file_exists($tmpImage)) {
CFile::ResizeImageFile(
$filePath,
$tmpImage,
array("width" => $size['WIDTH'], "height" => $size['HEIGHT']),
$size['RESIZE']
);
}
if(!file_exists($tmpImageRetina)) {
CFile::ResizeImageFile(
$filePath,
$tmpImageRetina,
array("width" => ($size['WIDTH'] * 2), "height" => ($size['HEIGHT']) * 2),
$size['RESIZE']
);
}
$arRet = array(
'regularFile' => array(
"src" => '/upload/tmp/' . $fileName
),
'retinaFile' => array(
"src" => '/upload/tmp/' . $fileNameRetina
)
);
if($size['DIMENSIONS'] == 'N'){
$arRet['dontSetDimension'] = true;
}
return $arRet;
}
if(isset($size)){
if(is_array($size['FILTER'])){
$filters = $size['FILTER'];
}else{
switch ($size['FILTER']){
case 'nosharp':
$filters = Array(
"name" => "sharpen",
"precision" => 0
);
break;
default:
$filters = false;
}
}
$regularFile = CWPFile::ResizeImageGet(
$file,
array("width" => $size['WIDTH'], "height" => $size['HEIGHT']),
$size['RESIZE'],
true,
$filters
);
if($size['RETINA']=="N"){
$retinaFile = false;
}else{
$retinaFile = CWPFile::ResizeImageGet(
$file,
array("width" => ($size['WIDTH']*2), "height" => ($size['HEIGHT'])*2),
$size['RESIZE'],
true,
$filters
);
}
}else{
$regularFile = CWPFile::ResizeImageGet(
$file,
array("width" => "500", "height" => "500"),
BX_RESIZE_IMAGE_PROPORTIONAL,
true
);
$retinaFile = CWPFile::ResizeImageGet(
$file,
array("width" => "1000", "height" => "1000"),
BX_RESIZE_IMAGE_PROPORTIONAL,
true
);
}
$arRet = array(
'regularFile' => $regularFile,
'retinaFile' => $retinaFile,
);
if($size['DIMENSIONS'] == 'N'){
$arRet['dontSetDimensions'] = true;
}
return $arRet;
}
//Функция для вывода тега изображений. Остальные deprecated, используйте её.
function resizeImgTag($file, $sizeName, $htmlParams=array()){
if (!is_array($file))
$file = CFile::GetFileArray($file);
$imgInfo = resizeImgInfo($file, $sizeName);
$tagParams = array(
'src' => $imgInfo['regularFile']['src']
);
//Если мы передаём дитейл или превью, для него уже есть альты и тайтлы
if(array_key_exists('ALT', $file)){
$tagParams['alt'] = $file['ALT'];
}
if(array_key_exists('TITLE', $file)){
$tagParams['title'] = $file['TITLE'];
}
//Совмещаем сгенерированное и то, что передали. Теоретически можно всё сгенерированное переопределить.
$tagParams = array_merge($tagParams, $htmlParams);
if(!array_key_exists('alt',$tagParams)){
//Ну и ай-яй. Невалидно без альта
$tagParams['alt'] = ' ';
}
if($imgInfo['retinaFile']!==false){
$tagParams['data-at2x'] = $imgInfo['retinaFile']['src'];
}else{
$tagParams['data-no-retina'] = "";
}
// Не устанавливать размеры JS-ом при замене на retina-изображение
if($imgInfo['dontSetDimensions']){
$tagParams['data-no-resize'] = "";
}
$strTagParams = '';
foreach($tagParams as $key=>$item) {
$strTagParams .= ' '.$key.'="'.$item.'"';
}
$htmlTag ='<img '.trim($strTagParams).'>';
return $htmlTag;
}
//Функция для вывода только Src изображения.
function resizeImgSrc($file, $sizeName){
$imgInfo = resizeImgInfo($file, $sizeName);
return $imgInfo['regularFile']['src'];
}
/**
* @param $sectionId
* @param $arFilter
* @param $arParams
* @return array|bool
* Возвращает ближайший родительский раздел, который не является псевдоразделом
*/
function getClosestNotPseudoSection($sectionId, $arFilter, $arParams){
if($sectionId){
$resInside = CIBlockSection::GetList(
array(),
array(
'IBLOCK_ID' => $arParams['IBLOCK_ID'],
'ID' => $sectionId,
'ACTIVE' => 'Y',
'!UF_PSEUDO_SECTION' => false
),
true,
array(
'ID',
'IBLOCK_ID',
'CODE',
'IBLOCK_SECTION_ID',
'UF_PSEUDO_SECTION'
)
);
if($obInside = $resInside->GetNext()){
$sectionValue = unserialize(htmlspecialchars_decode($obInside['UF_PSEUDO_SECTION']));
if(count($sectionValue) > 0){
if($sectionValue['is_pseudosection'] == 'Y'){
$obCond = new CCCatalogCondTree();
$obCond->Init(BT_COND_MODE_GENERATE, BT_COND_BUILD_CATALOG, array());
$conditions = $obCond->Parse($sectionValue['rule']);
$strEval = $obCond->Generate($conditions, array());
$strEval = preg_replace('/([\"\'])\\1+/', '$1', $strEval);
$arFilterInside = array();
eval('$arFilterInside = '.$strEval);
foreach($arFilterInside as $fKey => $arFElem){
$arFilter[] = array(
'PROP_ID' => preg_replace("/\D/", "", $fKey),
'PROP_VALUE' => $arFElem
);
}
$sectionId = $obInside['IBLOCK_SECTION_ID'];
$functionReturn = getClosestNotPseudoSection($sectionId, $arFilter, $arParams);
if($functionReturn){
$sectionId = $functionReturn['SECTION_ID'];
$arFilter = array_merge($arFilter, $functionReturn['FILTER']);
}
return array('SECTION_ID' => $sectionId, 'FILTER' => $arFilter);
}
}
}
}
return false;
}
// Каноничный URL для ссылки.
// $element может принимать на вход ID элемента, массив элемента($arItem), массив элементов ($arResult['ITEMS'])
function getCanonicalLink($element, $detailPageTemplate = false){
//Если у нас массив $arResult['ITEMS'], то эта переменная пригодится
$elementsTable = array();
$return = $element;
$elementId = false;
//Узнаём, что же у нас на входе
if(is_int($element) || !is_array($element)){ // просто айди
if(intval($element) > 0){
$elementId = $element;
$handler = 'id';
}else{
return $element;
}
}elseif(is_array($element)){ // массив одного элемента
if(array_key_exists('ID', $element)){
$elementId = intval($element['ID']);
if($elementId > 0){
$handler = 'item';
}else{
return $element;
}
}elseif(array_key_exists('ID', $element[key($element)])){ // массив $arResult['ITEMS']
$handler = 'items';
foreach($element as $key => $value){
$elementId[] = $value['ID'];
$elementsTable[$value['ID']] = $key;
}
}else{
return $element;
}
}else{
return $element;
}
//Массив для кэша URL инфоблока
$cachedIblocks = array();
$paramDetailPageTemplate = $detailPageTemplate;
$dbRes = CIBlockElement::GetList(
array("SORT" => "ASC"),
$arFilter = array("ID" => $elementId),
false,
false,
array(
"CODE",
"DETAIL_PAGE_URL",
"PROPERTY_CANONICAL_SECTION",
"IBLOCK_SECTION_ID"
)
);
// Если указан каноничный раздел, то строим ссылку на основе него
while($arRes = $dbRes->GetNext()){
$detailPageUrl = $arRes['DETAIL_PAGE_URL'];
//Если раздел деактивировали или удалили
if($arRes["PROPERTY_CANONICAL_SECTION_VALUE"]){
$dbSection = CIBlockSection::GetByID(intval($arRes["PROPERTY_CANONICAL_SECTION_VALUE"]));
if($arSection = $dbSection->GetNext()){
if($arSection['ACTIVE'] != 'Y'){
$arRes["PROPERTY_CANONICAL_SECTION_VALUE"] = false;
}
}else{
$arRes["PROPERTY_CANONICAL_SECTION_VALUE"] = false;
}
}
//Если свойства CANONICAL_SECTION нет как такового — используем новый функционал "Основной раздел"
if(!isset($arRes["PROPERTY_CANONICAL_SECTION_VALUE"])){
$arRes["PROPERTY_CANONICAL_SECTION_VALUE"] = $arRes['IBLOCK_SECTION_ID'];
}
//Если раздела ещё нет, но свойство CANONICAL_SECTION вообще есть
if(!$arRes["PROPERTY_CANONICAL_SECTION_VALUE"]){
$arList = array();
// Ищем самый глубокий из непсевдоразделов элемента и привязываем его
$db_old_groups = CIBlockElement::GetElementGroups(
intval($arRes['ID']),
false,
array(
"ID",
"IBLOCK_SECTION_ID",
"IBLOCK_ID",
"NAME",
"DEPTH_LEVEL"
)
);
while($ar_group = $db_old_groups->Fetch()){
if($ar_group['ACTIVE'] != 'Y'){
continue;
}
$arUF = $GLOBALS["USER_FIELD_MANAGER"]->GetUserFields("IBLOCK_".intval($ar_group["IBLOCK_ID"]).
"_SECTION", $ar_group["ID"]);
$UF_PS = $arUF["UF_PSEUDO_SECTION"]["VALUE"];
if(strlen($UF_PS) > 0){
$arUF_PS = unserialize($UF_PS);
if($arUF_PS["is_pseudosection"] == "Y"){
continue;
}
}
$arList[$ar_group["ID"]] = array('ID' => $ar_group["ID"],
'PARENT' => intval($ar_group["IBLOCK_SECTION_ID"]),
'NAME' => $ar_group["NAME"],
'DEPTH_LEVEL' => $ar_group["DEPTH_LEVEL"]);
}
$sort_arr = array();
foreach($arList as $uniqueId => $row){
foreach($row as $key => $value){
$sort_arr[$key][$uniqueId] = $value;
}
}
array_multisort($sort_arr["DEPTH_LEVEL"], SORT_DESC, $arList);
reset($arList);
$arNewCanonical = $arList[key($arList)];
CIBlockElement::SetPropertyValuesEx($arRes['ID'], $arRes['IBLOCK_ID'], array("CANONICAL_SECTION" => $arNewCanonical['ID']));
$arRes["PROPERTY_CANONICAL_SECTION_VALUE"] = $arNewCanonical['ID'];
}
if($arRes["PROPERTY_CANONICAL_SECTION_VALUE"]){
$arList = array();
$dbParents = CIBlockSection::GetNavChain(false, intval($arRes["PROPERTY_CANONICAL_SECTION_VALUE"]));
while($arParents = $dbParents->Fetch()){
$arList[] = $arParents['CODE'];
}
$sectionPath = implode('/', $arList);
$detailPageTemplate = $paramDetailPageTemplate;
// Если не передан параметр шаблона DETAIL_PAGE_URL, то берём из настроек инфоблока
if(!$detailPageTemplate){
if(array_key_exists($arRes['IBLOCK_ID'], $cachedIblocks)){
$detailPageTemplate = $cachedIblocks[$arRes['IBLOCK_ID']]['DETAIL_PAGE_URL'];
}else{
$rsIblocks = CIBlock::GetList(array('ID' => 'ASC'), array('=ID' => $arRes['IBLOCK_ID']));
if($arIblocks = $rsIblocks->GetNext()){
$detailPageTemplate = $arIblocks['DETAIL_PAGE_URL'];
$cachedIblocks[$arRes['IBLOCK_ID']] = array('DETAIL_PAGE_URL' => $detailPageTemplate);
}
}
}
//Строим DETAIL_PAGE_URL с нуля
$detailPageUrl = $detailPageTemplate;
$detailPageUrl = str_replace('#SECTION_CODE_PATH#', $sectionPath, $detailPageUrl);//Меняем код пути до нужной секции
$detailPageUrl = str_replace('#ELEMENT_CODE#', $arRes['CODE'], $detailPageUrl);//Меняем код товара
$detailPageUrl = str_replace('#CODE#', $arRes['CODE'], $detailPageUrl);//Меняем код товара
$detailPageUrl = str_replace('#ELEMENT_ID#', $arRes['ID'], $detailPageUrl);//Меняем код товара
$detailPageUrl = str_replace('#SITE_DIR#', SITE_DIR, $detailPageUrl);//Меняем код товара
$detailPageUrl = str_replace('//', '/', $detailPageUrl);//Меняем код товара
}
switch ($handler){
case 'id':
$return = $detailPageUrl;
break;
case 'item':
$element['DETAIL_PAGE_URL'] = $detailPageUrl;
$return = $element;
break;
case 'items':
$key = $elementsTable[$arRes['ID']];
$element[$key]['DETAIL_PAGE_URL'] = $detailPageUrl;
$return = $element;
break;
}
}
return $return;
}
// Показывает время выполнения до текущего момента
function dumptime($text = ''){
$time = microtime(true) - START_SCRIPT_TIME;
dump(sprintf($text.' %.4F сек.', $time));
}
// Работает как GetMessage(), только принимает на вход количество товара
// Необходимы строки в файле языка PLURAL_СВОЙСТВО_ONE, PLURAL_СВОЙСТВО_TWO, PLURAL_СВОЙСТВО_FIVE
// Например:
// $MESS['PLURAL_ITEM_ONE'] = 'товар';
// $MESS['PLURAL_ITEM_TWO'] = 'товара';
// $MESS['PLURAL_ITEM_MANY'] = 'товаров';
function GetMessagePlural($cnt, $name, $aReplace = null){
global $MESS;
if(isset($MESS['PLURAL_'.$name.'_ONE']) && isset($MESS['PLURAL_'.$name.'_TWO']) &&
isset($MESS['PLURAL_'.$name.'_MANY'])
){
$forms = array($MESS['PLURAL_'.$name.'_ONE'], $MESS['PLURAL_'.$name.'_TWO'], $MESS['PLURAL_'.$name.'_MANY']);
$s = plural($cnt, $forms);
if($aReplace !== null && is_array($aReplace)){
foreach($aReplace as $search => $replace){
$s = str_replace($search, $replace, $s);
}
}
return $s;
}
return \Bitrix\Main\Localization\Loc::getMessage($name, $aReplace);
}
function getComponentTemplates($dir, $componentName, $vendor = "bitrix"){
$templatesList = array(".default" => ".default");
$templates = glob($dir."/".$vendor."/".$componentName."/*", GLOB_ONLYDIR);
foreach($templates as $key => $value){
$name = substr($value, strrpos($value, '/') + 1);
$templatesList[$name] = $name;
}
$templates = CComponentUtil::GetTemplatesList($vendor.":".$componentName, $_GET["template_id"]);
foreach($templates as $key => $value){
if(isset($templatesList[$value['NAME']]) || $value['NAME'] == '.default'){
continue;
} // Those aren't available from here
if($value['TEMPLATE'] == ""){
$value['TEMPLATE'] = "__bitrix__";
}
$templatesList[$value['NAME']] = $value['NAME']." (".$value['TEMPLATE'].")";
}
return $templatesList;
}
function getCompareProperties($iblock_id){
CModule::IncludeModule("iblock");
global $arCompareExcludeProperties;
$props = array();
$res = CIBlock::GetProperties($iblock_id);
while($r = $res->Fetch()){
if(array_search($r["CODE"], $arCompareExcludeProperties) === false){
$props[] = $r["CODE"];
}
}
return $props;
}
//Подготавливаем свойства для фильтра псевдоразделов
if(!function_exists('preparePropsForPseudosectionFilter')){
function preparePropsForPseudosectionFilter($arElement){
//Приводим все значения к массиву
foreach($arElement['PROPERTIES'] as $key => $value){
// Для свойства список.
if(is_array($value['VALUE_ENUM_ID'])){
$arElement['PROPERTY_'.$value['ID'].'_VALUE'] = $value['VALUE_ENUM_ID'];
}else{
if(is_array($value['VALUE'])){
$arElement['PROPERTY_'.$value['ID'].'_VALUE'] = $value['VALUE'];
}else{
if(isset($value['VALUE_ENUM_ID'])){
$arElement['PROPERTY_'.$value['ID'].'_VALUE'] = array($value['VALUE_ENUM_ID']);
}else{
$arElement['PROPERTY_'.$value['ID'].'_VALUE'] = array($value['VALUE']);
}
}
}
}
//Если какие-нибудь свойства потерялись
foreach($arElement as $key => $value){
if(
mb_strpos($key, 'PROPERTY_') !== false
&& mb_strpos($key, '_VALUE') === false
&& !array_key_exists($key.'_VALUE', $arElement)
&& mb_strpos($key, '~') !== 0
){
if(!is_array($value)){
$arElement[$key.'_VALUE'] = array($value);
}
}
}
return $arElement;
}
}
//Привязка к псевдоразделам по айди
if(!function_exists('setPseudoSectionsToElement')){
function setPseudoSectionsToElement($element_id){
if(CModule::IncludeModule("iblock") && CModule::IncludeModule("catalog")){
$MODULE_ID = "webprofy.pseudosection";
$IBLOCK_ID = COption::GetOptionString($MODULE_ID, "IBLOCK_ID");
$addedToSection = array();
$cacheDir = $_SERVER['DOCUMENT_ROOT'].'/upload/custom_cache/';
$cacheFileIblock = $cacheDir.'custom_pseudosection_admin.php';
$message = null;
$main_section_id = null;
if(!is_dir($cacheDir)){
mkdir($cacheDir, 0777, true);
}
// основная часть
$handle = fopen($cacheFileIblock, "r");
$contents = fread($handle, filesize($cacheFileIblock));
$arSections = json_decode($contents, true);
fclose($handle);
$arSelect = array("ID", "IBLOCK_ID", "PROPERTY_*"); //IBLOCK_ID и ID обязательно должны быть указаны
$arFilter = array("IBLOCK_ID" => $IBLOCK_ID, "ID" => $element_id, "ACTIVE" => "Y");
$rsElements = CIBlockElement::GetList(array('ID' => "ASC"), $arFilter, false, false, $arSelect);
$IBLOCK_OFFER_ID = false;
$mxResult = CCatalogSku::GetInfoByProductIBlock($IBLOCK_ID);
if(is_array($mxResult)){
$IBLOCK_OFFER_ID = $mxResult['IBLOCK_ID'];
}
if($obElement = $rsElements->GetNextElement()){
$arElement = $obElement->GetFields();
$arElement['PROPERTIES'] = $obElement->GetProperties();
$arElement = preparePropsForPseudosectionFilter($arElement);
$db_old_groups = CIBlockElement::GetElementGroups($arElement['ID'], true, array("ID"));
$ar_new_groups = array();
$ar_old_groups = array();
while($ar_group = $db_old_groups->Fetch()){
if(!array_key_exists($ar_group["ID"], $arSections)){
$ar_old_groups[] = $ar_group["ID"];
}
}
$ar_unchanged_groups = $ar_old_groups;
foreach($ar_old_groups as $key => $group){
$nav = CIBlockSection::GetNavChain($IBLOCK_ID, $group);
while($arSectionPath = $nav->GetNext()){
$ar_old_groups[] = $arSectionPath['ID'];
}
}
$ar_old_groups = array_unique($ar_old_groups);
if($IBLOCK_OFFER_ID){
$arElementClear = $arElement;
$rsOffers = CIBlockElement::GetList(
array(),
array(
'IBLOCK_ID' => $IBLOCK_OFFER_ID,
'PROPERTY_CML2_LINK' => $arElement['ID'],
"ACTIVE" => "Y"
),
false,
false,
array("ID", "IBLOCK_ID", "PROPERTY_*")
);
while($obOffer = $rsOffers->GetNextElement()){
$arNewElement = $arElementClear;
$arNewElement['PROPERTIES'] = $obOffer->GetProperties();
$arNewElement = preparePropsForPseudosectionFilter($arNewElement);
$arElement = array_merge($arElementClear, $arNewElement);
ksort($arSections);
foreach($arSections as $arSection){
if(mb_strlen($arSection['EVAL_FILTER']) > 0){
if(
eval('return('.$arSection['EVAL_FILTER'].');')
&& (
($arSection['DISCARD_PARENT_GROUP'] == "N" &&
array_search($arSection['SECTION_ID'], $ar_old_groups) !== false)
|| $arSection['DISCARD_PARENT_GROUP'] == "Y"
)
){
if($arSection['DISCARD_PARENT_GROUP'] == "Y"){
$ar_old_groups[] = $arSection['ID'];
}
if(array_search($arSection['ID'], $ar_new_groups) === false){
$addedToSection[] = $arElement['ID'];
$ar_new_groups[] = $arSection['ID'];
if(!$main_section_id){
$main_section_id = $arSection['ID'];
}
}
}
}
}
}
$ar_new_groups = array_keys(array_flip(array_merge($ar_new_groups, $ar_old_groups)));
}
ksort($arSections);
foreach($arSections as $arSection){
if(mb_strlen($arSection['EVAL_FILTER']) > 0){
if(
eval('return('.$arSection['EVAL_FILTER'].');')
&& (
($arSection['DISCARD_PARENT_GROUP'] == "N" &&
array_search($arSection['SECTION_ID'], $ar_old_groups) !== false)
|| $arSection['DISCARD_PARENT_GROUP'] == "Y"
)
){
if($arSection['DISCARD_PARENT_GROUP'] == "Y"){
$ar_old_groups[] = $arSection['ID'];
}
if((array_search($arSection['ID'], $ar_new_groups)) === false){
$addedToSection[] = $arElement['ID'];
$ar_new_groups[] = $arSection['ID'];
if(!$main_section_id){
$main_section_id = $arSection['ID'];
}
}
}
}
}
$ar_new_groups = array_keys(array_flip(array_merge($ar_new_groups, $ar_unchanged_groups)));
if($ar_unchanged_groups != $ar_new_groups){
CIBlockElement::SetElementSection($arElement['ID'], $ar_new_groups);
}
}
}
}
}
/**
* @param $url
* @return bool
* Парсит урл видео с YouTube и возвращает id
*/
function parseYouTubeUrl($url)
{
$pattern = '#^(?:https?://)?(?:www\.)?(?:m\.)?(?:youtu\.be/|youtube\.com(?:/embed/|/v/|/watch\?v=|/watch\?.+&v=))([\w-]{11})(?:.+)?$#x';
preg_match($pattern, $url, $matches);
return (isset($matches[1])) ? $matches[1] : false;
}
/**
* @param $lang
* @param $date
* @return string
* Возвращает дату в строковом представлении: N дней, месяцев, часов, минут + назад
*/
function wpFormatDate($date, $lang = 'ru'){
$date = strtotime($date);
$cur_time = time();
$no = $diff = $cur_time - $date;
if($lang == 'en'){
$seconds = array(
'second',
'second',
'seconds'
);
$minutes = array(
'minute',
'minute',
'minutes'
);
$hours = array(
'hour',
'hour',
'hours'
);
$days = array(
'day',
'day',
'days'
);
$weeks = array(
'week',
'week',
'weeks'
);
$months = array(
'month',
'month',
'months'
);
$years = array(
'year',
'year',
'years'
);
$decades = array(
'decade',
'decade',
'decades'
);
}else{
$seconds = array(
'секунда',
'секунды',
'секунд'
);
$minutes = array(
'минута',
'минуты',
'минут'
);
$hours = array(
'час',
'часа',
'часов'
);
$days = array(
'день',
'дня',
'дней'
);
$weeks = array(
'неделя',
'недели',
'недель'
);
$months = array(
'месяц',
'месяца',
'месяцев'
);
$years = array(
'год',
'года',
'лет'
);
$decades = array(
'десятилетие',
'десятилетия',
'десятилетий'
);
}
$phrase = array(
$seconds,
$minutes,
$hours,
$days,
$weeks,
$months,
$years,
$decades
);
$length = array(
1,
60,
3600,
86400,
604800,
2630880,
31570560,
315705600
);
for($i = sizeof($length) - 1; ($i >= 0) && (($no = $diff / $length[$i]) <= 1); $i--){
;
}
if($i < 0){
$i = 0;
}
$no = floor($no);
$value = sprintf("%d %s ", $no, plural($no, $phrase[$i]));
if($lang == 'en'){
return $value.' ago';
}else{
return $value.' назад';
}
}
/**
* Возвращает отформатированный текст строки для выбранной валюты без вывода самой цены.
* @param string $currency
* @return string
*/
function formatCurrencyString($currency){
$formatDescription = CCurrencyLang::GetFormatDescription($currency);
return preg_replace('/(^|[^&])#/', '', $formatDescription['FORMAT_STRING']);
}
/**
* Замена функции CUtil::translit. Полная её копия с использованием мультибайтовых строковых функций.
* @param string $str
* @param string $lang
* @param array $params
* @return string
*/
function translit($str, $lang, $params = array()){
static $search = array();
if(!isset($search[$lang])){
$mess = IncludeModuleLangFile($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/js_core_translit.php", $lang, true);
$trans_from = explode(",", $mess["TRANS_FROM"]);
$trans_to = explode(",", $mess["TRANS_TO"]);
foreach($trans_from as $i => $from){
$search[$lang][$from] = $trans_to[$i];
}
}
$defaultParams = array(
"max_len" => 100,
"change_case" => 'L', // 'L' - toLower, 'U' - toUpper, false - do not change
"replace_space" => '_',
"replace_other" => '_',
"delete_repeat_replace" => true,
"safe_chars" => '',
);
foreach($defaultParams as $key => $value){
if(!array_key_exists($key, $params)){
$params[$key] = $value;
}
}
$len = mb_strlen($str);
$str_new = '';
$last_chr_new = '';
for($i = 0; $i < $len; $i++){
$chr = mb_substr($str, $i, 1);
if(preg_match("/[a-zA-Z0-9]/".BX_UTF_PCRE_MODIFIER, $chr) || strpos($params["safe_chars"], $chr) !== false){
$chr_new = $chr;
}elseif(preg_match("/\\s/".BX_UTF_PCRE_MODIFIER, $chr)){
if(
!$params["delete_repeat_replace"]
||
($i > 0 && $last_chr_new != $params["replace_space"])
){
$chr_new = $params["replace_space"];
}else{
$chr_new = '';
}
}else{
if(array_key_exists($chr, $search[$lang])){
$chr_new = $search[$lang][$chr];
}else{
if(
!$params["delete_repeat_replace"]
||
($i > 0 && $i != $len - 1 && $last_chr_new != $params["replace_other"])
){
$chr_new = $params["replace_other"];
}else{
$chr_new = '';
}
}
}
if(strlen($chr_new)){
if($params["change_case"] == "L" || $params["change_case"] == "l"){
$chr_new = mbToLower($chr_new);
}elseif($params["change_case"] == "U" || $params["change_case"] == "u"){
$chr_new = mbToUpper($chr_new);
}
$str_new .= $chr_new;
$last_chr_new = $chr_new;
}
if(mb_strlen($str_new) >= $params["max_len"]){
break;
}
}
return $str_new;
}
/**
* Замена функции ToUpper. Полная её копия с использованием мультибайтовых строковых функций.
* @param $str
* @param bool $lang
* @return string
*/
function mbToUpper($str, $lang = false){
static $lower = array();
static $upper = array();
if(!defined("BX_CUSTOM_TO_UPPER_FUNC")){
if(defined("BX_UTF")){
return mb_strtoupper($str);
}else{
if($lang === false){
$lang = LANGUAGE_ID;
}
if(!isset($lower[$lang])){
$arMsg = IncludeModuleLangFile(__FILE__, $lang, true);
$lower[$lang] = $arMsg["ABC_LOWER"];
$upper[$lang] = $arMsg["ABC_UPPER"];
}
return mb_strtoupper(strtr($str, $lower[$lang], $upper[$lang]));
}
}else{
$func = BX_CUSTOM_TO_UPPER_FUNC;
return $func($str);
}
}
/**
* Замена функции ToLower. Полная её копия с использованием мультибайтовых строковых функций.
* @param $str
* @param bool $lang
* @return string
*/
function mbToLower($str, $lang = false){
static $lower = array();
static $upper = array();
if(!defined("BX_CUSTOM_TO_LOWER_FUNC")){
if(defined("BX_UTF")){
return mb_strtolower($str);
}else{
if($lang === false){
$lang = LANGUAGE_ID;
}
if(!isset($lower[$lang])){
$arMsg = IncludeModuleLangFile(__FILE__, $lang, true);
$lower[$lang] = $arMsg["ABC_LOWER"];
$upper[$lang] = $arMsg["ABC_UPPER"];
}
return mb_strtolower(strtr($str, $upper[$lang], $lower[$lang]));
}
}else{
$func = BX_CUSTOM_TO_LOWER_FUNC;
return $func($str);
}
}
function wp_get_script_url(){
$script_url = NULL;
if(!empty($_SERVER['SCRIPT_URL'])) {
$script_url = $_SERVER['SCRIPT_URL'];
} elseif(!empty($_SERVER['REDIRECT_URL'])) {
$script_url = $_SERVER['REDIRECT_URL'];
} elseif(!empty($_SERVER['REQUEST_URI'])) {
$p = parse_url($_SERVER['REQUEST_URI']);
$script_url = $p['path'];
}
return $script_url;
}
function IncludeGlobalLangFile(){
global $MESS;
$langPath = $_SERVER['DOCUMENT_ROOT'] . SITE_TEMPLATE_PATH . '/lang/' . LANGUAGE_ID . '/main.php';
if(!file_exists($langPath)){
$langPath = $_SERVER['DOCUMENT_ROOT'] .'/.default/lang/' . LANGUAGE_ID . '/main.php';
}
if(file_exists($langPath)){
include $langPath;
}
}
/**
* Добавляет переменные из языкового файла для использования в js через BX.Message();
* @param string $lang путь к языковому файлу
* @param bool $bReturn возвращать результат или нет
* @param mixed $arAdditionalMess массив дополнительных языковых переменных
* @return string
*
* Для использования языковых файлов в js шаблона компонента необходимо в компонент эпилоге выполнить функцию
* loadJsLanguageFile(__FILE__);
*/
function loadJsLanguageFile($lang, $bReturn = false, $arAdditionalMess = false){
$jsMsg = '';
if($lang){
$lang_filename = $_SERVER['DOCUMENT_ROOT'].str_replace("/lang/".LANGUAGE_ID."/", "/", $lang);
$mess_lang = \Bitrix\Main\Localization\Loc::loadLanguageFile($lang_filename);
if(!empty($mess_lang)){
$jsMsg = '(window.BX||top.BX).message('.CUtil::PhpToJSObject($mess_lang, false).');';
}
}
if(is_array($arAdditionalMess)){
$jsMsg = '(window.BX||top.BX).message('.CUtil::PhpToJSObject($arAdditionalMess, false).');'.$jsMsg;
}
if($jsMsg !== ''){
$jsMsg = '<script type="text/javascript">'.$jsMsg.'</script>';
if($bReturn){
return $jsMsg."\r\n";
}else{
\Bitrix\Main\Page\Asset::getInstance()->addString($jsMsg, true, 'AFTER_CSS');
}
}
return $jsMsg;
}
function gaParseCookie() {
$cid ='';
if (isset($_COOKIE['_ga'])) {
list($version,$domainDepth, $cid1, $cid2) = preg_split('[\.]', $_COOKIE["_ga"],4);
$contents = array('version' => $version, 'domainDepth' => $domainDepth, 'cid' => $cid1.'.'.$cid2);
$cid = $contents['cid'];
}
return $cid;
}
function debugf($mess, $label = '', $file = false){
if(!$file){
$file = $_SERVER['DOCUMENT_ROOT'] . '/debug.log';
}
$message = print_r($mess, true);
error_log('' . $label."\n".$message.'' . "\n", 3, $file);
}
/**
* @param $code
* @return int|bool
* Возвращает ID инфоблока по его коду или false
*/
if(!function_exists('getIblockIdByCode')) {
function getIblockIdByCode($code) {
if (CModule::IncludeModule("iblock") && isset($code) && !empty($code)) {
$res = CIBlock::GetList(array(), array("CODE" => $code), false);
if ($ar_res = $res->Fetch()) {
return $ar_res['ID'];
}
}
return false;
}
}
function getManualItem(){
$result = [];
$items = CIBlockElement::GetList([],
[
'ACTIVE'=>'Y',
'IBLOCK_ID' => CATALOG_IBLOCK_ID,
'!PROPERTY_' . PROPERTY_MANUAL_FILE_CODE => false
],
false,
false,
['ID','IBLOCK_ID']);
while($item = $items->GetNext()){
$result[] = $item['ID'];
}
return $result;
}