Basket - uniqcle/Bitrix GitHub Wiki
\Bitrix\Sale\Basket
- класс для работы с корзиной.
- Корзина (
Sale\Basket
) - Товар в корзине (
Sale\BasketItem
) - Свойства товаров в корзине (
Sale\BasketPropertiesCollection
) - ORM Classes
- Events
- Deprecated
- Additional
Получить корзину текущего юзера
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(
\Bitrix\Sale\Fuser::getId(),
\Bitrix\Main\Context::getCurrent()->getSite() // Примечание: getSite работает только в публичной части.
);
// Информация о корзине
$price = $basket->getPrice(); // Цена с учетом скидок
$fullPrice = $basket->getBasePrice(); // Цена без учета скидок
$weight = $basket->getWeight(); // Общий вес корзины
$orderBasket = $basket->getOrderableItems(); // Получение товаров в корзине, доступных для покупки (```CAN_BUY=Y```)
// Или получить корзину заказа
$basket = Sale\Order::load($orderId)->getBasket(); // $orderId номер заказа
// или
$basket = Sale\Basket::loadItemsForOrder($order); // $order объект заказа
$basket->getPrice(); // Цена всей корзины с учетом скидок
$basket->getBasePrice(); // Цена всей корзины без учета скидок
$basket->getVatSum(); // Сумма ндс
$basket->getVatRate(); // Ставка ндс
$basket->getListOfFormatText()); // возвращает корзину в читаемом виде, например в письме
$basket->getQuantityList(); // возвращает массив "количеств" товаров в корзине
array_sum($basket->getQuantityList()); // float(3) - количество товаров в корзине
count($basket->getQuantityList()); // int(2) - количество позиций в корзине
Получение информации о скидках в корзине
// (в компоненте "bitrix:sale.basket.basket" эта информация уже доступна в переменной $arResult['APPLIED_DISCOUNT_LIST'])
if (!$basket->getOrder())
{
$userId = $USER->GetID() ?: CSaleUser::GetAnonymousUserID();
$order = \Bitrix\Sale\Order::create(\Bitrix\Main\Context::getCurrent()->getSite(), $userId);
$result = $order->appendBasket($basket);
if ($result->isSuccess())
{
}
$discounts = $order->getDiscount();
$showPrices = $discounts->getShowPrices();
if (!empty($showPrices['BASKET']))
{
foreach ($showPrices['BASKET'] as $basketCode => $data)
{
$basketItem = $basket->getItemByBasketCode($basketCode);
if ($basketItem instanceof \Bitrix\Sale\BasketItemBase)
{
$basketItem->setFieldNoDemand('BASE_PRICE', $data['SHOW_BASE_PRICE']);
$basketItem->setFieldNoDemand('PRICE', $data['SHOW_PRICE']);
$basketItem->setFieldNoDemand('DISCOUNT_PRICE', $data['SHOW_DISCOUNT']);
}
}
}
}
$order = $basket->getOrder();
$calcResults = $order->getDiscount()->getApplyResult(true);
$fullDiscountList = $calcResults['FULL_DISCOUNT_LIST'];
$appliedDiscountList = array();
foreach ($calcResults['DISCOUNT_LIST'] as $discountData)
{
if (isset($calcResults['FULL_DISCOUNT_LIST'][$discountData['REAL_DISCOUNT_ID']]))
{
$appliedDiscountList[$discountData['REAL_DISCOUNT_ID']] = $calcResults['FULL_DISCOUNT_LIST'][$discountData['REAL_DISCOUNT_ID']];
}
}
Удаление позиции корзины по идентификатору позиции корзины
// для успешного удаления, корзина должна быть получена через getBasket, а не через getOrderableBasket
$item=$basket->getItemById($basketId);
$item->delete();
$refreshStrategy = \Bitrix\Sale\Basket\RefreshFactory::create(\Bitrix\Sale\Basket\RefreshFactory::TYPE_FULL);
$basket->refresh($refreshStrategy);
$basket->save();
Добавление в корзину
use Bitrix\Sale;
//cur user basket
$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), Bitrix\Main\Context::getCurrent()->getSite());
//order's basket
$basket = Sale\Order::load($orderId)->getBasket();
$price = $basket->getPrice();
$fullPrice = $basket->getBasePrice();
$weight = $basket->getWeight();
//add to basket
if ($item = $basket->getExistsItem('catalog', $productId)) {
$item->setField('QUANTITY', $item->getQuantity() + $quantity);
} else {
$item = $basket->createItem('catalog', $productId);
$item->setFields(array(
'QUANTITY' => $quantity,
'CURRENCY' => \Bitrix\Currency\CurrencyManager::getBaseCurrency(),
'LID' => \Bitrix\Main\Context::getCurrent()->getSite(),
'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProvider',
));
}
$basket->save();
//delete basket item
$basket->getItemById($id)->delete();
$basket->save();
//CAN_BUY=Y items
$orderBasket = $basket->getOrderableItems();
Для публичных компонентов
Добавление в корзину и ее обновление
use Bitrix\Sale;
$siteId = 's1';
$fUserId = \Bitrix\Sale\FUser::getId();
$productId = 21;
$res = array();
$product = array(
'PRODUCT_ID' => 31,
'QUANTITY' => 7,
/* если нужно использовать свойства корзины
'PROPS' => array(
array(
"NAME" => "Номер конфигурации",
"CODE" => "HASH",
"VALUE" => $hash,
"SORT" => "100",
),
array(
"NAME" => "Уникальный идентификатор",
"CODE" => "TIMESTAMP",
"VALUE" => $uniqueId,
"SORT" => "100",
),
),
*/
);
/* если нужно добавить товар с уникальной ценой, которая
будет браться не из каталога и не будет впоследствии меняться */
$rewriteFields = array(
'PRICE'=> 0,
'CUSTOM_PRICE'=>'Y',
'PRODUCT_PROVIDER_CLASS'=>'', // это поле необходимо при 'CUSTOM_PRICE'=>'Y', иначе будет отображаться скидка от цены товара c PRODUCT_ID
'CURRENCY'=>'RUB', // это нужно когда не указан 'PRODUCT_PROVIDER_CLASS'
);
$options = [];
$basketResult = \Bitrix\Catalog\Product\Basket::addProduct($product /*, $rewriteFields , $options*/);
if ($basketResult->isSuccess())
{
$res['success'] = true;
$data = $basketResult->getData();
/*
Array (
[ID] => 3 // basket id
)
*/
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(
\Bitrix\Sale\Fuser::getId(),
\Bitrix\Main\Context::getCurrent()->getSite() // Примечание: getSite работает только в публичной части.
);
// Пересчет с учетом купонов и скидок
// $refreshStrategy = \Bitrix\Sale\Basket\RefreshFactory::create(\Bitrix\Sale\Basket\RefreshFactory::TYPE_FULL);
// $basket->refresh($refreshStrategy);
$basket->refresh();
$basket->save();
} else {
$res['success'] = false;
$res['error'] = $basketResult->getErrorMessages();
}
Добавление/обновление товара в корзине
аналог
CSaleBasket::Add
use \Bitrix\Sale;
$productId = 7;
$quantity = 1;
$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), Bitrix\Main\Context::getCurrent()->getSite());
$properties['COLOR'] = array(
'NAME' => 'Цвет',
'CODE' => 'COLOR',
'VALUE' => 'black',
'SORT' => 100
);
//создаём новый товар в корзине
$item = $basket->createItem('catalog', $productId);
$item->setFields(array(
'QUANTITY' => $quantity,
'CURRENCY' => Bitrix\Currency\CurrencyManager::getBaseCurrency(),
'LID' => Bitrix\Main\Context::getCurrent()->getSite(),
'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProviderCustom',
));
$basket->save();
/*
$basketPropertyCollection = $item->getPropertyCollection();
$basketPropertyCollection->setProperty($properties);
$basketPropertyCollection->save();
*/
Товары в корзине представлены в виде коллекции объектов класса
Bitrix\Sale\BasketItem
$basketItems = $basket->getBasketItems(); // массив объектов Sale\BasketItem
Sale\Basket
реализует интерфейсы \ArrayAccess
, \Countable
и \IteratorAggregate
, поэтому с объектом корзины можно обращаться как с массивом, получая товары в корзине по индексу или перебирая записи с помощью foreach
.
foreach ($basket as $basketItem) {
echo $basketItem->getField('NAME') . ' - ' . $basketItem->getQuantity() . '<br />';
}
Информация о товарах в корзине
$item = $basketItems[0];
$item->getId(); // ID записи в корзине
$item->getProductId(); // ID товара
$item->getField('NAME'); // Любое поле товара в корзине
$item->canBuy(); // true, если доступно для покупки
$item->getBasketCode() // код корзины
$item->getFUserId() // id владельца корзины
$item->getQuantity() // количество товара
$item->getWeight() // вес товара
$item->canBuy() // товар доступен для покупки
$item->isDelay() // товар отложен
$item->getCurrency() // код валюты
$item->getFinalPrice()// стоимость всех единиц позиции товара
$item->getPrice() // цена с учетом скидок
$item->getBasePrice() // цена без учета скидок
$item->getDefaultPrice() // цена по умолчанию
$item->getDiscountPrice() // величина скидки
$item->isCustomPrice() // цена указана вручную (без использования провайдера)
$item->getVatRate() // ставка гдс
$item->getPriceWithVat() // цена с ндс
$item->getBasePriceWithVat() // базовая цена с ндс
$item->getInitialPrice() // исходная цена без ндс
$item->getVat() // ндс
$item->isVatInPrice() // цена включает ндс
$item->getCallbackFunction() // поле "CALLBACK_FUNC"
$item->getProviderEntity() // объект провайдера
$item->getProvider() // класс провайдера
$item->getField('PRICE') // получение значения любого поля
$item->getAvailableFields() // массив кодов всех полей
$item->getSettableFields() // массив кодов изменяемых полей
$item->getCalculatedFields() // массив кодов генерируемых полей
$item->isCalculatedField('FIELD_NAME') // поле является генерируемым
$item->isBarcodeMulti()
$item->getCollection(); // Корзина, в которой лежит товар
Действия над записями
$item->setField('QUANTITY', $quantity); // Изменение поля
$item->setFields(array(
'QUANTITY' => $quantity,
'CUSTOM_PRICE' => $customPrice,
)); // Изменение полей
$item->delete(); // Удаление
$item->save(); // Сохранение изменения, можно использовать и $basket->save();
Получение записи по ID и удаление записи из корзины (аналог
CSaleBasket::Delete
)
$basket->getItemById($id)->delete();
$basket->save();
Работа с корзиной
use Bitrix\Sale;
$basketItems = $basket->getBasketItems();
foreach ($basket as $basketItem) {
echo $basketItem->getField('NAME') . ' - ' . $basketItem->getQuantity() . '<br />';
}
$item = $basketItems[0];
$item->getId();
$item->getProductId();
$item->getPrice();
$item->getQuantity();
$item->getFinalPrice();
$item->getWeight();
$item->getField('NAME');
$item->canBuy();
$item->isDelay();
$item->getPropertyCollection();
$item->getCollection();
//operations
$item->setField('QUANTITY', $quantity);
$item->setFields(array(
'QUANTITY' => $quantity,
'CUSTOM_PRICE' => $customPrice,
));
$item->delete();
$item->save(); //or $basket->save();
Поиск позиции в корзине
$item = $basket->getItemById($id); // по id, $item->getId()
$item = $basket->getItemByBasketCode($basketCode); // по коду корзины, $item->getBasketCode()
$item = $basket->getExistsItem($moduleId, $productId, $properties); // по коду товара и свойствам корзины
$item = $basket->getExistsItemByItem($basketItem); // по объекту BasketItem
Получение количества товаров и количества позиций в корзине
$productCount = count($basket->getQuantityList());
$itemCount = array_sum($basket->getQuantityList());
foreach ($basket as $basketItem)
$arResult['basket'][$basketItem->getProductId()] = $basketItem->getQuantity(); // массив соответствий PRODUCT_ID и количества
Есть ли товар в корзине для текущ. покупателя
// Есть ли товар в корзине для текущ. покупателя
$siteId = 's1';
$fUserId = \Bitrix\Sale\FUser::getId();
$productId = 21;
$productByBasketItem = null;
$bProductInBasket = false;
$basket = \Bitrix\Sale\Basket::loadItemsForFUser($fUserId, $siteId);
$basketItems = $basket->getBasketItems();
if($basketItems) {
foreach($basketItems as $basketItem) {
if($basketItem->getField('PRODUCT_ID') == $productId) {
$productByBasketItem = $basketItem;
$bProductInBasket = true;
break;
}
}
}
pre($bProductInBasket); // Булево значение
pre($productByBasketItem->getId()); // Сам объект
Получение объекта корзины и массива товаров в корзине
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(
\Bitrix\Sale\Fuser::getId(),
\Bitrix\Main\Context::getCurrent()->getSite()
);
$basketItems = $basket->getBasketItems(); // все товары
$basketItemsOrderable = $basket->getOrderableItems(); // только товары, доступные для заказа
//Немного другой способ, позволяет получить корзину только с товарами, которые доступны для заказа
$basketStorage = \Bitrix\Sale\Basket\Storage::getInstance(
\Bitrix\Sale\Fuser::getId(),
\Bitrix\Main\Context::getCurrent()->getSite()
);
$basket = $basketStorage->getOrderableBasket();
Удаление товара с с идентификатором в переменной $productId из корзины
// если в корзине присутствует один и тот же товар с разными свойствами, то все позиции корзины будут удалены
// для успешного удаления, корзина должна быть получена через getBasket, а не через getOrderableBasket
foreach ($basket as $item){
if($item->getProductId()!=$productId)
continue;
$item->delete();
$refreshStrategy = \Bitrix\Sale\Basket\RefreshFactory::create(\Bitrix\Sale\Basket\RefreshFactory::TYPE_FULL);
$basket->refresh($refreshStrategy);
$basket->save();
}
У товара в корзине можно получить коллекцию свойств - объект Bitrix\Sale\BasketPropertiesCollection
. Метод getPropertyValues
возвращает массив свойств.
$basketPropertyCollection = $item->getPropertyCollection(); // Свойства товара в корзине, коллекция объектов Sale\BasketPropertyItem
$basketPropertyCollection->getPropertyValues();
// Получение свойств позиции корзины
foreach ($item->getPropertyCollection() as $property) // \Bitrix\Sale\BasketPropertyItem
{
var_dump($property->getField('NAME')); // string(14) "Product XML_ID"
var_dump($property->getField('CODE')); // string(14) "PRODUCT.XML_ID"
var_dump($property->getField('VALUE')); // string(36) "1b31a4b4-6917-43c8-8591-c3812e013fcc"
var_dump($property->getField('SORT')); // string(3) "100"
var_dump($property->getField('XML_ID')); // string(16) "bx_5ef392ec7e158"
}
Добавить новое свойство или изменить существующие можно следующим образом
$basketPropertyCollection->setProperty(array(
array(
'NAME' => 'Цвет',
'CODE' => 'COLOR',
'VALUE' => 'Кофе с молоком',
'SORT' => 100,
),
));
$basketPropertyCollection->save();
Пример удаления свойства
foreach ($basketPropertyCollection as $propertyItem) {
if ($propertyItem->getField('CODE') == 'COLOR') {
$propertyItem->delete();
break;
}
}
$basketPropertyCollection->save();
Функции для работы со свойствами корзины по символьному коду
function getBasketPropertyValue(\Bitrix\Sale\BasketItem $item,$code)
{
foreach ($item->getPropertyCollection() as $property)
{
if($property->getField('CODE')!=$code)
continue;
return $property->getField('VALUE');
}
return false;
}
function getBasketPropertyValues(\Bitrix\Sale\BasketItem $item)
{
$values = array();
foreach ($item->getPropertyCollection() as $property)
$values[$property->getField('CODE')] = $property->getField('VALUE');
return $values;
}
function saveBasketProperty(\Bitrix\Sale\BasketItem $item,$code,$value=false,$name=false,$sort=false,$xmlId=false)
{
foreach ($item->getPropertyCollection() as $property)
{
if($property->getField('CODE')!=$code)
continue;
if($value!==false)
$property->setField('VALUE', $value);
if($name!==false)
$property->setField('NAME', $name);
if($sort!==false)
$property->setField('SORT', $sort);
if($xmlId!==false)
$property->setField('XML_ID', $xmlId);
return;
}
$property = $item->getPropertyCollection()->createItem();
$property->setField('CODE', strval($code));
$property->setField('VALUE', strval($value));
$property->setField('NAME', strval($name));
$property->setField('SORT', $sort!==false?$sort:'100');
if($xmlId!==false)
$property->setField('XML_ID', $xmlId);
}
function deleteBasketProperty(\Bitrix\Sale\BasketItem $item,$code)
{
foreach ($item->getPropertyCollection() as $property)
{
if($property->getField('CODE')!=$code)
continue;
$property->delete();
return;
}
}
// использование
// получить значение по символьному коду
var_dump(getBasketPropertyValue($item,'test'));
// получить массив значений, где ключом является символьный код
var_dump(getBasketPropertyValues($item));
// сохранить значение (добавить или обновить)
saveBasketProperty($item,'test','123');
$basket->save(); // для корзины заказа должно быть $order->save();
// удалить значение
deleteBasketProperty($item,'test');
$basket->save(); // для корзины заказа должно быть $order->save();
Обращаться напрямую к таблице корзины, без использования объектов можно с использованием ORM-класса Bitrix\Sale\Internals\BasketTable
. Например, перебрать товары в корзине текущего пользователя:
$basketRes = Sale\Internals\BasketTable::getList(array(
'filter' => array(
'FUSER_ID' => Sale\Fuser::getId(),
'ORDER_ID' => null,
'LID' => SITE_ID,
'CAN_BUY' => 'Y',
)
));
while ($item = $basketRes->fetch()) {
var_dump($item);
}
А таким образом можем получить количество и сумму товаров в корзине текущего юзера
$result = Sale\Internals\BasketTable::getList(array(
'filter' => array(
'FUSER_ID' => Sale\Fuser::getId(),
'ORDER_ID' => null,
'LID' => SITE_ID,
'CAN_BUY' => 'Y',
),
'select' => array('BASKET_COUNT', 'BASKET_SUM'),
'runtime' => array(
new \Bitrix\Main\Entity\ExpressionField('BASKET_COUNT', 'COUNT(*)'),
new \Bitrix\Main\Entity\ExpressionField('BASKET_SUM', 'SUM(PRICE*QUANTITY)'),
)
))->fetch();
Получить свойства товаров в корзине поможет класс
Bitrix\Sale\Internals\BasketPropertyTable
$basketPropRes = Sale\Internals\BasketPropertyTable::getList(array(
'filter' => array(
"BASKET_ID" => $basketItemId,
),
));
while ($property = $basketPropRes->fetch()) {
var_dump($property);
}
Перебрать товары в корзине текущего пользователя
$basketIterator = BasketTable::getList(array(
'filter' => array('=FUSER_ID' => Sale\Fuser::getId(), '=ORDER_ID' => null)
));
while ($basketItem = $basketIterator->fetch()) {
var_dump($basketItem);
}
GetList в result_modifier.php в компоненте catalog.section
<? if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
$arBasketItems = array();
$dbBasketItems = CSaleBasket::GetList(
array(
"ID" => "ASC"
),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"ORDER_ID" => "NULL"
),
false,
false,
array("ID",
"PRODUCT_ID",
"QUANTITY",
"DELAY",
"CAN_BUY",
"PRICE")
);
// Получаем актуальную корзину пользователя
while ($arItems = $dbBasketItems->Fetch())
{
$arBasketItems[] = $arItems['PRODUCT_ID'];
}
//Если товар есть в корзине, то устанавливаем флаг
foreach($arResult['ITEMS'] as &$arItem){
if (in_array($arItem['ID'], $arBasketItems)) {
$arItem['INBASKET'] = 'Y';
}
}
Для торговых предложений
<? if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die(); ?>
<?php
$arBasketItems = array();
$dbBasketItems = CSaleBasket::GetList(
array(
"ID" => "ASC"
),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"ORDER_ID" => "NULL"
),
false,
false,
array("ID",
"PRODUCT_ID",
"QUANTITY",
"DELAY",
"CAN_BUY",
"PRICE")
);
// Получаем актуальную корзину пользователя
while ($arItems = $dbBasketItems->Fetch())
{
$arBasketItems[] = $arItems['PRODUCT_ID'];
}
$arIDsBasketItems = [];
// получить по ID торгового предложения ID товара
foreach($arBasketItems as $arItemB){
$arIDsBasketItems[] = CCatalogSku::GetProductInfo($arItemB);
}
//Собираем массив для удобства
foreach($arIDsBasketItems as $arItem){
$arNew[] = $arItem['ID'];
}
//Если товар есть в корзине, то устанавливаем флаг
foreach($arResult['ITEMS'] as &$arItem){
if (in_array($arItem['ID'], $arNew)) {
$arItem['INBASKET'] = 'Y';
}
}
?>
https://burlaka.studio/lab/order_basket_and_so_so/
https://it-svalka.ru/blog/bitrix/rabota-s-korzinoy-1s-bitriks-d7/