Архитектура обработки параметров сортировки
-
Инициализация контекста запроса Используем класс
Bitrix\Main\Applicationдля получения объекта запроса:$request = Application::getInstance()->getContext()->getRequest(); -
Валидация входных параметров Определяем "белый" список допустимых значений для полей сортировки и направления:
const SORT_NEW = 'ACTIVE_FROM'; const SORT_POPULAR = 'SHOW_COUNTER'; $allowedSorts = [SORT_NEW, SORT_POPULAR]; $allowedOrders = ['ASC', 'DESC']; $currentSort = in_array($request->get('sort'), $allowedSorts, true) ? $request->get('sort') : SORT_NEW; $currentOrder = in_array(strtoupper($request->get('order')), $allowedOrders, true) ? strtoupper($request->get('order')) : 'DESC';
Генерация URL с сохранением параметров
Инкапсулируем логику формирования URL в отдельную функцию:
function generateSortUrl(string $sortType, string $currentSort, string $currentOrder): string {
$params = $request->getQueryList()->toArray();
$newOrder = ($sortType === $currentSort)
? ($currentOrder === 'ASC' ? 'DESC' : 'ASC')
: 'DESC';
$params['sort'] = $sortType;
$params['order'] = $newOrder;
return '?' . http_build_query($params);
}
// Пример использования:
$sortLinkNew = htmlspecialcharsbx(generateSortUrl(SORT_NEW, $currentSort, $currentOrder));
Интеграция с компонентом news.list
Передаем валидированные параметры в компонент через массив $arParams:
$APPLICATION->IncludeComponent(
"bitrix:news.list",
"",
[
"IBLOCK_ID" => $arParams["IBLOCK_ID"],
"SORT_BY1" => $currentSort,
"SORT_ORDER1" => $currentOrder,
"FIELD_CODE" => ["SHOW_COUNTER", "SHOW_COUNTER_START"], // Для отображения метрик
// ...
],
$component
);
Верстка интерфейса сортировки
Вариант 1. Кнопочный интерфейс
<div class="sort-btns__box">
<button
class="<?= ($currentSort === SORT_NEW) ? 'active' : '' ?><?= $currentOrder === 'ASC' ? ' up' : '' ?>"
onclick="location.href='<?= $sortLinkNew ?>'">
Новизне
<? if ($currentSort === SORT_NEW): ?>
<span class="sort-arrow"><?= $currentOrder === 'ASC' ? '↑' : '↓' ?></span>
<? endif; ?>
</button>
</div>
Вариант 2. Выпадающий список
<form action="<?= $APPLICATION->GetCurPage() ?>">
<select name="catalog_sort" onchange="this.form.submit()">
<option value="asc" <?= $currentOrder === 'ASC' ? 'selected' : '' ?>>По возрастанию</option>
<option value="desc" <?= $currentOrder === 'DESC' ? 'selected' : '' ?>>По убыванию</option>
</select>
</form>
Оптимизация и безопасность
-
Экранирование выходных данных Всегда используем
htmlspecialcharsbx()для предотвращения XSS:$sortLink = htmlspecialcharsbx(generateSortUrl(...)); -
Обработка GET-параметров через URLSearchParams Для JavaScript-реализации:
const url = new URL(window.location.href); url.searchParams.set('order', newOrder); window.location.href = url.toString();
Расширение функциональности
-
Метрики популярности Добавляем поля
SHOW_COUNTERиSHOW_COUNTER_STARTвFIELD_CODEкомпонента для отслеживания статистики. -
Кеширование запросов Реализуем механизм кеширования с использованием
CPHPCacheдля снижения нагрузки на БД:$cache = new CPHPCache(); if ($cache->InitCache($cacheTime, $cacheKey)) { $result = $cache->GetVars(); } elseif ($cache->StartDataCache()) { // Выполнение тяжелых запросов $cache->EndDataCache($result); }
Данный подход обеспечивает:
-
Строгую валидацию входных параметров.
-
Гибкость при изменении логики сортировки.
-
Защиту от XSS и недопустимых значений.
-
Совместимость с компонентами Bitrix и стандартами разработки.
Update
Простая сортировка во включаемой области
Можно вывести, например, в header.
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die();
}
/**
* @global object $APPLICATION
* @var array $arResult
* @var array $arParams
*/
use Bitrix\Main\Application;
$request = Application::getInstance()->getContext()->getRequest();
$getOrder = $request->get("order");
?>
<form id="sortForm" action="<?=$APPLICATION->GetCurPage()?>">
<div class="sorting">
<span>Сортировать по:</span>
<div class="select__box sorting-box custom-select">
<select name="catalog_sort" onchange="submitFormSorting()">
<option value="asc"<?= $getOrder === 'asc' ? ' selected' : '' ?>>Цена (по возрастанию)</option>
<option value="desc"<?= $getOrder === 'desc' ? ' selected' : '' ?>>Цена (по убыванию)</option>
</select>
</div>
</div>
</form>
<script>
function submitFormSorting() {
let form = document.getElementById('sortForm')
let select = form.querySelector('select[name="catalog_sort"]')
let selectedValue = select.value
let baseUrl = form.action
window.location.href = `${baseUrl}?sort=SCALED_PRICE_1&order=${selectedValue}`
}
</script>
// Или с сохранением GET параметров
<script>
/**
* Функция для изменения сортировки в каталоге (возрастанию / убыванию).
*/
function submitFormSorting() {
const form = document.getElementById('sortForm');
const select = form.querySelector('select[name="catalog_sort"]');
const selectedValue = select.value;
// Текущий URL.
const url = new URL(window.location.href);
// Обновляем параметр сортировки.
if (selectedValue) {
url.searchParams.set('order', selectedValue);
} else {
url.searchParams.delete('order');
}
window.location.href = url.toString();
}
</script>