В этой заметке рассакажу как добавлять товары в "Отложенные", для иммитации функционала "Избранное". Для этого будем использовать API 1С-Битрикс. Добавление будет происходить на AJAX- без перезагрузки страницы
Выводим количество отложенных товаров
В штатной корзине sale.basket есть отложить товар. Наша задача вывести количество отложенных товаров в шаблоне сайта, например в шапке и назвать "Избранное"- вот в таком виде:

Для этого, в нужном месте шаблона выводим следующий код:
<?
use Bitrix\Main\Loader;
Loader::includeModule("sale");
$delaydBasketItems = CSaleBasket::GetList(
array(),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"ORDER_ID" => "NULL",
"DELAY" => "Y"
),
array()
);
echo $delaydBasketItems;
?>
В переменную $delaydBasketItems - мы передали и вывели количество отложенных товаров, отфильтровав их параметром "DELAY" => "Y". Если не использовать данный параметр- нам выведется общее количество товаров в корзине, вместе с готовыми к покупке.
Создаем обработчик для добавления товара из карточки.
Далее создаем файл wishlist.php и ложим его в директорию /local/ajax/. Внутри этого файла размещаем следующий код (подсказки по коду в комментриях)
<?
//Подключаем ядро Битрикс и главный модуль
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
use Bitrix\Main\Loader;
//Подключаем модуль sale
Loader::includeModule("sale");
//Получаем корзину текущего пользователя
$fUserID = CSaleBasket::GetBasketUserID(True);
$fUserID = IntVal($fUserID);
//Создаем переменные для обработчика
$arFields = array(
"PRODUCT_ID" => $_POST['p_id'],
"PRODUCT_PRICE_ID" => $_POST['pp_id'],
"PRICE" => $_POST['p'],
"CURRENCY" => "RUB",
"WEIGHT" => 0,
"QUANTITY" => 1,
"LID" => 's1',
"DELAY" => "Y",
"CAN_BUY" => "Y",
"NAME" => $_POST['name'],
"MODULE" => "sale",
"NOTES" => "",
"DETAIL_PAGE_URL" => $_POST['dpu'],
"FUSER_ID" => $fUserID
);
//Получаем количество отложеных товаров
if (CSaleBasket::Add($arFields)) {
$arBasketItems = array();
$dbBasketItems = CSaleBasket::GetList(
array(
"NAME" => "ASC",
"ID" => "ASC"
),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"ORDER_ID" => "NULL",
"DELAY" => "Y",
),
false,
false,
array("PRODUCT_ID")
);
while ($arItems = $dbBasketItems->Fetch()){
$arBasketItems[] = $arItems["PRODUCT_ID"];
}
//Загоняем отложенне в переменную
$inwished = count($arBasketItems);
}
//Выводи количество отложенных товаров
echo $inwished;
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");
?>
Этот обработчик будет получать событие о добавлении товара в отложенные. В детальной карточке товара размещаем скрипт который будет обращаться, к созданному выше обработчику, точнее передавать в него параметры товара:
function add2wish(p_id, pp_id, p, name, dpu, th){
$.ajax({
type: "POST",
url: "/local/ajax/wishlist.php",
data: "p_id=" + p_id + "&pp_id=" + pp_id + "&p=" + p + "&name=" + name + "&dpu=" + dpu,
success: function(html){
$(th).addClass('in_wishlist');
$('#wishcount').html(html);
}
});
};
И здесь же, в карточке товара, размещаем ссылку которая будет инициализировать скрипт и передавать параметры о товаре и цене.
<a href="javascript:void(0)" class="wishbtn <? if (in_array($arResult["ID"],$arBasketItems )) echo 'in_wishlist '; ?>"
onclick="add2wish(
'<?=$arResult["ID"]?>',
'<?=$arResult["CATALOG_PRICE_ID_1"]?>',
'<?=$arResult["CATALOG_PRICE_1"]?>',
'<?=$arResult["NAME"]?>',
'<?=$arResult["DETAIL_PAGE_URL"]?>',
this)">
Добавить в избранное / отложенные
</a>
При клике, на эту ссылку, товар будет добавлен в отложенные и самой ссылке присвотся класс in_wishlist- что бы можно было ее стилизовать под дизайн
Обновление счетчика отложенных
И еще одна мелочь. Это обновление счетчика Избранных в шапке сайта. Что бы он обновлялся на лету- просто обворачиваем вывод счетчика (созданный выше) в div c id wishcount. Вот так
<div id="wishcount">
<?
use Bitrix\Main\Loader;
Loader::includeModule("sale");
$delaydBasketItems = CSaleBasket::GetList(
array(),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"ORDER_ID" => "NULL",
"DELAY" => "Y"
),
array()
);
echo $delaydBasketItems;
?>
</div>
Что бы не сбрасывался стиль кнопки, в карточке товара- если данный товар есть в отложенных
//Проверяем, есть ли данный товар в отложенных
$curProductId = $arResult['ID'];
$dbBasketItems = CSaleBasket::GetList(
array(
"NAME" => "ASC",
"ID" => "ASC"
),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"PRODUCT_ID" => $curProductId,
"ORDER_ID" => "NULL",
"DELAY" => "Y"
),
false,
false,
array("PRODUCT_ID")
);
while ($arItems = $dbBasketItems->Fetch())
{
$itInDelay = $arItems['PRODUCT_ID'];
}
//Добавляем к кнопке class
if ( (in_array($arResult["ID"], $delaydBasketItems)) || (isset($itInDelay)) ) { echo 'in_wishlist'; }
Выше, мы просто проверили наличие данного товара (по его ID), есть ли он в отложенных. Если есть, загнали в переменную $itInDelay его ID. В самой кнопке-ссылке, проверили на существование переменной $itInDelay (точнее, что она не пустая)
Более наглядное применение в видео-инструкции.
Данное видео является одной из серий (19) курса по разработке интернет-магазина на Битрикс
На этом все. Заметка написана на базе темы на офицальном форуме Битрикс. Дополнена не достающими фактами.
Как при добавление в избранное передать значения выбранных торговых предложений?
Пыталась добавить через параметр "PROPS" CSaleBasket::Add($arFields);
вышло таким образом https://c2n.me/3Rn0pZ1
Подскажите как добавить в избранное Торговые предложения.
И подскажите как реализовать не в детальной карточке товара, а в списке товаров?
Цитата |
---|
Александр Силуянов пишет: Странно, но у меня через раз работает. Например три-четыре товара добавит, потом перестает реагировать. Потом опять пару товаров добавит и т.д. В чем может быть дело как считаете? И подскажите как реализовать не в детальной карточке товара, а в списке товаров? |
Хром вот такую ошибку выдает при клике Uncaught SyntaxError: missing ) after argument list
Цитата | ||
---|---|---|
Александр Силуянов пишет:
Хром вот такую ошибку выдает при клике Uncaught SyntaxError: missing ) after argument list |
В названии продукции есть слово L'Oreal и верхний апостроф мешал корректному вызову...
Убрал из кода '<?=$arResult["NAME"]?>', и еще ко что..
Замечательные уроки, всё получается, но есть вопрос, у Вас на сайте есть список отложенных товаров - как его вывести(отдельно от корзины)?
"NAME" => $_POST['name']),

