Last active
June 18, 2023 10:14
-
-
Save Talyzenkov/36bd52e8ba9f6edc82a3d48e53abe9a9 to your computer and use it in GitHub Desktop.
Change bitrix smartfilter logic for one property from "OR" to "AND"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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; | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Разобрался, в коде есть огрех:
условие на 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;`