Иногда нужно и такое: Например: на одном из разрабатываемых сайтов, мне нужно было создать всего 4 товара. при этом покупателю не доступна возможность купить два товара, только один. Но у него должна остаться возможность "передумать".
Если пользователь уже кинул товар в корзину, он может его из корзины удалить и положить новый товар. Но это не удобно. Мы сделаем так- если у пользователя в корзине есть товар. Но он нажал кнопку "Купить" у другого товара, мы будем удалять (полностью очищать корзину) предыдущий из корзины и ложить новый.
В файл /local/php_interface/init.php добавляем обработчик. Он просто, по нажатию кнопки с name="BasketDelete", где бы она не была, полностью очищает корзину.
if ($_POST["BasketDelete"] and CModule::IncludeModule("sale")) { CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID()); }
К кнопкам "Купить", в списке товаров, применяем пример из заметки Информация о заказах и содержимое корзины текущего пользователя.
Если в корзине у пользователя есть товар, то заменяем ссылку "Купить", у других товаров, на "Купить" ведущую на новую страницу (предварительно создаем ее) "/newitem<? echo $arOffer["BUY_URL"] &rt;?"
У товара который есть в корзине, заменяем кнопку "Купить" на ссылку в оформление заказа
В index.php раздела /newitem/ размещае вот такой код:
<? $APPLICATION->SetTitle("Изменение тарифа"); $page = $_SERVER['REQUEST_URI']; $actionPage = array('/newitem/'); $clearpage = str_replace($actionPage, "", $page); ?> <form method="post" action="/<?echo $clearpage;?>" class="newtarif"> Ваш тариф будет изменен (любой текст) <input id="delme" type="submit" value="ОК" name="BasketDelete"> </form>
Пояснения:
— Мы предупредили пользователя, что товар будет заменен на новый
— Пользователь должен согласиться нажав "ОК". Нажимая на "ОК" он полностью очищает корзину и иницирует POST запрос
— Мы, POST запросом отправляем его по ссылке инициирующей добавление нового товара в корзину
— Ссылку добавления мы взяли прямо из URL браузера очистив от не нужных данных с помощью регулярного выражения str_replace
Один минус этого решения, если пользователь не нажмет на "ОК"- то вся наша хитрость не сработает. Он может просто вернуться на главную страницу и потом пройти в корзину. Тогда у него там будет два товара
Победить это можно:
Добавив javascript на страницу /newitem/index.php который будет принудительно кликать на "ОК".
<script> setTimeout(function () { document.getElementById('delme').click(); }, 100); </script>
Просто кликаем на элемент с id="delme" (input c "ОК") через 100 миллисекунд. Время можете выставить самостоятельно или вообще обнулить. Тогда пользователь даже не заметит страницу со сменой
Само собой, если пользователь совсем "хитрый" он может отключить js и не нажать на "ОК". Бороться с такими, пока не знаю как. Но думаю, способ додумать можно.
Вариант на php без использования js и, как следствие, вариант без изъяна. Вся суть сводится к: отправляем пользователя по ссылке с параметром, внутри которого завернут ID товара, который должен заменить уже существующие.
// подключаем ядро require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_before.php"); // подключаем модули Bitrix\Main\Loader::includeModule("sale"); Bitrix\Main\Loader::includeModule("catalog"); // очищаем корзину CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID()); // выдергиваем ID товара из ссылки $curUrl = $APPLICATION->GetCurPageParam(); $curArParams = explode('=', $curUrl); // Добавляем товар в корзину $fields = [ 'PRODUCT_ID' => $curArParams['1'], 'QUANTITY' => 1, ]; $r = Bitrix\Catalog\Product\Basket::addProduct($fields); //Отправляем в корзину header('Location: /mobileapp/order/index.php', true, 301); exit();
Здесь, методом CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID()); зачистили корзину, вообще полностью и методом Basket::addProduct добавили новый товар.
На нем, уже много видеоуроков по 1С-Битрикс. Как одиночные видео так и серии видеоуроков Перейти на канал
Совсем скоро выйдет видеокурс по разработке доски объявлений с мобильным приложением. Подписывайтесь и будьте в курсе: