Например, есть свойство длина со значениями 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. Код тестировался в ограниченных условиях, не факт, что будет везде работать.