Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/aspro.allcorp3/lib/ |
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/aspro.allcorp3/lib/crosssales.php |
<? namespace Aspro\Allcorp3; use CAllcorp3 as Solution, CAllcorp3Cache as Cache, CAllcorp3Condition as Condition, \Aspro\Allcorp3\Property\CustomFilter, \Bitrix\Main\Web\Json; class CrossSales { const ALL_USERS_GROUP_ID = 2; const IBLOCK_TYPE = 'monolith_real_catalog'; const IBLOCK_CODE = 'monolith_real_cross_sales'; const PROPERTY_EXT_PRODUCTS_FILTER_CODE = 'EXT_PRODUCTS_FILTER'; protected static $arShowPlacesByIblockId = array(); protected $siteId; protected $iblockId; protected $arParams; protected $arRules; protected $productId; protected $productIblockId; protected $arProductSelect; protected $arProduct; public function __construct($productId, $arParams = array()){ $this->setProduct($productId, $arParams); } public function __set($name, $value){ switch($name){ case 'productId': $this->setProduct($value, $this->arParams); break; case 'arParams': $this->setProduct($this->productId, $arParams); break; case 'siteId': $this->siteId = $value; $this->iblockId = self::_getSiteIblockId($this->siteId); $this->arParams = $this->arProduct = $this->arProductSelect = array(); break; } return $value; } public function __get($name){ if(property_exists($this, $name)){ return $this->{$name}; } return null; } protected function _reset(){ $this->productId = $this->productIblockId = $this->arRules = $this->$siteId = $this->iblockId = false; $this->arParams = $this->arProduct = $this->arProductSelect = array(); } public function setProduct($productId, $arParams = array()){ $this->_reset(); if(($productId = intval($productId)) > 0){ $this->productId = $productId; $this->siteId = defined('SITE_ID') ? SITE_ID : false; $this->iblockId = self::_getSiteIblockId($this->siteId); $this->arParams = $arParams && is_array($arParams) ? $arParams : array(); $productIblockId = $arParams['IBLOCK_ID'] ? $arParams['IBLOCK_ID'] : false; if(($productIblockId = intval($productIblockId)) > 0){ $this->productIblockId = $productIblockId; } else{ $this->productIblockId = self::_getProductIblockId($productId); } } } public function getRules(){ if($this->arRules === false){ $arRules = array(); if($this->iblockId){ $propertyProductsFilterIblockId = CustomFilter::getSettingsIblockId('PRODUCTS_FILTER', $this->iblockId); if($propertyProductsFilterIblockId == $this->productIblockId){ $arRulesTmp = array(); // get current user groups $arUserGroups = self::_getUserGroups(); // collect show places variants $arShowPlaces = self::_getShowPlaces($this->iblockId); $arShowPlacesFlipped = array_flip($arShowPlaces); $arSelect = array( 'ID', 'PROPERTY_PRIORITY', 'PROPERTY_SORT', 'PROPERTY_SHOW_PLACE', 'PROPERTY_LAST_LEVEL_RULE', 'PROPERTY_LAST_RULE', 'PROPERTY_PRODUCTS_FILTER', 'PROPERTY_EXT_PRODUCTS_FILTER', 'PROPERTY_USER_GROUPS', 'PROPERTY_LINK_REGION', ); $arFilter = array( 'IBLOCK_ID' => $this->iblockId, 'ACTIVE' => 'Y', array( 'LOGIC' => 'OR', array('PROPERTY_USER_GROUPS' => $arUserGroups), array('PROPERTY_USER_GROUPS' => false), ), ); // use region if($GLOBALS['arRegion'] && $GLOBALS['arTheme']['USE_REGIONALITY']['VALUE'] === 'Y'){ $arFilter[] = array( 'LOGIC' => 'OR', array('PROPERTY_LINK_REGION' => $GLOBALS['arRegion']['ID']), array('PROPERTY_LINK_REGION' => false), ); } // get all rules for current user groups in current region if($arRulesTmp = Cache::CIBLockElement_GetList( array( 'property_PRIORITY' => 'DESC', 'property_SORT' => 'ASC', 'CACHE' => array( 'MULTI' => 'Y', 'TAG' => Cache::GetIBlockCacheTag($this->iblockId), ) ), $arFilter, false, false, $arSelect )){ // get active by date without cache $arRulesIDs = array_column($arRulesTmp, 'ID'); $dbRes = \CIBlockElement::GetList( array(), array( 'ID' => $arRulesIDs, 'IBLOCK_ID' => $this->iblockId, 'ACTIVE_DATE' => 'Y', ), false, false, array('ID') ); $arRulesIDs = array(); while($arRule = $dbRes->Fetch()){ $arRulesIDs[] = $arRule['ID']; } if($arRulesIDs){ $obCache = new \CPHPCache(); $cacheTime = 36000000; $cacheTag = Cache::GetIBlockCacheTag($this->iblockId); $cachePath = '/CMaxCache/iblock/CIBlockElement_GetList/'.$cacheTag.'/'; $cacheID = 'CIBlockElement_GetList_'.$cacheTag.md5(serialize($arRulesIDs)); if($obCache->InitCache($cacheTime, $cacheID, $cachePath)){ $res = $obCache->GetVars(); $arRulesTmp = $res['arRulesTmp']; $this->arProductSelect = $res['arProductSelect']; } else{ $this->arProductSelect = array( 'ID', 'IBLOCK_ID', ); // collect parsed conditions from PRODUCT_FILTER property // collect product fields for select $cond = new Condition(); foreach($arRulesTmp as $i => &$arRule){ if(in_array($arRule['ID'], $arRulesIDs)){ $bBadProductsFilter = true; if(is_string($arRule['PROPERTY_PRODUCTS_FILTER_VALUE'])){ if($arRule['PROPERTY_PRODUCTS_FILTER_VALUE']){ $arTmpProductsFilter = Json::decode($arRule['PROPERTY_PRODUCTS_FILTER_VALUE']); if(is_array($arTmpProductsFilter)){ try{ $arRule['PROPERTY_PRODUCTS_FILTER_VALUE'] = $this->parseCondition($arTmpProductsFilter, $this->arParams); $bBadProductsFilter = false; } catch(\Exception $e){ $arRule['PROPERTY_PRODUCTS_FILTER_VALUE'] = false; } } } else{ $bBadProductsFilter = false; } } if(!$bBadProductsFilter){ if(!$arRule['PROPERTY_PRODUCTS_FILTER_VALUE']){ $arRule['PROPERTY_PRODUCTS_FILTER_VALUE'] = array('IBLOCK_ID' => $propertyProductsFilterIblockId); } if(isset($arRule['PROPERTY_EXT_PRODUCTS_FILTER_VALUE']) && is_string($arRule['PROPERTY_EXT_PRODUCTS_FILTER_VALUE'])){ $arTmpExtProductsFilter = Json::decode($arRule['PROPERTY_EXT_PRODUCTS_FILTER_VALUE']); if($arTmpExtProductsFilter && $arTmpExtProductsFilter['CHILDREN']){ try{ $arRule['PROPERTY_EXT_PRODUCTS_FILTER_VALUE'] = $cond->parseCondition($arTmpExtProductsFilter, $this->arParams); } catch(\Exception $e){ $arRule['PROPERTY_EXT_PRODUCTS_FILTER_VALUE'] = array(); } if($arRule['PROPERTY_EXT_PRODUCTS_FILTER_VALUE']){ $arRule['PROPERTY_PRIORITY_VALUE'] = intval($arRule['PROPERTY_PRIORITY_VALUE']); $arRule['PROPERTY_SHOW_PLACE_ENUM_ID'] = ($arRule['PROPERTY_SHOW_PLACE_ENUM_ID'] ? (array)$arRule['PROPERTY_SHOW_PLACE_ENUM_ID'] : array_values($arShowPlaces)); // next rule continue; } } } } } // remove bad rule unset($arRulesTmp[$i]); } unset($arRule); if($cond->arProductSelect){ $this->arProductSelect = array_merge( $this->arProductSelect, $cond->arProductSelect ); } unset($cond); $obCache->StartDataCache($cacheTime, $cacheID, $cachePath); if(strlen($cacheTag)){ $GLOBALS['CACHE_MANAGER']->StartTagCache($cachePath); $GLOBALS['CACHE_MANAGER']->RegisterTag($cacheTag); $GLOBALS['CACHE_MANAGER']->EndTagCache(); } $obCache->EndDataCache(array('arRulesTmp' => $arRulesTmp, 'arProductSelect' => $this->arProductSelect)); } } // get some fields & properties of product if($arRulesTmp){ $this->arProductSelect = array_unique($this->arProductSelect); // echo '<pre>'; // print_r($this->arProductSelect); // echo '</pre>'; $this->arProduct = Cache::CIBLockElement_GetList( array( 'CACHE' => array( 'MULTI' => 'N', 'TAG' => Cache::GetIBlockCacheTag($this->productIblockId), ) ), array( 'ID' => $this->productId, 'IBLOCK_ID' => $this->productIblockId, ), false, false, $this->arProductSelect ); // get all parents sections of product // it is need in _checkParsedCondition for to check by IBLOCK_SECTION_ID & need in _replaceCond2ProductValues for to replace REAL_PARENT_IBLOCK_SECTION_ID if($this->arProduct['IBLOCK_SECTION_ID']){ $arSectionsIDs = $this->arProduct['REAL_IBLOCK_SECTION_ID'] = $this->arProduct['IBLOCK_SECTION_ID'] = (array)$this->arProduct['IBLOCK_SECTION_ID']; $this->arProduct['REAL_PARENT_IBLOCK_SECTION_ID'] = array(); while($arSectionsIDs){ if($arSections = Cache::CIBlockSection_GetList( array( 'CACHE' => array( 'MULTI' => 'Y', 'TAG' => Cache::GetIBlockCacheTag($this->productIblockId), 'GROUP' => array('IBLOCK_SECTION_ID'), ) ), array( 'ID' => $arSectionsIDs, 'IBLOCK_ID' => $this->productIblockId, '!SECTION_ID' => false, ), false, array( 'ID', 'IBLOCK_SECTION_ID', ) )){ $arSectionsIDs = array_keys($arSections); $this->arProduct['IBLOCK_SECTION_ID'] = array_unique(array_merge($this->arProduct['IBLOCK_SECTION_ID'], $arSectionsIDs)); if(!$this->arProduct['REAL_PARENT_IBLOCK_SECTION_ID']){ $this->arProduct['REAL_PARENT_IBLOCK_SECTION_ID'] = $arSectionsIDs; } } else{ $arSectionsIDs = array(); } } } // echo '<pre>'; // print_r($this->arProduct); // echo '</pre>'; $arLastRule = $arLastLevelRule = array(); foreach($arRulesTmp as $i => &$arRule){ if($this->_checkParsedCondition($arRule['PROPERTY_PRODUCTS_FILTER_VALUE'])){ $this->_replaceCond2ProductValues($arRule['PROPERTY_EXT_PRODUCTS_FILTER_VALUE']); $arRules['ALL'][$arRule['ID']] = &$arRule; foreach($arRule['PROPERTY_SHOW_PLACE_ENUM_ID'] as $showPlaceID){ if(!$arLastRule[$showPlaceID]){ if($arRule['PROPERTY_PRIORITY_VALUE'] > $arLastLevelRule[$showPlaceID]){ $arRules[$arShowPlacesFlipped[$showPlaceID]][$arRule['ID']] = &$arRule; if($arRule['PROPERTY_LAST_RULE_VALUE']){ $arLastRule[$showPlaceID] = true; } if($arRule['PROPERTY_LAST_LEVEL_RULE_VALUE']) { $arLastLevelRule[$showPlaceID] = $arRule['PROPERTY_PRIORITY_VALUE']; } } } } } } unset($arRule); } } } } $this->arRules = $arRules; } return $this->arRules; } public function getItemsFilter($showPlace = ''){ $arFilter = array(); if($this->arRules){ if($arRules = strlen($showPlace) ? $this->arRules[$showPlace] : $this->arRules['ALL']){ $arFilter = array_column($arRules, 'PROPERTY_EXT_PRODUCTS_FILTER_VALUE'); if(count($arFilter) > 1){ $arFilter['LOGIC'] = 'OR'; } else{ $arFilter = reset($arFilter); } $arFilter = array( 'LOGIC' => 'AND', ( ($propertyExtProductsFilterIblockId = CustomFilter::getSettingsIblockId('EXT_PRODUCTS_FILTER', $this->iblockId)) ? array('!ID' => $this->productId, 'IBLOCK_ID' => $propertyExtProductsFilterIblockId, 'ACTIVE' => 'Y') : array('!ID' => $this->productId, 'ACTIVE' => 'Y') ), $arFilter ); if($GLOBALS['arRegion'] && $GLOBALS['arTheme']['USE_REGIONALITY']['VALUE'] === 'Y' && $GLOBALS['arTheme']['USE_REGIONALITY']['DEPENDENT_PARAMS']['REGIONALITY_FILTER_ITEM']['VALUE'] === 'Y'){ $regionId = $GLOBALS['arRegion']['ID']; if($arSectionsIds = Solution::getSectionsIds_NotInRegion($this->iblockId, $regionId)){ $arFilter['!IBLOCK_SECTION_ID'] = $arSectionsIds; } } } } return $arFilter; } public function getItems($showPlace = '', $sort = 'rand', $order = 'ASC'){ if($arFilter = $this->getItemsFilter($showPlace)){ $displayElementSlider = ($this->arParams['DISPLAY_ELEMENT_SLIDER'] ? $this->arParams['DISPLAY_ELEMENT_SLIDER'] : 10); $propertyExtProductsFilterIblockId = CustomFilter::getSettingsIblockId('EXT_PRODUCTS_FILTER', $this->iblockId); // echo '<pre>'; // print_r($arFilter); // echo '</pre>'; return Cache::CIBLockElement_GetList( array( $sort => $order, 'CACHE' => array( 'TIME' => ($this->arParams['CACHE_TYPE'] !== 'N' ? $this->arParams['CACHE_TIME'] : 0), 'MULTI' => 'Y', 'TAG' => Cache::GetIBlockCacheTag($propertyExtProductsFilterIblockId), 'RESULT' => array('ID'), ) ), $arFilter, false, array('nTopCount' => $displayElementSlider), array( 'ID', 'IBLOCK_ID', ) ); } return false; } protected static function _getSiteIblockId($siteId){ return Cache::$arIBlocks[$siteId][self::IBLOCK_TYPE][self::IBLOCK_CODE][0] ? Cache::$arIBlocks[$siteId][self::IBLOCK_TYPE][self::IBLOCK_CODE][0] : false; } protected static function _getProductIblockId($productId){ return \CIBlockElement::GetIBlockByID($productId); } protected static function _getShowPlaces($iblockId){ $arPlaces = array(); if(($iblockId = intval($iblockId)) > 0){ if(!isset(self::$arShowPlacesByIblockId[$iblockId])){ $dbRes = \CIBlockProperty::GetPropertyEnum('SHOW_PLACE', array(), array('IBLOCK_ID' => $iblockId)); while($arVariant = $dbRes->Fetch()){ $arPlaces[$arVariant['XML_ID']] = $arVariant['ID']; } } else{ $arPlaces = self::$arShowPlacesByIblockId[$iblockId]; } } return $arPlaces; } protected static function _getUserGroups(){ $arGroups = array(); if(isset($GLOBALS['USER']) && $GLOBALS['USER']->IsAuthorized()){ $resUserGroup = \Bitrix\Main\UserGroupTable::getList( array( 'filter' => array( 'USER_ID' => $GLOBALS['USER']->GetID(), ), 'select' => array('GROUP_ID'), ) ); while($arGroup = $resUserGroup->fetch()){ $arGroups[] = $arGroup['GROUP_ID']; } } $arGroups[] = self::ALL_USERS_GROUP_ID; return $arGroups; } public static function isCrossSalesIblock($iblockId){ return $iblockId && isset(Cache::$arIBlocksInfo[$iblockId]) && strpos(Cache::$arIBlocksInfo[$iblockId]['CODE'], self::IBLOCK_CODE) !== false; } public function parseCondition($condition, $params) { $result = array(); if (!empty($condition) && is_array($condition)) { if ($condition['CLASS_ID'] === 'CondGroup') { if (!empty($condition['CHILDREN'])) { foreach ($condition['CHILDREN'] as $child) { $childResult = $this->parseCondition($child, $params); // is group if ($child['CLASS_ID'] === 'CondGroup') { $result[] = $childResult; } // same property names not overrides each other elseif (isset($result[key($childResult)])) { $fieldName = key($childResult); if (!isset($result['LOGIC'])) { if($fieldName == 0){ $result[$fieldName] = array($fieldName => $result[$fieldName]); $result = array_merge(array( 'LOGIC' => $condition['DATA']['All'], ), $result); } else{ $result = array( 'LOGIC' => $condition['DATA']['All'], array($fieldName => $result[$fieldName]) ); } } $result[][$fieldName] = $childResult[$fieldName]; } else { $result += $childResult; } } if (!empty($result)) { $this->parsePropertyCondition($result, $condition, $params); if (count($result) > 1) { $result['LOGIC'] = $condition['DATA']['All']; } } } } else { $result += $this->parseConditionLevel($condition, $params); } } return $result; } protected function parseConditionLevel($condition, $params) { $result = array(); if (!empty($condition) && is_array($condition)) { $name = $this->parseConditionName($condition); if (!empty($name)) { $operator = $this->parseConditionOperator($condition); $value = $this->parseConditionValue($condition, $name); $result[$operator.$name] = array( 'NAME' => $name, 'OPERATOR' => $operator, 'VALUE' => $value, ); if(strpos($name, 'CondIBProp') === false){ $this->arProductSelect[] = $name; } } } return $result; } protected function parseConditionName(array $condition) { $name = ''; $conditionNameMap = array( 'CondIBXmlID' => 'XML_ID', 'CondIBActive' => 'ACTIVE', 'CondIBSection' => 'IBLOCK_SECTION_ID', 'CondIBDateActiveFrom' => 'DATE_ACTIVE_FROM', 'CondIBDateActiveTo' => 'DATE_ACTIVE_TO', 'CondIBSort' => 'SORT', 'CondIBDateCreate' => 'DATE_CREATE', 'CondIBCreatedBy' => 'CREATED_BY', 'CondIBTimestampX' => 'TIMESTAMP_X', 'CondIBModifiedBy' => 'MODIFIED_BY', 'CondIBTags' => 'TAGS', 'CondCatQuantity' => 'CATALOG_QUANTITY', 'CondCatWeight' => 'CATALOG_WEIGHT', 'CondIBName' => 'NAME', 'CondIBElement' => 'ID', ); if (isset($conditionNameMap[$condition['CLASS_ID']])) { $name = $conditionNameMap[$condition['CLASS_ID']]; } elseif (strpos($condition['CLASS_ID'], 'CondIBProp') !== false) { $name = $condition['CLASS_ID']; } return $name; } protected function parseConditionOperator($condition) { $operator = ''; switch ($condition['DATA']['logic']) { case 'Equal': $operator = '=='; break; case 'Not': $operator = '!'; break; case 'Contain': $operator = '%'; break; case 'NotCont': $operator = '!%'; break; case 'Great': $operator = '>'; break; case 'Less': $operator = '<'; break; case 'EqGr': $operator = '>='; break; case 'EqLs': $operator = '<='; break; } return $operator; } protected function parseConditionValue($condition, $name) { $value = $condition['DATA']['value']; switch ($name) { case 'DATE_ACTIVE_FROM': case 'DATE_ACTIVE_TO': case 'DATE_CREATE': case 'TIMESTAMP_X': $value = ConvertTimeStamp($value, 'FULL'); break; } return $value; } protected function parsePropertyCondition(array &$result, array $condition, $params) { static $arPropertiesCodes; if (!empty($result)) { $subFilter = array(); foreach ($result as $name => $value) { if (!empty($result[$name]) && is_array($result[$name]) && !isset($result[$name]['NAME'])) { $this->parsePropertyCondition($result[$name], $condition, $params); } else { if (($ind = strpos($name, 'CondIBProp')) !== false) { list($prefix, $iblock, $propertyId) = explode(':', $name); $operator = $ind > 0 ? substr($prefix, 0, $ind) : ''; $catalogInfo = \CCatalogSku::GetInfoByIBlock($iblock); if(!isset($arPropertiesCodes)){ $arPropertiesCodes = array(); } if(!array_key_exists($propertyId, $arPropertiesCodes)){ $propCode = \CIBlockProperty::GetByID($propertyId, $iblock)->Fetch()['CODE']; $propCode = strtoupper($propCode); $arPropertiesCodes[$propertyId] = $propCode; } else{ $propCode = $arPropertiesCodes[$propertyId]; } if ( $catalogInfo['CATALOG_TYPE'] != \CCatalogSku::TYPE_CATALOG && $catalogInfo['IBLOCK_ID'] == $iblock ) { $subFilter[$operator.'PROPERTY_'.$propCode] = $value; $subFilter[$operator.'PROPERTY_'.$propCode]['NAME'] = 'PROPERTY_'.$propCode; $subFilter[$operator.'PROPERTY_'.$propCode]['PROPERTY'] = $propCode; } else { $result[$operator.'PROPERTY_'.$propCode] = $value; $result[$operator.'PROPERTY_'.$propCode]['NAME'] = 'PROPERTY_'.$propCode; $result[$operator.'PROPERTY_'.$propCode]['PROPERTY'] = $propCode; } $this->arProductSelect[] = 'PROPERTY_'.$propCode; unset($result[$name]); } } } if (!empty($subFilter) && !empty($catalogInfo)) { $offerPropFilter = array( 'IBLOCK_ID' => $catalogInfo['IBLOCK_ID'], 'ACTIVE_DATE' => 'Y', 'ACTIVE' => 'Y' ); if ($params['HIDE_NOT_AVAILABLE_OFFERS'] === 'Y') { $offerPropFilter['HIDE_NOT_AVAILABLE'] = 'Y'; } elseif ($params['HIDE_NOT_AVAILABLE_OFFERS'] === 'L') { $offerPropFilter[] = array( 'LOGIC' => 'OR', 'CATALOG_AVAILABLE' => 'Y', 'CATALOG_SUBSCRIBE' => 'Y' ); } if (count($subFilter) > 1) { $subFilter['LOGIC'] = $condition['DATA']['All']; $subFilter = array($subFilter); } $result += $subFilter; } } } protected function _checkParsedCondition($arParsedCondition){ if($arParsedCondition && is_array($arParsedCondition)){ foreach($arParsedCondition as $key => $value){ if(!is_array($value)){ continue; } if(is_numeric($key)){ $arParsedCondition[$key] = $this->_checkParsedCondition($value); } else{ unset($find); if(isset($value['PROPERTY'])){ $find = isset($this->arProduct['PROPERTY_'.$value['PROPERTY'].'_ENUM_ID']) ? $this->arProduct['PROPERTY_'.$value['PROPERTY'].'_ENUM_ID'] : $this->arProduct['PROPERTY_'.$value['PROPERTY'].'_VALUE']; } else{ $find = $this->arProduct[$value['NAME']]; } if($find){ if(is_array($value['VALUE'])){ foreach($value['VALUE'] as &$v){ if(($timestamp = MakeTimeStamp($v)) !== false){ $v = $timestamp; } } } else{ if(($timestamp = MakeTimeStamp($value['VALUE'])) !== false){ $value['VALUE'] = $timestamp; } } if(is_array($find)){ foreach($find as &$v){ if(($timestamp = MakeTimeStamp($v)) !== false){ $v = $timestamp; } } } else{ if(($timestamp = MakeTimeStamp($find)) !== false){ $find = $timestamp; } } } switch($value['OPERATOR']){ case '==': if(is_array($value['VALUE'])){ $arParsedCondition[$key] = isset($find) && in_array($find, $value['VALUE']); } else{ if(isset($find) && is_array($find)){ $arParsedCondition[$key] = in_array($value['VALUE'], $find); } else{ $arParsedCondition[$key] = isset($find) && $find == $value['VALUE']; } } break; case '!': if(is_array($value['VALUE'])){ $arParsedCondition[$key] = isset($find) && !in_array($find, $value['VALUE']); } else{ if(isset($find) && is_array($find)){ $arParsedCondition[$key] = !in_array($value['VALUE'], $find); } else{ $arParsedCondition[$key] = isset($find) && $find != $value['VALUE']; } } break; case '<': $arParsedCondition[$key] = isset($find) && $find < $value['VALUE']; break; case '<=': $arParsedCondition[$key] = isset($find) && $find <= $value['VALUE']; break; case '>': $arParsedCondition[$key] = isset($find) && $find > $value['VALUE']; break; case '>=': $arParsedCondition[$key] = isset($find) && $find >= $value['VALUE']; break; case '%': $arParsedCondition[$key] = isset($find) && strpos($find, $value['VALUE']) !== false; break; case '!%': $arParsedCondition[$key] = isset($find) && strpos($find, $value['VALUE']) === false; break; } } if($arParsedCondition['LOGIC'] === 'AND' && $arParsedCondition[$key] == false){ $arParsedCondition = false; break; } if($arParsedCondition['LOGIC'] === 'OR' && $arParsedCondition[$key] == true){ $arParsedCondition = true; break; } if(!isset($arParsedCondition['LOGIC'])){ if($arParsedCondition[$key] == true){ $arParsedCondition = true; } else{ $arParsedCondition = false; } } } if(is_array($arParsedCondition)){ if($arParsedCondition['LOGIC'] === 'OR'){ $arParsedCondition = false; } else{ $arParsedCondition = true; } } } return boolval($arParsedCondition); } protected function _replaceCond2ProductValues(&$arFilter){ static $arMultipleListPropertiesIDs; if($arFilter && is_array($arFilter)){ foreach($arFilter as $key => $value){ if(is_array($value)){ $this->_replaceCond2ProductValues($arFilter[$key]); } else{ if(strpos($value, 'CondCrossIBField') !== false){ list($prefix, $iblock, $field) = explode(':', $value); $bSIn = strpos($key, '=') !== false; $bNotEqual = strpos($key, '!') !== false; $bIn = $bEqual = !$bSIn && !$bNotEqual; if(preg_match('/^[^A_Z]*SECTION_ID[^A_Z]*$/i', $key)){ unset($arFilter[$key]); $value = $field === 'PARENT_IBLOCK_SECTION_ID' ? $this->arProduct['REAL_PARENT_IBLOCK_SECTION_ID'] : $this->arProduct['REAL_IBLOCK_SECTION_ID']; if($value){ if(count($value) == 1){ $value = reset($value); } if($bEqual){ $arFilter[] = array( 'SECTION_ID' => $value, 'INCLUDE_SUBSECTIONS' => 'Y', 'SECTION_GLOBAL_ACTIVE' => 'Y', ); } elseif($bNotEqual){ $arFilter[] = array( '!IBLOCK_SECTION_ID' => $value, '!SUBSECTION' => $value, ); } else{ // other operators } } else{ $arFilter[] = array( ($bEqual ? '' : '!').'SECTION_ID' => false, ); } } else{ // other fields } } elseif(strpos($value, 'CondCrossIBProp') !== false){ list($prefix, $iblock, $propertyId) = explode(':', $value); $find = isset($this->arProduct['PROPERTY_'.$propertyId.'_ENUM_ID']) ? $this->arProduct['PROPERTY_'.$propertyId.'_ENUM_ID'] : $this->arProduct['PROPERTY_'.$propertyId.'_VALUE']; $bSIn = strpos($key, '=') !== false; $bNotEqual = strpos($key, '!') !== false; $bIn = $bEqual = !$bSIn && !$bNotEqual; if($bNotEqual || $bSIn){ if($iblock){ if(!isset($arrayrMultipleListPropertiesIDs)){ $arMultipleListPropertiesIDs = array(); $dbRes = \CIBlockProperty::GetList( array(), array('IBLOCK_ID' => $iblock, 'ACTIVE' => 'Y', 'PROPERTY_TYPE' => 'L', 'MULTIPLE' => 'Y') ); while($arProperty = $dbRes->Fetch()){ $arMultipleListPropertiesIDs[$arProperty['ID']] = true; } } } } if(!isset($find) || !$find){ if($bEqual || $bIn || $bSIn){ $arFilter[$key] = false; } elseif($bNotEqual){ $arFilter[$key] = false; } } elseif(isset($find)){ if(($bNotEqual || $bSIn) && $arMultipleListPropertiesIDs && $arMultipleListPropertiesIDs[$propertyId]){ unset($arFilter[$key]); $arFind = is_array($find) ? $find : array($find); foreach($arFind as $find){ $arFilter[] = array( ($bNotEqual ? '!' : '').'ID' => \CIBlockElement::SubQuery('ID', array('IBLOCK_ID' => $iblock, 'PROPERTY_'.$propertyId => $find)), ); } } else{ $arFilter[$key] = $find; } } } } } } } } ?>