-
-
Save Talyzenkov/36bd52e8ba9f6edc82a3d48e53abe9a9 to your computer and use it in GitHub Desktop.
<?php | |
/* | |
Change bitrix smartfilter logic for one property from "OR" to "AND" | |
*/ | |
$arPropIds = ['37', '38']; // ID properties for changing | |
$bSubfilter = 0; | |
foreach ($arPropIds as $propId) | |
{ | |
if ($GLOBALS['arrFilter']['=PROPERTY_' . $propId] && count($GLOBALS['arrFilter']['=PROPERTY_' . $propId]) > 1) | |
{ | |
$bSubfilter = 1; | |
break; | |
} | |
} | |
if ($bSubfilter) | |
{ | |
$queryWhere = ''; | |
$i = $count = 0; | |
foreach ($arPropIds as $propId) | |
{ | |
if ($GLOBALS['arrFilter']['=PROPERTY_' . $propId] && count($GLOBALS['arrFilter']['=PROPERTY_' . $propId])) | |
{ | |
$i++; | |
if ($i >= 2) | |
{ | |
$queryWhere .= ' OR '; | |
} | |
$queryWhere .= "(IBLOCK_PROPERTY_ID='$propId' " | |
. "AND VALUE in (" . implode(",", $GLOBALS['arrFilter']['=PROPERTY_' . $propId]) . ") )"; | |
$count += count($GLOBALS['arrFilter']['=PROPERTY_' . $propId]); | |
unset($GLOBALS['arrFilter']['=PROPERTY_' . $propId]); | |
} | |
} | |
$query = "SELECT IBLOCK_ELEMENT_ID, " | |
. "count(VALUE) cnt FROM " | |
. "b_iblock_element_property WHERE " | |
. $queryWhere | |
. "GROUP BY IBLOCK_ELEMENT_ID having cnt=$count"; | |
$result = $DB->Query($query); | |
while ($arElement = $result->GetNext()) | |
{ | |
$row[] = $arElement['IBLOCK_ELEMENT_ID']; | |
} | |
} | |
unset($GLOBALS['arrFilter']['=PROPERTY_' . $propId]); | |
$GLOBALS['arrFilter']['ID'] = $row; | |
?> |
Разобрался, в коде есть огрех:
условие на 9 строке лучше ставить не > 1, а > 0, потому что одиночный фильтр тогда не сработает, будет работать только от 2 чекбоксов.
Доработал слегка код:
`//create array with props
$IBLOCK_ID = $arParams["IBLOCK_ID"];
$arProps = [];
$properties = CIBlockProperty::GetList(Array("sort"=>"asc", "name"=>"asc"), Array("ACTIVE"=>"Y", "IBLOCK_ID"=>$IBLOCK_ID));
while ($prop_fields = $properties->GetNext())
{
$arProps[$prop_fields["CODE"]]["ID"] = $prop_fields["ID"];
$arProps[$prop_fields["CODE"]]["NAME"] = $prop_fields["NAME"];
}
$arPropIds = [(int)$arProps["OUR_PROP_NAME"]["ID"]]; // ID properties for changing
$bSubfilter = 0;
foreach ($arPropIds as $propId)
{
if ($GLOBALS['arrFilter']['=PROPERTY_' . $propId] && count($GLOBALS['arrFilter']['=PROPERTY_' . $propId]) > 0)
{
$bSubfilter = 1;
break;
}
}
if ($bSubfilter)
{
$queryWhere = '';
$i = $count = 0;
foreach ($arPropIds as $propId)
{
if ($GLOBALS['arrFilter']['=PROPERTY_' . $propId] && count($GLOBALS['arrFilter']['=PROPERTY_' . $propId]))
{
$i++;
if ($i >= 2)
{
$queryWhere .= ' OR ';
}
$queryWhere .= "(IBLOCK_PROPERTY_ID='$propId' "
. "AND VALUE in (" . implode(",", $GLOBALS['arrFilter']['=PROPERTY_' . $propId]) . ") )";
$count += count($GLOBALS['arrFilter']['=PROPERTY_' . $propId]);
unset($GLOBALS['arrFilter']['=PROPERTY_' . $propId]);
}
}
$query = "SELECT IBLOCK_ELEMENT_ID, "
. "count(VALUE) cnt FROM "
. "b_iblock_element_property WHERE "
. $queryWhere
. "GROUP BY IBLOCK_ELEMENT_ID having cnt=$count";
$result = $DB->Query($query);
while ($arElement = $result->GetNext())
{
$row[] = $arElement['IBLOCK_ELEMENT_ID'];
}
}
unset($GLOBALS['arrFilter']['=PROPERTY_' . $propId]);
$GLOBALS['arrFilter']['ID'] = $row;`
Куда вставлять данный код?