Для контентных сайтов и интернет магазинов часто появляется необходимость добавить функционал добавления страниц в закладки или избранное. Рассмотрим решение задачи на базе системы управления сайтом 1С - Битрикс.
Для начала определимся, список документов для не зарегистрированных пользователей мы будем хранить в Cookies, а для зарегистрированных в пользовательском поле в базе данных.
Создадим пользовательское поля в панели управления Настройки — Пользовательские поля как на картинке ниже
Далее сделаем разметку для кнопок. Добавим к иконке избранного класс js-add-to-favorite и параметр data-id, в котором будет храниться ID элемента инфоблока.
Обработчик нажатия на кнопку будет следующим (на проекте мы не будем использовать jquery)
if(document.querySelector(".subscribe-form")) { document.querySelectorAll(".js-add-to-favorite").forEach((element) => { element.addEventListener("click", function (event) { event.preventDefault(); var form_data = new FormData(); form_data.append('id', element.getAttribute("data-id")); (async function() { var data = await postAjax('/ajax/favorite.php', form_data); if(data == 1) { element.classList.add("active"); } else { element.classList.remove("active"); } })(); }); }); } let postAjax = async (url, data) => { return await fetch(url, { method: 'POST', body: data, headers: { 'X-Requested-With': 'XMLHttpRequest' }, }).then(function(response) { return response.json(); }); }
Теперь нужно сделать обработчик добавления элементов в избранное. В папке ajax в корне сайта создаем файл favorite.php с следующим содержанием
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle(" "); $GLOBALS['APPLICATION']->RestartBuffer(); use Bitrix\Main\Application; use Bitrix\Main\Web\Cookie; $application = Application::getInstance(); $context = $application->getContext(); global $APPLICATION; $result = 0; if($_REQUEST['id']) { $_REQUEST['id'] = (int)$_REQUEST['id']; if(!$USER->IsAuthorized()) // Для неавторизованного { $arElements = unserialize($APPLICATION->get_cookie('favorite')); $arElements = $arElements != [] ? $arElements : []; if(!in_array($_REQUEST['id'], $arElements)) { $arElements[] = $_REQUEST['id']; $result = 1; // Добавляем } else { $key = array_search($_REQUEST['id'], $arElements); unset($arElements[$key]); $result = 2; // Удаляем } $cookie = new Cookie("favorite", serialize($arElements), time() + 60*60*24*60); $cookie->setDomain($context->getServer()->getHttpHost()); $cookie->setHttpOnly(false); $context->getResponse()->addCookie($cookie); $context->getResponse()->writeHeaders(""); } else { // Для авторизованного $idUser = $USER->GetID(); $rsUser = CUser::GetByID($idUser); $arUser = $rsUser->Fetch(); $arElements = $arUser['UF_FAVORITE']; $arElements = $arUser['UF_FAVORITE'] != [] ? $arUser['UF_FAVORITE'] : []; if(!in_array($_REQUEST['id'], $arElements)) // Если еще нет элемента в избранном { $arElements[] = $_REQUEST['id']; $result = 1; } else { $key = array_search($_REQUEST['id'], $arElements); // Находим элемент unset($arElements[$key]); $result = 2; } $USER->Update($idUser, Array("UF_FAVORITE" => $arElements)); // Добавляем элемент } } echo json_encode($result); exit; ?>
Последний шаг, создаем страницу избранного и используем компонент bitrix:catalog.section. Перед компонентом добавим следующий код, в котором получим массив из ID элементов, а далее подключим стандартный компонент
if(!$USER->IsAuthorized()) // Для неавторизованного { global $APPLICATION; $favorites = unserialize(Application::getInstance()->getContext()->getRequest()->getCookie("favorite")); } else { $idUser = $USER->GetID(); $rsUser = CUser::GetByID($idUser); $arUser = $rsUser->Fetch(); $favorites = $arUser['UF_FAVORITE']; } $GLOBALS['arrFilter']=["ID" => $favorites]; if(count($favorites) > 0 && is_array($favorites)) :
Если мы хотим автоматически отображать какой элемент уже добавлен в избранное на странице, то в начале шаблона добавим код
global $APPLICATION, $USER, $arFavorites; if(!$USER->IsAuthorized()) { $arFavorites = unserialize($APPLICATION->get_cookie("favorite")); } else { $idUser = $USER->GetID(); $rsUser = CUser::GetByID($idUser); $arUser = $rsUser->Fetch(); $arFavorites = $arUser['UF_FAVORITE']; // Достаём избранное пользователя } $arFavorites = $arFavorites != [] ? $arFavorites : [];
А добавление класса будет выглядеть так class=”js-add-to-favorite <? echo (in_array($item["ID"], $arFavorites)) ? 'active' : '';?>"