Очень часто при создании интернет-магазина требуется наличие функционала для добавления товаров в избранное (wishlist).
В данной статье написан метод разработки избранного на основе bitrix:catalog.section, cookies и пользовательских полей.
Создание поля хранения избранного
Избранное будет работать при помощи обработчика ajax.php, к которому мы будем обращаться посредством AJAX-запроса при клике на кнопку добавления товара в избранное:
- Для незарегистрированного пользователя мы будем записывать ID товаров в Cookies;
- Для зарегистрированного пользователя записывать объекты в пользовательское поле, которое мы создадим.
Для начала создадим пользовательское поле, которое будет хранить добавленные в избранное товары.
Данное поле должно обязательно иметь множественное значение. Пример представлен ниже:
Создание иконки для шапки с количеством избранного
После того как мы завели пользовательское поле UF_FAVORITES, требуется создать страницу и ссылку (например «/personal/wishlist/») на избранное . В данном примере выводится количество добавленных товаров в избранное:
<a id="want" class="block" href="/personal/wishlist/"> <span class="col"></span> <div class="icon"></div> <p>Хочу</p></a> <a class="block" href="/personal/wishlist/"></a><a class="block" href="/personal/wishlist/"><br></a>
Функция добавления избранного при помощи AJAX (без перезагрузки страницы)
Теперь нужно подготовить функцию с AJAX-запросом, с помощью которой будет отправляться ID товара в обработчик, в котором будет происходить его добавление в избранное. Функция проверяет, наличие товара в массиве, если он уже добавлен, то мы его удаляем. Если операция прошла успешно, пересчитываем количество товаров в избранном и выводим количество.
Пример:
$(document).ready(function() { /* Favorites */ $('.favor').on('click', function(e) { var favorID = $(this).attr('data-item'); if($(this).hasClass('active')) var doAction = 'delete'; else var doAction = 'add'; addFavorite(favorID, doAction); }); /* Favorites */ }); /* Избранное */ function addFavorite(id, action) { var param = 'id='+id+"&action="+action; $.ajax({ url: '/local/ajax/favorites.php', // URL отправки запроса type: "GET", dataType: "html", data: param, success: function(response) { // Если Данные отправлены успешно var result = $.parseJSON(response); if(result == 1){ // Если всё чётко, то выполняем действия, которые показывают, что данные отправлены $('.favor[data-item="'+id+'"]').addClass('active'); var wishCount = parseInt($('#want .col').html()) + 1; $('#want .col').html(wishCount); // Визуально меняем количество у иконки } if(result == 2){ $('.favor[data-item="'+id+'"]').removeClass('active'); var wishCount = parseInt($('#want .col').html()) - 1; $('#want .col').html(wishCount); // Визуально меняем количество у иконки } }, error: function(jqXHR, textStatus, errorThrown){ // Ошибка console.log('Error: '+ errorThrown); } }); } /* Избранное */
Создание обработчика избранных товаров ajax.php
При помощи AJAX-запроса мы обращаемся к обработчику ajax.php, в котором идёт проверка пользователя, авторизован ли он. Делаем запись в пользовательское поле UF_FAVORITES, если он авторизован.
Если пользователь не авторизован, записываем ID товара в Cookies. Чтобы корректно сделать запись, нужно вернуть из cookies массив с избранными товарами, и добавить нашу позицию в массив. Также присутствует проверка на дублирование, для исключения повторений.
Код обработчика ajax.php , который добавляет/удаляет товары избранного:
<?php require_once($_SERVER['DOCUMENT_ROOT']. "/bitrix/modules/main/include/prolog_before.php"); /* Избранное */ global $APPLICATION; if($_GET['id']) { if(!$USER->IsAuthorized()) // Для неавторизованного { $arElements = unserialize($_COOKIE['favorites']); if(!in_array($_GET['id'], $arElements)) { $arElements[] = $_GET['id']; $result = 1; // Датчик. Добавляем } else { $key = array_search($_GET['id'], $arElements); // Находим элемент, который нужно удалить из избранного unset($arElements[$key]); $result = 2; // Датчик. Удаляем } // $cookie = new Cookie("favorites", serialize($arElements), time() + 60*60*24*60); // print_r($arElements); if(empty($arElements)){ setcookie("favorites", '', time() - 1, "/", $_SERVER['SERVER_NAME'], false); } else { setcookie("favorites", serialize($arElements), time() + 60*60*24*60, "/", $_SERVER['SERVER_NAME'], false); } } else { // Для авторизованного $idUser = $USER->GetID(); $rsUser = CUser::GetByID($idUser); $arUser = $rsUser->Fetch(); $arElements = $arUser['UF_FAVORITES']; // Достаём избранное пользователя if(!in_array($_GET['id'], $arElements)) // Если еще нету этой позиции в избранном { $arElements[] = $_GET['id']; $result = 1; } else { $key = array_search($_GET['id'], $arElements); // Находим элемент, который нужно удалить из избранного unset($arElements[$key]); $result = 2; } $USER->Update($idUser, Array("UF_FAVORITES" => $arElements)); // Добавляем элемент в избранное } } /* Избранное */ echo json_encode($result); die(); ?>
Мы сформировали обработчик, который добавляет товары в избранное. После этого попробуем добавить парочку товаров в избранное. Они запишутся в Cookies или в пользовательское поле UF_FAVORITES (в зависимости от типа пользователя). Если мы выведем массив ‘$_COOKIE‘, то должны обнаружить там добавленные ID товара.
Чтобы проверить ID товаров в поле UF_FAVORITES, используем код:
<?php require_once($_SERVER['DOCUMENT_ROOT']. "/bitrix/modules/main/include/prolog_before.php"); global $APPLICATION; $idUser = $USER->GetID(); $rsUser = CUser::GetByID($idUser); $arUser = $rsUser->Fetch(); $arFavorites = $arUser['UF_FAVORITES']; // Достаём избранное пользователя print_r($arFavorites); }
Вывод избранных товаров на странице «Избранное»
Осталось нужным нам образом представить эти товары пользователю. В своём примере я использовал bitrix:catalog.section, хотя рекомендую использовать bitrix:catalog.top.
Если вы еще не создали страницу, на которой будете выводить избранные товары, создайте ее. (напр.: /personal/wishlist/);
Перед вызовом компонента формируем фильтр с соответствующим условием. Если мы не авторизованы, возвращаем Cookies. Если авторизованы, возвращаем пользовательское поле UF_FAVORITES. И записываем массив $favorites в переменную arrFilter, для фильтрации вывода товаров избранного.
Код перед вызовом компонента:
if(!$USER->IsAuthorized()) // Для неавторизованного { global $APPLICATION; $favorites = unserialize($_COOKIE["favorites"]); } else { $idUser = $USER->GetID(); $rsUser = CUser::GetByID($idUser); $arUser = $rsUser->Fetch(); $favorites = $arUser['UF_FAVORITES']; } $GLOBALS['arrFilter']=Array("ID" => $favorites); if(count($favorites) > 0 && is_array($favorites)):
Выделение избранных товаров в каталоге (закрасить иконку)
Финальный шаг. Товары выводятся, добавляются в избранное и удаляются. Осталось показать пользователю, что товар успешно добавился в избранное, и при перемещению по каталогу, он видел, какие товары добавлены в наш ‘wishlist’. Я сделал закрашивание иконки (сердца), давая понять, что товар избранный.
Для этого обратимся к файлу component_epilog.php в нашем компоненте (в данном случае bitrix:catalog.section), в котором будем добавлять соответствующий класс active к иконке избранного товара, тем самым закрашивая её.
<?php global $APPLICATION; if(!$USER->IsAuthorized()) { $arFavorites = unserialize($_COOKIE["favorites"]); } else { $idUser = $USER->GetID(); $rsUser = CUser::GetByID($idUser); $arUser = $rsUser->Fetch(); $arFavorites = $arUser['UF_FAVORITES']; // Достаём избранное пользователя } /* Меняем отображение сердечка товара */ foreach($arFavorites as $k => $favoriteItem): ?> <script> if($('a.favor[data-item="< ?=$favoriteItem? >"]')) $('a.favor[data-item="< ?=$favoriteItem? >"]').addClass('active'); </script> <?php endforeach; ?>
На этом все, можно пользоваться 🙂