36 $this->valid = \CIBlock::getArrayByID($this->iblockId,
"PROPERTY_INDEX") ===
"Y";
38 if (self::$catalog ===
null)
40 self::$catalog = \Bitrix\Main\Loader::includeModule(
"catalog");
45 $catalogInfo = \CCatalogSKU::getInfoByProductIBlock($this->iblockId);
46 if (!empty($catalogInfo) && is_array($catalogInfo))
48 $this->skuIblockId = $catalogInfo[
"IBLOCK_ID"];
49 $this->skuPropertyId = $catalogInfo[
"SKU_PROPERTY_ID"];
50 $this->valid = $this->valid && \CIBlock::getArrayByID($this->skuIblockId,
"PROPERTY_INDEX") ===
"Y";
54 $this->dictionary =
new Dictionary($this->iblockId);
55 $this->storage =
new Storage($this->iblockId);
57 $this->valid = $this->valid && $this->dictionary->isExists();
145 public function query(array $filter, array $facetTypes = array(), $facetId = 0)
147 $connection = \Bitrix\Main\Application::getConnection();
148 $sqlHelper = $connection->getSqlHelper();
160 $element = new \CIBlockElement;
161 $element->strField =
"ID";
162 $element->prepareSql(array(
"ID"), $filter,
false,
false);
163 $elementFrom = $element->sFrom;
164 $elementWhere = $element->sWhere;
176 "where" => $this->
getWhere($facetId),
177 "facet" => array($facetId),
182 foreach ($facetFilter as $facetId)
187 foreach ($facets as $i => $facetWhereAndFacets)
189 if ($facetWhereAndFacets[
"where"] ==
$where)
191 $facets[$i][
"facet"][] = $facetId;
201 "facet" => array($facetId),
208 foreach ($facets as $facetWhereAndFacets)
210 $where = $facetWhereAndFacets[
"where"];
211 $facetFilter = $facetWhereAndFacets[
"facet"];
213 $sqlSearch = array(
"1=1");
221 ,MIN(F.VALUE_NUM) MIN_VALUE_NUM
222 ,MAX(F.VALUE_NUM) MAX_VALUE_NUM
223 ".($connection instanceof \Bitrix\Main\DB\MysqlCommonConnection
224 ?
",MAX(case when LOCATE('.', F.VALUE_NUM) > 0 then LENGTH(SUBSTRING_INDEX(F.VALUE_NUM, '.', -1)) else 0 end)"
225 :
",MAX(".$sqlHelper->getLengthFunction(
"ABS(F.VALUE_NUM) - FLOOR(ABS(F.VALUE_NUM))").
"+1-".$sqlHelper->getLengthFunction(
"0.1").
")"
227 ,COUNT(DISTINCT F.ELEMENT_ID) ELEMENT_COUNT
231 INNER JOIN ".$this->storage->getTableName().
" F ON BE.ID = F.ELEMENT_ID"
232 :$this->storage->getTableName().
" F"
235 F.SECTION_ID = ".$this->sectionId.
"
236 and F.FACET_ID in (".implode(
",", $facetFilter).
")
243 elseif (count(
$where) == 1)
245 $fcJoin =
"INNER JOIN ".$this->storage->getTableName().
" FC on FC.ELEMENT_ID = BE.ID";
246 foreach (
$where as $facetWhere)
248 $sqlWhere = $this->
whereToSql($facetWhere,
"FC");
250 $sqlSearch[] = $sqlWhere;
253 elseif (count(
$where) <= 5)
258 foreach (
$where as $facetWhere)
261 $subJoin .=
"FROM ".$this->storage->getTableName().
" FC$i\n";
263 $subJoin .=
"INNER JOIN ".$this->storage->getTableName().
" FC$i ON FC$i.ELEMENT_ID = FC0.ELEMENT_ID\n";
265 $sqlWhere = $this->
whereToSql($facetWhere,
"FC$i");
269 $subWhere .=
"\nAND ".$sqlWhere;
271 $subWhere .= $sqlWhere;
278 SELECT FC0.ELEMENT_ID
282 ) FC on FC.ELEMENT_ID = BE.ID
287 $condition = array();
288 foreach (
$where as $facetWhere)
290 $sqlWhere = $this->
whereToSql($facetWhere,
"FC0");
292 $condition[] = $sqlWhere;
296 SELECT FC0.ELEMENT_ID
297 FROM ".$this->storage->getTableName().
" FC0
298 WHERE FC0.SECTION_ID = ".$this->sectionId.
"
300 (".implode(
")OR(", $condition).
")
302 GROUP BY FC0.ELEMENT_ID
303 HAVING count(DISTINCT FC0.FACET_ID) = ".count($condition).
"
304 ) FC on FC.ELEMENT_ID = BE.ID
312 ,MIN(F.VALUE_NUM) MIN_VALUE_NUM
313 ,MAX(F.VALUE_NUM) MAX_VALUE_NUM
314 ".($connection instanceof \Bitrix\Main\DB\MysqlCommonConnection
315 ?
",MAX(case when LOCATE('.', F.VALUE_NUM) > 0 then LENGTH(SUBSTRING_INDEX(F.VALUE_NUM, '.', -1)) else 0 end)"
316 :
",MAX(".$sqlHelper->getLengthFunction(
"ABS(F.VALUE_NUM) - FLOOR(ABS(F.VALUE_NUM))").
"+1-".$sqlHelper->getLengthFunction(
"0.1").
")"
318 ,COUNT(DISTINCT F.ELEMENT_ID) ELEMENT_COUNT
320 ".$this->storage->getTableName().
" F
326 :
"b_iblock_element BE"
329 WHERE ".implode(
" AND ", $sqlSearch).
"
331 ) E ON E.ID = F.ELEMENT_ID
333 F.SECTION_ID = ".$this->sectionId.
"
334 and F.FACET_ID in (".implode(
",", $facetFilter).
")
340 $result = $connection->query(implode(
"\nUNION ALL\n", $sqlUnion));
402 $sectionCondition =
"$tableAlias.SECTION_ID = ".$this->sectionId;
403 $facetCondition =
"$tableAlias.FACET_ID = ".$where[
"FACET_ID"];
410 $sqlWhere = $sectionCondition
411 .
" AND ".$facetCondition
412 .
" AND $tableAlias.VALUE_NUM = 0"
413 .
" AND $tableAlias.VALUE in (".implode(
", ",
$where[
"VALUES"]).
")"
420 $sqlWhere = $sectionCondition
421 .
" AND ".$facetCondition
422 .
" AND $tableAlias.VALUE_NUM ".
$where[
"OP"].
" ".
$where[
"VALUES"][0]
423 .
" AND $tableAlias.VALUE = 0"
426 elseif (
$where[
"OP"] ==
"><")
428 $sqlWhere = $sectionCondition
429 .
" AND ".$facetCondition
430 .
" AND $tableAlias.VALUE_NUM BETWEEN ".
$where[
"VALUES"][0].
" AND ".
$where[
"VALUES"][1]
431 .
" AND $tableAlias.VALUE = 0"
438 $sqlWhere = $sectionCondition
439 .
" AND ".$facetCondition
440 .
" AND $tableAlias.VALUE_NUM ".
$where[
"OP"].
" ".
$where[
"VALUES"][0]
443 elseif (
$where[
"OP"] ==
"><")
445 $sqlWhere = $sectionCondition
446 .
" AND ".$facetCondition
447 .
" AND $tableAlias.VALUE_NUM BETWEEN ".
$where[
"VALUES"][0].
" AND ".
$where[
"VALUES"][1]
450 elseif (
$where[
"OP"] ==
"=")
452 $sqlWhere = $sectionCondition
453 .
" AND ".$facetCondition
454 .
" AND $tableAlias.VALUE_NUM in (".implode(
", ",
$where[
"VALUES"]).
")"
461 $sqlWhere = $sectionCondition
462 .
" AND ".$facetCondition
464 if ($this->toCurrencyId && $this->convertCurrencyId)
467 foreach ($this->convertCurrencyId as $currency => $currencyDictionaryId)
469 $convertedPrice = \CCurrencyRates::convertCurrency(
$where[
"VALUES"][0], $this->toCurrencyId, $currency);
470 $sqlOr[] =
"($tableAlias.VALUE = $currencyDictionaryId AND $tableAlias.VALUE_NUM ".$where[
"OP"].
" $convertedPrice)";
472 $sqlWhere .=
" AND (".implode(
" OR ", $sqlOr).
")";
476 $sqlWhere .=
" AND $tableAlias.VALUE_NUM ".$where[
"OP"].
" ".
$where[
"VALUES"][0];
479 elseif (
$where[
"OP"] ==
"><")
481 $sqlWhere = $sectionCondition
482 .
" AND ".$facetCondition
484 if ($this->toCurrencyId && $this->convertCurrencyId)
487 foreach ($this->convertCurrencyId as $currency => $currencyDictionaryId)
489 $convertedPrice1 = \CCurrencyRates::convertCurrency(
$where[
"VALUES"][0], $this->toCurrencyId, $currency);
490 $convertedPrice2 = \CCurrencyRates::convertCurrency(
$where[
"VALUES"][1], $this->toCurrencyId, $currency);
491 $sqlOr[] =
"($tableAlias.VALUE = $currencyDictionaryId AND $tableAlias.VALUE_NUM BETWEEN $convertedPrice1 AND $convertedPrice2)";
493 $sqlWhere .=
" AND (".implode(
" OR ", $sqlOr).
")";
497 $sqlWhere .=
" AND $tableAlias.VALUE_NUM BETWEEN ".$where[
"VALUES"][0].
" AND ".
$where[
"VALUES"][1];
503 if ($sqlWhere && $subsectionsCondition !==
'')
505 $sqlWhere .=
" and ".$tableAlias.
".".$subsectionsCondition;
603 if (!isset($this->priceFilter))
605 $this->priceFilter = array();
608 $priceList = Catalog\GroupTable::getList(array(
609 'select' => array(
'ID'),
610 'order' => array(
'ID' =>
'ASC')
612 while($price = $priceList->fetch())
614 $this->priceFilter[] = (int)$price[
'ID'];
616 unset($price, $priceList);
633 $facetId = $this->storage->propertyIdToFacetId($propertyId);
634 if ($operator ==
"<=" || $operator ==
">=")
636 $this->where[$operator.$facetId] = array(
639 "FACET_ID" => $facetId,
640 "VALUES" => array(doubleval($value)),
642 if (isset($this->where[
">=".$facetId]) && isset($this->where[
"<=".$facetId]))
644 $this->where[
"><".$facetId] = array(
647 "FACET_ID" => $facetId,
649 $this->where[
">=".$facetId][
"VALUES"][0],
650 $this->where[
"<=".$facetId][
"VALUES"][0]
653 unset($this->where[
">=".$facetId]);
654 unset($this->where[
"<=".$facetId]);
670 $facetId = $this->storage->priceIdToFacetId($priceId);
671 if ($operator ==
"<=" || $operator ==
">=")
673 $this->where[$operator.$facetId] = array(
676 "FACET_ID" => $facetId,
677 "VALUES" => array(doubleval($value)),
679 if (isset($this->where[
">=".$facetId]) && isset($this->where[
"<=".$facetId]))
681 $this->where[
"><".$facetId] = array(
684 "FACET_ID" => $facetId,
686 $this->where[
">=".$facetId][
"VALUES"][0],
687 $this->where[
"<=".$facetId][
"VALUES"][0]
690 unset($this->where[
">=".$facetId]);
691 unset($this->where[
"<=".$facetId]);
707 $facetId = $this->storage->propertyIdToFacetId($propertyId);
708 if ($operator ==
"=")
710 if (isset($this->where[$facetId]))
712 $this->where[$facetId][
"VALUES"][] = intval($value);
716 $this->where[$facetId] = array(
719 "FACET_ID" => $facetId,
720 "VALUES" => array(intval($value)),
737 $facetId = $this->storage->propertyIdToFacetId($propertyId);
738 if ($operator ==
"<=" || $operator ==
">=")
740 $this->where[$operator.$facetId] = array(
743 "FACET_ID" => $facetId,
744 "VALUES" => array(intval($value)),
746 if (isset($this->where[
">=".$facetId]) && isset($this->where[
"<=".$facetId]))
748 $this->where[
"><".$facetId] = array(
751 "FACET_ID" => $facetId,
753 $this->where[
">=".$facetId][
"VALUES"][0],
754 $this->where[
"<=".$facetId][
"VALUES"][0]
757 unset($this->where[
">=".$facetId]);
758 unset($this->where[
"<=".$facetId]);
761 elseif ($operator ==
"=")
763 if (isset($this->where[$operator.$facetId]))
765 $this->where[$operator.$facetId][
"VALUES"][] = intval($value);
769 $this->where[$operator.$facetId] = array(
772 "FACET_ID" => $facetId,
773 "VALUES" => array(intval($value)),