Сортировка строковых значений свойств в умном фильтре
Запись от 03.09.2014
Например, есть свойство длина со значениями 5см и 20см. По умолчанию фильтр выдаст сначала 20см, а затем 5, т.к. 5 больше 2 - значения сравниваются, как строки, а не цифры. Именно это мы и постараемся исправить.
Для этого отредактируем файл result_modifier.php компонента catalog.smart.filter, добавив следующий код:
В значениях могут быть пробелы между числом и единицей измерения. Учитывается регистр, но это можно поправить модификатором "i" в регулярном выражении.
P.S. Судя по количеству условий, код не идеален - основная цель была "что бы работало", поэтому, если есть предложения по оптимизации и структуризации кода - буду рад выслушать и исправить.
P.P.S. Код тестировался в ограниченных условиях, не факт, что будет везде работать.
Для этого отредактируем файл result_modifier.php компонента catalog.smart.filter, добавив следующий код:
/* Sort values */
foreach($arResult["ITEMS"] as $key=>$arValue) {
if(!($arValue["PROPERTY_TYPE"] == "N" || isset($arValue["PRICE"])) && count($arValue["VALUES"])) {
$arValues = Array(); // For new values
$arResValues = Array(); // For new values in arResult
$bSort = true; // Sort or not sort
$iValuesCount = count($arValue["VALUES"]); // Num of elements
$sUnit = false; // Last of unit
foreach($arValue["VALUES"] as $keyVal=>$value) {
$arMatches = Array();
preg_match("/([\d\,\.]+)\s*([А-яA-z\d\-\_]*)/", $value["VALUE"], $arMatches);
if($arMatches[1] && $arMatches[2]) {
if($sUnit && $sUnit <> $arMatches[2]) {
$bSort = false; break;
} else {
$sUnit = $arMatches[2];
}
} else {
$bSort = false; break;
}
if($bSort) {
$arMatches["key"] = $keyVal;
$arValues[] = $arMatches;
}
}
if($bSort) {
usort($arValues, "compare");
foreach($arValues as $arVal) {
$arResValues[$arVal["key"]] = $arValue["VALUES"][$arVal["key"]];
}
$arResult["ITEMS"][$key]["VALUES"] = $arResValues;
}
}
}
function compare($v1, $v2) {
if ($v1[1] == $v2[1]) return 0;
return ($v1[1] < $v2[1])? -1: 1;
}
Что делает этот код - разбивает значения свойств (кроме цен) на составляющие - число и единица измерения, если у всех значений одинаковая единица измерения и она задана, то производится сортировка пересборка массива. В значениях могут быть пробелы между числом и единицей измерения. Учитывается регистр, но это можно поправить модификатором "i" в регулярном выражении.
P.S. Судя по количеству условий, код не идеален - основная цель была "что бы работало", поэтому, если есть предложения по оптимизации и структуризации кода - буду рад выслушать и исправить.
P.P.S. Код тестировался в ограниченных условиях, не факт, что будет везде работать.