Добавить в избранное для 1С-Битрикс

Оптимизация картинок из jpg в webp для Битрикс
Обзор обновления aveCRM 7.7
Добавить в избранное для 1С-Битрикс

Для контентных сайтов и интернет магазинов часто появляется необходимость добавить функционал добавления страниц в закладки или избранное. Рассмотрим решение задачи на базе системы управления сайтом 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'));
        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()->flush("");
    }
    else { // Для авторизованного
        $idUser = $USER->GetID();
        $rsUser = CUser::GetByID($idUser);
        $arUser = $rsUser->Fetch();
        $arElements = $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;
if(!$USER->IsAuthorized())
{
    $arFavorites = unserialize($APPLICATION->get_cookie("favorite"));
}
else {
    $idUser = $USER->GetID();
    $rsUser = CUser::GetByID($idUser);
    $arUser = $rsUser->Fetch();
    $arFavorites = $arUser['UF_FAVORITE'];  // Достаём избранное пользователя
}

А добавление класса будет выглядеть так class=”js-add-to-favorite <? echo (in_array($item["ID"], $arFavorites)) ? 'active' : '';?>"

Вы готовы начать работу или получить консультацию?

Самый простой способ - написать нам. Не стесняйтесь задавать вопросы. Мы готовы начать обсуждение вашего проекта сейчас, сделайте следующий шаг, напишите нам.