Цитата |
---|
Сергей Сыроежкин пишет: ошибка здесь, лишняя скобка... "NAME" => $_POST['name']), |
Спрашивал, на недавней трансляции, про фичу "Купить в один клик", был послан примерно сюда, а тут не такого


Цитата |
---|
Antik написал: Интересный момент, битрикс последний, шаблон дефолтный магазина, при добавлении в избранное товар появляется в корзине, но у него цена пустая, и есть кнопка добавить в заказ http://joxi.ru/brRpkKqCJkEWE2 , но даже при добавлении цена не появляется, я так полагаю потому что не передаётся параметр PRICE? |
Просто, передавайте в "избранное" первое попавшееся торговое предложение, а не сам товар.
подскажите как передать еще торговое предложение в избранное?!
Все работает, но только для авторизованных пользователей.
Также обратил внимание, что другие java скрипты глючат на неавторизованных пользователях, как будто не всё ядро подключено. Пример здесь. В чем может быть дело?
Корзина глючит тоже, форма регистрации не показывает капчу. В общем, какая-то масса проблем с общим корнем, а в документации не нашел ничего.

Цитата |
---|
Andrey Sukhanov написал: Добрый день. Все работает, но только для авторизованных пользователей. Также обратил внимание, что другие java скрипты глючат на неавторизованных пользователях, как будто не всё ядро подключено. Пример здесь . В чем может быть дело? Корзина глючит тоже , форма регистрации не показывает капчу. В общем, какая-то масса проблем с общим корнем, а в документации не нашел ничего. |
Если нет-то подсказать тяжело, нужно разбираться изнутри
Чуть позже, будет заметка о реализации отложенного- не на базе избранного.
Хотел бы сказать по поводу данного скрипта, что он плох в безопасности.
Использую ваши заготовки.
Цена передается через аякс, что не есть хорошо!
Вот пример
Через консоль браузера меняю цену:
http://joxi.ru/82QvQ0liwVOe6A
Жму в отложенные, теперь у меня в отложенных лежит товар с ценой 70.00
http://joxi.ru/brRv5Joi7Leger
Перекидываю его в корзину и что я вижу, теперь вместо товара с ценой 20070.00 руб. получаю товар за 70р.
Могу оформить заказ за 70р вместо 20070.00
На вашем сайте так же!
Взял для примера товар
http://bxstore.ru/catalog/item/audio-technica-vm520eb-h-golovka-zvukosnimatelya.php
http://joxi.ru/gmvKvnNcqdX5W2
http://joxi.ru/nAyRxkgTga1Oqr
Я бы сказал это критическая уязвимость...

