diff --git a/admin/main/submenu/settings/include/config.php b/admin/main/submenu/settings/include/config.php
index 3cfe04b..2c6336a 100644
--- a/admin/main/submenu/settings/include/config.php
+++ b/admin/main/submenu/settings/include/config.php
@@ -46,4 +46,18 @@ $data['env'] = $app->env();
+
+
+
+
+ renderCustomClassChecker(
+ 'Bitrix\IBlock\Component\ElementList',
+ 'Bitrix\IBlock\Component\OriginElementList',
+ 'Ixrs\Catalog\Interfaces\IBlock\Component\IElementList'
+ );
+ ?>
+
\ No newline at end of file
diff --git a/init.php b/init.php
new file mode 100644
index 0000000..3965595
--- /dev/null
+++ b/init.php
@@ -0,0 +1,29 @@
+isIncludeFileToInitPhp()){
+ return false;
+}
+catalog_base_app()->isIncludeFileToInitPhp(true);
+
+$isAdminSection = \Bitrix\Main\Application::getInstance()->getContext()->getRequest()->isAdminSection();
+
+
+$dbType = Application::getConnection()->getType();
+Loader::includeModule('iblock');
+$arClasses = [
+ 'Bitrix\Iblock\Component\ElementList' => 'modules/iblock/lib/component/elementlist.php',
+];
+
+Loader::registerAutoLoadClasses('ixrs.catalog', $arClasses);
diff --git a/lib/Interfaces/IBlock/Component/IElementList.php b/lib/Interfaces/IBlock/Component/IElementList.php
new file mode 100644
index 0000000..1fddbcb
--- /dev/null
+++ b/lib/Interfaces/IBlock/Component/IElementList.php
@@ -0,0 +1,8 @@
+factory()->iBlock()->getEntityById($iBlockId);
+ $iBlockFactory = app()->factory()->main()->getIBlockFactory();
+ $iBlockEntity = $iBlockFactory->getEntityById($iBlockId);
+
+ $propertyFactory = $af->getPropertyFactory();
+ if($iBlockEntity->getCatalogEntity()->hasOffers()){
+ $offerAf = app()->factory()->iBlock()->getEntityById($iBlockEntity->getCatalogEntity()->getOfferBlockId());
+ $offerPropertyFactory = $offerAf->getPropertyFactory();
+
+ foreach ($globalFilter as $key => $values){
+ $res = \Ixrs\Catalog\Support\IBlock::getOperationFilter($key);
+ // $res = \CIBlock::MkOperationFilter($key);
+
+ if(!$res) {
+ continue;
+ }
+
+ $propertyId = $res['ID'];
+ $propertyEntity = $propertyFactory->getEntityById($propertyId);
+ if(!$propertyEntity){
+ continue;
+ }
+ $offerPropertyEntity = $offerPropertyFactory->getCollection([
+ '=CODE' => $propertyEntity->getCode(),
+ '=XML_ID' => $propertyEntity->getXmlId(),
+ '=PROPERTY_TYPE' => $propertyEntity->getBaseType(),
+ '=USER_TYPE' => $propertyEntity->getUserType(),
+ '=ACTIVE' => 'Y',
+ ])->first();
+
+ if(!$offerPropertyEntity){
+ continue;
+ }
+
+ /**
+ * @var array $values
+ */
+ $oKey = $res['PREFIX'] . 'PROPERTY_' . $offerPropertyEntity->getId();
+ $values = (array)$values;
+
+ $pFilter[$propertyId]['E'] = [];
+ $pFilter[$propertyId]['O'] = [];
+
+ foreach ($values as $value){
+ $oValue = $value;
+ if($propertyEntity->getBaseType() === 'L' && $propertyEntity->getValueFactory()){
+ $pve = $propertyEntity->getValueFactory()->getEntityById($oValue);
+ $x = $pve->get('XML_ID');
+ if($x){
+ $opve = $offerPropertyEntity->getValueFactory()->getCollection(['XML_ID' => $x])->first();
+ $oValue = $opve?->getId();
+ }
+ else {
+ $oValue = null;
+ }
+ }
+ if($oValue){
+ if(isset($globalFilter[$key])){
+ $globalFilter[$key] = collect($globalFilter[$key])->deleteValues([$value])->toArray();
+ }
+ $pFilter[$propertyId]['E'][$key][] = $value;
+ $pFilter[$propertyId]['O'][$oKey][] = $oValue;
+ if(isset($globalFilter['OFFERS'][$oKey])){
+ $globalFilter['OFFERS'][$oKey] =
+ collect($globalFilter['OFFERS'][$oKey])->deleteValues([$oValue])->toArray();
+ }
+ }
+ }
+
+ if($pFilter[$propertyId]['E'][$key] || $pFilter[$propertyId]['O'][$oKey]){
+ if($globalFilter[$key]){
+ $pFilter[$propertyId]['E'][$key] = array_merge($pFilter[$propertyId]['E'][$key], $globalFilter[$key]);
+ unset($globalFilter[$key]);
+ }
+ if($globalFilter['OFFERS'][$oKey]){
+ $pFilter[$propertyId]['O'][$oKey] = array_merge($pFilter[$propertyId]['O'][$oKey], $globalFilter['OFFERS'][$oKey]);
+ unset($globalFilter['OFFERS'][$oKey]);
+ }
+ }
+
+ if(!$globalFilter[$key]){
+ unset($globalFilter[$key]);
+ }
+ if(!$globalFilter['OFFERS'][$oKey]){
+ unset($globalFilter['OFFERS'][$oKey]);
+ }
+ }
+ }
+
+ /** inject */
+ $oFilter = [];
+ if($pFilter){
+ foreach ($pFilter as $ePId => $item) {
+ $data = [];
+
+ foreach ($item['E'] as $fKey => $values) {
+ foreach ($values as $value){
+ $data[] = [$fKey => $value];
+ }
+ }
+ foreach ($item['O'] as $fKey => $values) {
+ $oFilter[$fKey] = $values;
+ foreach ($values as $value){
+ $data[] = ['=ID' => \CIBlockElement::SubQuery(
+ 'PROPERTY_'.$iBlockEntity->getCatalogEntity()->getSkuPropertyId(),
+ array_merge([
+ 'IBLOCK_ID' => $iBlockEntity->getCatalogEntity()->getOfferBlockId(),
+ 'ACTIVE_DATE' => 'Y',
+ 'ACTIVE' => 'Y',
+ ], [$fKey => $value])
+ )];
+ }
+ }
+
+ if($data){
+ $globalFilter[] = array_merge([
+ 'LOGIC' => 'OR',
+ ], $data);
+ }
+ }
+
+ //if(!is_array($this->storage['SUB_FILTER'])){
+ // $this->storage['SUB_FILTER'] = [];
+ //}
+ //foreach ($oFilter as $fKey => $values) {
+ // if(isset($this->storage['SUB_FILTER'][$fKey])){
+ // $this->storage['SUB_FILTER'][$fKey] =
+ // collect((array)$this->storage['SUB_FILTER'][$fKey])->merge($values)->unique()->toArray();
+ // }
+ // else {
+ // $this->storage['SUB_FILTER'][$fKey] = $values;
+ // }
+ //}
+ }
+ return $globalFilter;
+ }
+}
\ No newline at end of file
diff --git a/lib/Support/IBlock.php b/lib/Support/IBlock.php
new file mode 100644
index 0000000..8419f91
--- /dev/null
+++ b/lib/Support/IBlock.php
@@ -0,0 +1,42 @@
+<' => 'NB', //not between
+ '!=' => 'NI', //not Identical
+ '!%' => 'NS', //not substring
+ '><' => 'B', //between
+ '>=' => 'GE', //greater or equal
+ '<=' => 'LE', //less or equal
+ '=' => 'I', //Identical
+ '%' => 'S', //substring
+ '?' => '?', //logical
+ '>' => 'G', //greater
+ '<' => 'L', //less
+ '!' => 'N', // not field LIKE val
+ '*' => 'FT', // partial full text match
+ '*=' => 'FTI', // identical full text match
+ '*%' => 'FTL', // partial full text match based on LIKE
+ ];
+
+ public static function getOperationFilter($key)
+ {
+ $re = '/^(!><|!=|!%|><|>=|<=|=|%|\?|>|<|!|\*|\*=|\*%)?(PROPERTY_)(\d+)$/m';
+
+ $matches = [];
+ $r = preg_match($re, $key, $matches);
+
+ if($r){
+ return [
+ 'FIELD' => mb_strtoupper($matches[2] . $matches[3]),
+ 'OPERATION' => static::$operations[$matches[1]]??'',
+ 'PREFIX' => $matches[1],
+ 'ID' => $matches[3],
+ ];
+ }
+ return [];
+ }
+}
\ No newline at end of file
diff --git a/lib/Support/SmartFilter.php b/lib/Support/SmartFilter.php
new file mode 100644
index 0000000..da4e02f
--- /dev/null
+++ b/lib/Support/SmartFilter.php
@@ -0,0 +1,385 @@
+factory()->iBlock()->getEntityById($iBlockId);
+ $iBlockFactory = app()->factory()->main()->getIBlockFactory();
+ $iBlockEntity = $iBlockFactory->getEntityById($iBlockId);
+
+ if(!$iBlockEntity->getCatalogEntity()->hasOffers()) {
+ return $combo;
+ }
+ $propertyFactory = $af->getPropertyFactory();
+ $offerAf = app()->factory()->iBlock()->getEntityById($iBlockEntity->getCatalogEntity()->getOfferBlockId());
+ $offerPropertyFactory = $offerAf->getPropertyFactory();
+
+ foreach ($combo as $i => $combination){
+ $result[] = $combination;
+ foreach ($combination as $propertyId => $value){
+ $propertyEntity = $propertyFactory->getEntityById($propertyId);
+ if(!$propertyEntity){
+ continue;
+ }
+// $offerPropertyEntity = $offerPropertyFactory->getCollection([
+// '=CODE' => $propertyEntity->getCode(),
+// '=XML_ID' => $propertyEntity->getXmlId(),
+// '=PROPERTY_TYPE' => $propertyEntity->getBaseType(),
+// '=USER_TYPE' => $propertyEntity->getUserType(),
+// '=ACTIVE' => 'Y',
+// ])->first();
+ $offerPropertyEntity = $offerPropertyFactory->getEntityByCode($propertyEntity->getCode());
+ if(!$offerPropertyEntity){
+ continue;
+ }
+ if(!isset($combination[$offerPropertyEntity->getId()])){
+ continue;
+ }
+ if($combination[$offerPropertyEntity->getId()] === false){
+ continue;
+ }
+
+ $v = $combo[$i][$offerPropertyEntity->getId()];
+ unset($combo[$i][$offerPropertyEntity->getId()]);
+ $c = $combo[$i];
+ $c[$propertyId] = $v;
+
+ $result[] = $c;
+
+
+ }
+ }
+
+ return $result;
+ }
+
+
+ public static function getPreparedItems($iBlockId, $items, $filterName, $deleteOffersProps = true)
+ {
+ //pre('getPreparedItems ' . ($deleteOffersProps?'true':'false'));
+ $af = app()->factory()->iBlock()->getEntityById($iBlockId);
+ $iBlockFactory = app()->factory()->main()->getIBlockFactory();
+ $iBlockEntity = $iBlockFactory->getEntityById($iBlockId);
+ $propertyFactory = $af->getPropertyFactory();
+
+ if(!$iBlockEntity->getCatalogEntity()->hasOffers()) {
+ return $items;
+ }
+
+
+ $offerAf = app()->factory()->iBlock()->getEntityById($iBlockEntity->getCatalogEntity()->getOfferBlockId());
+ $offerPropertyFactory = $offerAf->getPropertyFactory();
+
+ foreach ($items as $propertyId => $property){
+
+ $propertyEntity = $propertyFactory->getEntityById($propertyId);
+ if(!$propertyEntity){
+ continue;
+ }
+
+ $offerPropertyEntity = $offerPropertyFactory->getEntityByCode($propertyEntity->getCode());
+ if(!$offerPropertyEntity){
+ continue;
+ }
+
+ if(!isset($items[$offerPropertyEntity->getId()])){
+ continue;
+ }
+
+ $oValues = $items[$offerPropertyEntity->getId()]['VALUES'];
+ $oValuesReserve = $oValues;
+ foreach ($oValuesReserve as &$oValue){
+ $oValue['IBLOCK_ID'] = $offerAf->getBlockId();
+ $oValue['PROPERTY_ID'] = $offerPropertyEntity->getId();
+ }
+ unset($oValue);
+
+ foreach ($oValues as $propertyValueId => $propertyValue){
+
+ $key = null;
+ foreach ($items[$propertyId]['VALUES'] as $propertyValueId2 => $propertyValueValue){
+ if($propertyValue['VALUE'] === $propertyValueValue['VALUE']){
+ $key = $propertyValueId2;
+ break;
+ }
+ }
+ if(is_null($key)){
+ continue;
+ }
+
+ unset($oValuesReserve[$propertyValueId]);
+
+ if($deleteOffersProps){
+ unset($items[$offerPropertyEntity->getId()]['VALUES'][$propertyValueId]);
+ if(!$items[$offerPropertyEntity->getId()]['VALUES']){
+ unset($items[$offerPropertyEntity->getId()]);
+ }
+ }
+
+ $items[$propertyId]['VALUES'][$key]['DISABLED'] ??= false;
+ $propertyValue['DISABLED'] ??= false;
+ $items[$propertyId]['VALUES'][$key]['DISABLED'] =
+ $items[$propertyId]['VALUES'][$key]['DISABLED'] && $propertyValue['DISABLED'];
+
+ $items[$propertyId]['VALUES'][$key]['CHECKED'] ??= false;
+ $propertyValue['CHECKED'] ??= false;
+ $items[$propertyId]['VALUES'][$key]['CHECKED'] =
+ $items[$propertyId]['VALUES'][$key]['CHECKED'] || $propertyValue['CHECKED'];
+
+
+ //if($items[$propertyId]['VALUES'][$key]['CONTROL_ID'] !== $propertyValue['CONTROL_ID']) {
+ // $items[$propertyId]['VALUES'][$key]['ELEMENT_COUNT'] += $propertyValue['ELEMENT_COUNT'];
+ //}
+ }
+
+ //foreach ($items[$propertyId]['VALUES'] as $propertyValueId => &$propertyValue){
+ // $propertyValue['CONTROL_NAME_ALT'] = $filterName . '_' . $propertyEntity->getId();
+ // $propertyValue['CONTROL_NAME'] = $propertyValue['CONTROL_NAME_ALT'] . '_' . $propertyValue['HTML_VALUE_ALT'];
+ // $propertyValue['CONTROL_ID'] = $propertyValue['CONTROL_NAME_ALT'] . '_' . $propertyValue['HTML_VALUE_ALT'];
+ //}
+ //unset($propertyValue);
+
+
+ if($deleteOffersProps) {
+ unset($items[$offerPropertyEntity->getId()]);
+ $items[$propertyId]['VALUES'] = $items[$propertyId]['VALUES'] + $oValuesReserve;
+ }
+
+ }
+
+ return $items;
+ }
+
+ public static function getPreparedFacetIndex($iBlockId, $items, $filterName, $deleteOffersProps = true)
+ {
+ //pre('getPreparedFacetIndex');
+ $af = app()->factory()->iBlock()->getEntityById($iBlockId);
+ $iBlockFactory = app()->factory()->main()->getIBlockFactory();
+ $iBlockEntity = $iBlockFactory->getEntityById($iBlockId);
+ $propertyFactory = $af->getPropertyFactory();
+
+ if(!$iBlockEntity->getCatalogEntity()->hasOffers()) {
+ return $items;
+ }
+
+
+ $offerAf = app()->factory()->iBlock()->getEntityById($iBlockEntity->getCatalogEntity()->getOfferBlockId());
+ $offerPropertyFactory = $offerAf->getPropertyFactory();
+
+ foreach ($items as $propertyId => $values){
+
+ $propertyEntity = $propertyFactory->getEntityById($propertyId);
+ if(!$propertyEntity){
+ continue;
+ }
+
+ $offerPropertyEntity = $offerPropertyFactory->getEntityByCode($propertyEntity->getCode());
+ if(!$offerPropertyEntity){
+ continue;
+ }
+
+ if(!isset($items[$offerPropertyEntity->getId()])){
+ continue;
+ }
+ $oValues = $items[$offerPropertyEntity->getId()];
+ $oValuesReserve = $oValues;
+
+ foreach ($oValues as $facetId => $propertyValue){
+ $key = null;
+ foreach ($items[$propertyId] as $facetId2 => $propertyValueValue){
+ if($propertyValue['VALUE'] === $propertyValueValue['VALUE']){
+ $key = $facetId2;
+ break;
+ }
+ }
+ if(is_null($key)){
+ continue;
+ }
+
+ unset($oValuesReserve[$facetId]);
+ if($deleteOffersProps){
+ unset($items[$offerPropertyEntity->getId()][$facetId]);
+ if(!$items[$offerPropertyEntity->getId()]){
+ unset($items[$offerPropertyEntity->getId()]);
+ }
+ }
+
+ $items[$propertyId][$key]['DISABLED'] ??= false;
+ $propertyValue['DISABLED'] ??= false;
+ $items[$propertyId][$key]['DISABLED'] =
+ $items[$propertyId][$key]['DISABLED'] && $propertyValue['DISABLED'];
+
+ $items[$propertyId][$key]['CHECKED'] ??= false;
+ $propertyValue['CHECKED'] ??= false;
+ $items[$propertyId][$key]['CHECKED'] =
+ $items[$propertyId][$key]['CHECKED'] || $propertyValue['CHECKED'];
+
+ if($items[$propertyId][$key]['CONTROL_ID'] !== $propertyValue['CONTROL_ID']) {
+ $items[$propertyId][$key]['ELEMENT_COUNT'] += $propertyValue['ELEMENT_COUNT'];
+ }
+ }
+
+ //foreach ($items[$propertyId] as $facetId => &$propertyValue){
+ // $propertyValue['CONTROL_NAME_ALT'] = $filterName . '_' . $propertyEntity->getId();
+ // $propertyValue['CONTROL_NAME'] = $propertyValue['CONTROL_NAME_ALT'] . '_' . $propertyValue['HTML_VALUE_ALT'];
+ // $propertyValue['CONTROL_ID'] = $propertyValue['CONTROL_NAME_ALT'] . '_' . $propertyValue['HTML_VALUE_ALT'];
+ //}
+ //unset($propertyValue);
+
+
+ //if($deleteOffersProps) {
+ //$items[$propertyId] = $items[$propertyId] + $oValuesReserve;
+ //}
+ }
+
+ return $items;
+ }
+
+ /**
+ * property id to offer property id
+ *
+ * @param $iBlockId
+ * @param $propertyId
+ * @return int|string|null
+ */
+ public static function getOfferPropertyId($iBlockId, $propertyId)
+ {
+
+ $af = app()->factory()->iBlock()->getEntityById($iBlockId);
+ $iBlockFactory = app()->factory()->main()->getIBlockFactory();
+ $iBlockEntity = $iBlockFactory->getEntityById($iBlockId);
+ $propertyFactory = $af->getPropertyFactory();
+
+ if(!$iBlockEntity->getCatalogEntity()->hasOffers()) {
+ return null;
+ }
+
+ $propertyEntity = $propertyFactory->getEntityById($propertyId);
+ if(!$propertyEntity){
+ return null;
+ }
+
+ $offerAf = app()->factory()->iBlock()->getEntityById($iBlockEntity->getCatalogEntity()->getOfferBlockId());
+ $offerPropertyFactory = $offerAf->getPropertyFactory();
+
+ $offerPropertyEntity = $offerPropertyFactory->getEntityByCode($propertyEntity->getCode());
+
+ return $offerPropertyEntity?->getId();
+ }
+
+ /**
+ * @param $iBlockId
+ * @param $propertyId
+ * @param int|string $propertyValueIndex модет быть id или xmlId
+ * @return void|null
+ */
+ public static function getOfferPropertyValueIndex($iBlockId, $propertyId, $propertyValueIndex)
+ {
+ $af = app()->factory()->iBlock()->getEntityById($iBlockId);
+ $iBlockFactory = app()->factory()->main()->getIBlockFactory();
+ $iBlockEntity = $iBlockFactory->getEntityById($iBlockId);
+ $propertyFactory = $af->getPropertyFactory();
+ $propertyEntity =$propertyFactory->getEntityById($propertyId);
+
+ if($iBlockEntity->getCatalogEntity()->hasOffers()) {
+ $offerAf = app()->factory()->iBlock()->getEntityById($iBlockEntity->getCatalogEntity()->getOfferBlockId());
+ $offerPropertyFactory = $offerAf->getPropertyFactory();
+
+
+ $offerPropertyEntity = $offerPropertyFactory->getEntityByCode($propertyEntity->getCode());
+
+ if (!$offerPropertyEntity) {
+ return null;
+ }
+ if($propertyEntity->getBaseType() === 'L' && $propertyEntity->getValueFactory()){
+ $pve = $propertyEntity->getValueFactory()->getEntityById($propertyValueIndex);
+ $xmlId = $pve?->getXmlId();
+ if($xmlId){
+ $opve = $offerPropertyEntity->getValueFactory()->getEntityByXmlId($xmlId);
+ return $opve?->getId();
+ }
+ return null;
+ }
+ return $propertyValueIndex;
+ }
+ }
+
+ /**
+ * @param $iBlockId
+ * @param $propertyId
+ * @param int|string $propertyValueIndex модет быть id или xmlId
+ * @return void|null
+ */
+ public static function getPropertyValueIndex($iBlockId, $oPropertyId, $oPropertyValueIndex)
+ {
+ $af = app()->factory()->iBlock()->getEntityById($iBlockId);
+ $iBlockFactory = app()->factory()->main()->getIBlockFactory();
+ $iBlockEntity = $iBlockFactory->getEntityById($iBlockId);
+ $propertyFactory = $af->getPropertyFactory();
+
+ if(!$iBlockEntity->getCatalogEntity()->hasOffers()) {
+ return null;
+ }
+ $offerAf = app()->factory()->iBlock()->getEntityById($iBlockEntity->getCatalogEntity()->getOfferBlockId());
+ $offerPropertyFactory = $offerAf->getPropertyFactory();
+ $offerPropertyEntity = $offerPropertyFactory->getEntityById($oPropertyId);
+
+ if(!$offerPropertyEntity){
+ return null;
+ }
+ //pre("{$offerPropertyEntity->getId()} {$offerPropertyEntity->getCode()} {$oPropertyValueIndex}");
+ $propertyEntity = $propertyFactory->getEntityByCode($offerPropertyEntity->getCode());
+
+ if (!$propertyEntity) {
+ return null;
+ }
+ if($offerPropertyEntity->getBaseType() === 'L' && $offerPropertyEntity->getValueFactory()){
+ $pve = $offerPropertyEntity->getValueFactory()->getEntityById($oPropertyValueIndex);
+ $xmlId = $pve?->getXmlId();
+ if($xmlId){
+ $opve = $propertyEntity->getValueFactory()->getEntityByXmlId($xmlId);
+ return $opve?->getId();
+ }
+ return null;
+ }
+ return $oPropertyValueIndex;
+ }
+
+ /**
+ * offer property id to property id
+ *
+ * @param $iBlockId
+ * @param $offerPropertyId
+ * @return int|string|null
+ */
+ public static function getPropertyId($iBlockId, $offerPropertyId)
+ {
+
+ $af = app()->factory()->iBlock()->getEntityById($iBlockId);
+ $iBlockFactory = app()->factory()->main()->getIBlockFactory();
+ $iBlockEntity = $iBlockFactory->getEntityById($iBlockId);
+ $propertyFactory = $af->getPropertyFactory();
+
+ if(!$iBlockEntity->getCatalogEntity()->hasOffers()) {
+ return null;
+ }
+ $offerAf = app()->factory()->iBlock()->getEntityById($iBlockEntity->getCatalogEntity()->getOfferBlockId());
+ $offerPropertyFactory = $offerAf->getPropertyFactory();
+ $offerPropertyEntity = $offerPropertyFactory->getEntityById($offerPropertyId);
+
+ if(!$offerPropertyEntity){
+ return null;
+ }
+
+ $propertyEntity = $propertyFactory->getEntityByCode($offerPropertyEntity->getCode());
+
+ return $propertyEntity?->getId();
+ }
+}
\ No newline at end of file
diff --git a/lib/Support/combo.php.example b/lib/Support/combo.php.example
new file mode 100644
index 0000000..58453f8
--- /dev/null
+++ b/lib/Support/combo.php.example
@@ -0,0 +1,58 @@
+
+ [
+ 876 => 'Акция',
+ 877 => 'SHIKstudio',
+ 878 => false,
+ 1247 => 'Россия',
+ 1250 => false,
+ 906 => false,
+ 1251 => false,
+ 1252 => false,
+ 1255 => false,
+ 1256 => false,
+ 1257 => false,
+ 1258 => false,
+ 1259 => false,
+ 1260 => false,
+ 1261 => false,
+ 1262 => false,
+ 1263 => false,
+ 1264 => false,
+ 1265 => false,
+ 1266 => false,
+ 1267 => false,
+ 1269 => false,
+ 1489 => false,
+ 1 => false,
+ ],
+ 1 =>
+ [
+ 876 => 'Акция',
+ 877 => 'SHIKstudio',
+ 878 => 'Y',
+ 1247 => 'Россия',
+ 1250 => false,
+ 906 => false,
+ 1251 => false,
+ 1252 => false,
+ 1255 => false,
+ 1256 => false,
+ 1257 => false,
+ 1258 => false,
+ 1259 => false,
+ 1260 => false,
+ 1261 => false,
+ 1262 => false,
+ 1263 => false,
+ 1264 => false,
+ 1265 => false,
+ 1266 => false,
+ 1267 => false,
+ 1269 => false,
+ 1489 => false,
+ 1 => false,
+ ],
+ // ...
+];
\ No newline at end of file
diff --git a/lib/Support/facet_index.php.example b/lib/Support/facet_index.php.example
new file mode 100644
index 0000000..acddd39
--- /dev/null
+++ b/lib/Support/facet_index.php.example
@@ -0,0 +1,38 @@
+ // property id
+ [
+ 394 => // FACET_VALUE
+ [
+ 'CONTROL_ID' => 'MAX_SMART_FILTER_876_4133288916',
+ 'CONTROL_NAME' => 'MAX_SMART_FILTER_876_4133288916',
+ 'CONTROL_NAME_ALT' => 'MAX_SMART_FILTER_876',
+ 'HTML_VALUE_ALT' => 4133288916,
+ 'HTML_VALUE' => 'Y',
+ 'VALUE' => 'Новинка',
+ 'SORT' => 300,
+ 'UPPER' => 'НОВИНКА',
+ 'FLAG' => true,
+ 'URL_ID' => 'new',
+ 'FACET_VALUE' => '394',
+ 'ELEMENT_COUNT' => '207',
+ ],
+ 395 =>
+ [
+ 'CONTROL_ID' => 'MAX_SMART_FILTER_876_2170276674',
+ 'CONTROL_NAME' => 'MAX_SMART_FILTER_876_2170276674',
+ 'CONTROL_NAME_ALT' => 'MAX_SMART_FILTER_876',
+ 'HTML_VALUE_ALT' => 2170276674,
+ 'HTML_VALUE' => 'Y',
+ 'VALUE' => 'Акция',
+ 'SORT' => 400,
+ 'UPPER' => 'АКЦИЯ',
+ 'FLAG' => true,
+ 'URL_ID' => 'stock',
+ 'FACET_VALUE' => '395',
+ 'ELEMENT_COUNT' => '56',
+ ],
+ ],
+ // 877 => ...
+];
\ No newline at end of file
diff --git a/modules/iblock/lib/component/OriginElementList.php b/modules/iblock/lib/component/OriginElementList.php
new file mode 100644
index 0000000..faaa8d2
--- /dev/null
+++ b/modules/iblock/lib/component/OriginElementList.php
@@ -0,0 +1,11 @@
+' . $fileContent);
+}
+
+use Ixrs\Catalog\Interfaces\IBlock\Component\IElementList;
+
+/**
+ * @see bitrix/modules/iblock/lib/component/elementlist.php
+ */
+class ElementList extends OriginElementList implements IElementList
+{
+
+ protected function initSubQuery()
+ {
+ $this->storage['SUB_FILTER'] = array();
+
+ if (
+ $this->useCatalog
+ && !$this->isMultiIblockMode()
+ && $this->offerIblockExist($this->arParams['IBLOCK_ID'])
+ )
+ {
+ $catalogFilter = array();
+ foreach ($this->globalFilter as $key => $value)
+ {
+ if (\CProductQueryBuilder::isCatalogFilterField($key))
+ {
+ //TODO: remove this hack after new catalog.section filter
+ if ($key === '=PRODUCT_UF_PRODUCT_MAPPING')
+ {
+ continue;
+ }
+ $catalogFilter[$key] = $value;
+ unset($this->globalFilter[$key]);
+ }
+ }
+
+ $iblock = $this->storage['CATALOGS'][$this->arParams['IBLOCK_ID']];
+
+ /** inject */
+ $this->globalFilter = \Ixrs\Catalog\Support\ElementList::getGlobalFilter($this->arParams['IBLOCK_ID'], $this->globalFilter);
+ /** inject end */
+
+ $offersFilterExists = !empty($this->globalFilter['OFFERS']) && is_array($this->globalFilter['OFFERS']);
+
+ if ($offersFilterExists)
+ {
+ $this->storage['SUB_FILTER'] = array_merge($this->globalFilter['OFFERS'], $catalogFilter);
+ $this->storage['SUB_FILTER']['IBLOCK_ID'] = $iblock['IBLOCK_ID'];
+ $this->storage['SUB_FILTER']['ACTIVE_DATE'] = 'Y';
+ $this->storage['SUB_FILTER']['ACTIVE'] = 'Y';
+
+ if ($this->arParams['HIDE_NOT_AVAILABLE'] === 'Y')
+ {
+ $this->storage['SUB_FILTER']['AVAILABLE'] = 'Y';
+ }
+
+ $this->filterFields['=ID'] = \CIBlockElement::SubQuery(
+ 'PROPERTY_'.$iblock['SKU_PROPERTY_ID'],
+ $this->storage['SUB_FILTER']
+ );
+ }
+ elseif (!empty($catalogFilter))
+ {
+ $this->storage['SUB_FILTER'] = $catalogFilter;
+ $this->storage['SUB_FILTER']['IBLOCK_ID'] = $iblock['IBLOCK_ID'];
+ $this->storage['SUB_FILTER']['ACTIVE_DATE'] = 'Y';
+ $this->storage['SUB_FILTER']['ACTIVE'] = 'Y';
+
+ $this->filterFields[] = array(
+ 'LOGIC' => 'OR',
+ array($catalogFilter),
+ '=ID' => \CIBlockElement::SubQuery(
+ 'PROPERTY_'.$iblock['SKU_PROPERTY_ID'],
+ $this->storage['SUB_FILTER']
+ ),
+ );
+ }
+
+
+
+ }
+ }
+
+}
\ No newline at end of file