Вывод 404 страницы при некорректных значениях в URL фильтра каталога при ЧПУ

Доброго времени суток!

На одном проекте встала задача для комплексного компонента каталога, а в частности при выбранном фильтре проверять параметры которые передаются в URL-е и если в нем находятся несуществующие параметры выводить 404 страницу (при ЧПУ для catalog.smart.filter).

Для примера, есть действующая рабочая страница с адресом/catalog/dveri/filter/tolshina_polotna-is-35/apply/ и есть старый адрес (или просто любой спамный адрес) /catalog/dveri/filter/tolshina_polotna-is-999999999/apply/. Т.е. такого параметра в фильтре нет, но страница все равно отдает 200 код и выводит данные по странице без фильтра. Вот её то нам и нужно убрать, т.е. выводить 404 код и страницу.

Сразу хочу сказать, что показанная реализация далеко не идеальная и подходит на минимальных изменениях комплексного шаблона компонента, но каждый может её донастроить "под себя". Мне для выполнения задачи хватило минимальных дополнений.

Что делаем:

1) убеждаемся, что у нас добавлен обработчик события на эпилоге, проверяющий константу ERROR_404 и при её наличии выводящий 404 страницу с нужным кодом. Примерно такого содержания:

AddEventHandler("main", "OnEpilog", "error_page");
function error_page()
{
    $page_404 = "/404.php";
    GLOBAL $APPLICATION;
    if(strpos($APPLICATION->GetCurPage(), $page_404) === false && defined("ERROR_404") && ERROR_404 == "Y")
    {
        $APPLICATION->RestartBuffer();
        CHTTP::SetStatus("404 Not Found");
        include($_SERVER["DOCUMENT_ROOT"].SITE_TEMPLATE_PATH."/header.php");
        include($_SERVER["DOCUMENT_ROOT"].$page_404);
        include($_SERVER["DOCUMENT_ROOT"].SITE_TEMPLATE_PATH."/footer.php");
        die();
    }
}

Добавить его можно в init.php например.

2) Мы будем проверять, что выбран адрес с установленными значениями фильтра (в моём случае это наличие /filter/), а также есть параметры фильтрации для catalog.section (по умолчанию глобальная переменная $arrFilter, у вас может быть другая).

Для этого идем в шаблон нашего catalog.section в файл result_modifier.php и там ставим проверку (можно её поставить перед вызовом catalog.section, как вам угодно)

global $arrFilter;
$curPage = $APPLICATION->GetCurPage(false);

if(strpos($curPage, "/filter/") !== false && empty($arrFilter))
{
	define("ERROR_404","Y");
}

Как вы можете видеть я проверяю вообще на пустоту массива фильтра $arrFilter, если он у вас где-то еще переопределяется и там присутствуют другие значения (кроме тех, что устанавливает catalog.smart.filter) - вам нужна более сложная логика для проверки. Но для общего примера и понимания мне кажется этого достаточно.

Все, после этого если адрес страницы содержит /filter/, а параметров фильтрации нет никаких, будет отдаваться 404 страница.


Возврат к списку