Так же при перекидывание из отложенных в корзину, количество товаров становиться 2, а не 1. Должен же просто меняться флаг на "DELAY" => "N"
Логика наверно должна быть такая, что через аякс передается ID товара, а уже внутри скрипта получаем все данные , в том числе и цену. Мне кажется этот код надо убирать с вашего сайта и написать без уязвимостей.

Цитата |
---|
Константин Ильин написал: Михаил, спасибо за ваши видео и уроки, помогают разобраться с битриксом. Логика наверно должна быть такая, что через аякс передается ID товара, а уже внутри скрипта получаем все данные , в том числе и цену. Мне кажется этот код надо убирать с вашего сайта и написать без уязвимостей. |
Не получилось именно купить такой, "хакнутый" товар. При оформлении заказа, все равно установилась правильная цена.
Но да, минусом это можно назвать.
Да и достаточно, в самом деле, передавать только ID товара в ссылке и скрипте.
Вообще, эта модель, избранное-через отложенные корзины, мне не очень нравится и уже готов компонент нормальных избранных.
Скоро опубликую, в блоге. Допричесать нужно.
Цитата | ||
---|---|---|
Михаил Базаров пишет:
|
Цитата |
---|
Вообще, эта модель, избранное-через отложенные корзины, мне не очень нравится и уже готов компонент нормальных избранных. |
В этом плане модх конечно выигрывает, так сказать для разработчиков проще.
Цитата |
---|
Скоро опубликую, в блоге. Допричесать нужно. |


Цитата |
---|
dev bosgroup пишет: а как сделать чтобы при повторном нажатии данный товар убирался из "избранного" ??? |
подскажите пожалуйста, как на аяксе реализовать вывод избранных товаров?
используя функционал из данного урока.
при клике на кнопку добавить в избранное у вас меняется сразу же счетчик.
к примеру к нему добавлю всплывающее окно - и в нем выведу "отложенные" - тогда они там появляются только после перезагрузки страницы, а хотелось бы чтоб сразу всплывали.

Во первых, скрипт передает цену, указанную в параметре "&p=" напрямую, а это говорит о том, что я могу в любой момент подменить цену в html на любую другую и она попадет в отложенные в корзину, где я смогу "вернуть" товар в корзину и купить по этой цене.
Во вторых, в идеале убрать jQuery и забиндить обработчик на Bitrix JS и реализовать с помощью ajax битрикса в файле script.js шаблона.
Спасибо за статью;)

Цитата |
---|
Андрей Сенин написал: Реализация вполне не плохая, но на самом деле я бы делал по-другому: Во первых, скрипт передает цену, указанную в параметре "&p=" напрямую, а это говорит о том, что я могу в любой момент подменить цену в html на любую другую и она попадет в отложенные в корзину, где я смогу "вернуть" товар в корзину и купить по этой цене. Во вторых, в идеале убрать jQuery и забиндить обработчик на Bitrix JS и реализовать с помощью ajax битрикса в файле script.js шаблона. Спасибо за статью;) |
Понятное дело, не сам компонент оформления заказа, а "подкапотная" реализация.
У меня уже готов свой компонент избранного, пишет все отдельную табличку БД - на нескольких проектах работает успешно. Скоро (не знаю когда

Скажите пожалуйста а как добавить кнопку удалить из избранного для одного товара из списка.
Удалить все -работает
Но хочется по одному удалять
Цитата | ||
---|---|---|
написал:
Понятное дело, не сам компонент оформления заказа, а "подкапотная" реализация. У меня уже готов свой компонент избранного, пишет все отдельную табличку БД - на нескольких проектах работает успешно. Скоро (не знаю когда ) заверну его в установщик и поделюсь. |

Цитата | ||
---|---|---|
Вячеслав написал:
|
Пока нет, но скоро
