Для контентных сайтов и интернет магазинов часто появляется необходимость добавить функционал добавления страниц в закладки или избранное. Рассмотрим решение задачи на базе системы управления сайтом 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' : '';?>"
