Как работать с корзиной в D7 Битрикс
В этой статье рассмотрим основные функции ядра D7 Битрикс для работы с корзиной. На мой взгляд тема очень актуальная и мне часто приходится иметь дело с этим. Поэтому коротко и понятно в этой статье я изложу материал, который у меня накопился.
Простые классы
Для добавления товара в корзину в D7 существует класс Bitrix\Catalog\Product\Basket c аналогом метода Add2BasketByProductID
<? | |
\Bitrix\Main\Loader::includeModule('catalog'); | |
$result = Bitrix\Catalog\Product\Basket::addProduct( | |
[ | |
'PRODUCT_ID' => $id, // id товара или предложения | |
], | |
[ | |
'QUANTITY' => $quantity, // количество | |
'PROPS' => [ | |
[ | |
'NAME' => 'Размер', | |
'CODE' => 'SIZE', | |
'VALUE' => '180', | |
'SORT' => '100', | |
], | |
], | |
] | |
); | |
if (!$result->isSuccess()) | |
{ | |
\Bitrix\Main\Diag\Debug::dump($result->getErrorMessages()); | |
} |
ORM-классы
Обновить товар в корзине с помощью того же класса не получится, но можно сделать с помощью ORM-класса Bitrix\Sale\Internals\BasketTable
Но для того, чтобы обновить товар в корзине, нужно знать ID корзины. Получить его можно с помощью метода GetList:
<? | |
\Bitrix\Main\Loader::includeModule('sale'); | |
$arBasketItem = Bitrix\Sale\Internals\BasketTable::getList([ | |
'filter' => [ | |
'FUSER_ID' => Bitrix\Sale\Fuser::getId(), // ID покупателя, это может быть неавторизованный пользователь | |
'ORDER_ID' => null, // если заказ создан, передаем id заказа | |
'PRODUCT_ID' => $id, // id товара или предложения | |
'LID' => Bitrix\Main\Context::getCurrent()->getSite(), // работает только из публички, в другом случае можно указать жестко "s1" | |
'CAN_BUY' => 'Y', | |
], | |
'select' => [ | |
'ID', | |
'PRODUCT_ID', | |
'QUANTITY', | |
], | |
])->fetch(); |
Теперь, зная идентификатор, можно обновить корзину:
<? | |
$result = Bitrix\Sale\Internals\BasketTable::update($basketId, [ | |
'QUANTITY' => $quantity, | |
]); | |
if (!$result->isSuccess()) | |
{ | |
\Bitrix\Main\Diag\Debug::dump($result->getErrorMessages()); | |
} |
С помощью этого ORM-класса также можно и добавлять товары в корзину с помощью метода add, но я не рекомендую этого делать из-за низкоуровневости его работы – могут некоторые поля потеряться.
Свойства
Обновить свойства корзины с помощью класс BasketTable у вас не получится, так как Корзина и Свойства корзины – это разные таблицы. Поэтому для свойств корзины есть свой ORM-класс Bitrix\Sale\Internals\BasketPropertyTable
Чтобы добавить новое свойство корзины, нужно знать ее идентификатор:
<? | |
Bitrix\Sale\Internals\BasketPropertyTable::add([ | |
'BASKET_ID' => $basketId, // id позиции корзины | |
'NAME' => 'Вес', | |
'CODE' => 'WEIGHT', | |
'VALUE' => '2 кг', | |
]); |
А вот, чтобы обновить свойство нужно знать его идентификатор. Его можно получить с помощью getList и затем обновить значение свойства:
<? | |
// получаем id свойства | |
$propSize = Bitrix\Sale\Internals\BasketPropertyTable::getList([ | |
'filter' => [ | |
'=BASKET_ID' => $basketId, // id позиции корзины | |
'=CODE' => 'SIZE', | |
], | |
'select' => [ | |
'ID', | |
], | |
])->fetch(); | |
if ($propSize) | |
{ | |
// обновляем значение свойства | |
$result = Bitrix\Sale\Internals\BasketPropertyTable::update($propSize['ID'], [ | |
'VALUE' => '100', | |
]); | |
if (!$result->isSuccess()) | |
{ | |
\Bitrix\Main\Diag\Debug::dump($result->getErrorMessages()); | |
} | |
} |
Универсальные классы
Более крутой способ работы с корзиной – использование класса Bitrix\Sale\Basket.
Если вы работаете в phpStorm не забудьте подключать автоподсветку для классов в блоке с комментариями. Они очень помогут разобраться.
Способы получения объекта корзины:
<? | |
\Bitrix\Main\Loader::includeModule('sale'); | |
$fuser = \Bitrix\Sale\Fuser::getId(); | |
/** | |
* @var \Bitrix\Sale\Basket $basket | |
*/ | |
$basket = Bitrix\Sale\Basket::loadItemsForFUser($fuser, SITE_ID); | |
// если корзина привязана заказа, можно получить так: | |
// по объекту заказа (Bitrix\Sale\Order) | |
$basket = Bitrix\Sale\Basket::loadItemsForOrder($order); | |
// по id заказа | |
$basket = Bitrix\Sale\Order::load($orderId)->getBasket(); | |
// по номеру заказа | |
$basket = Bitrix\Sale\Order::loadByAccountNumber($orderNum)->getBasket(); |
Способы добавления товаров в корзину:
<? | |
/** | |
* @var \Bitrix\Sale\BasketItem $basketItem | |
*/ | |
// первый вариант | |
$basketItem = $basket->createItem('catalog', $productId); // id товара или предложения | |
$basketItem->setField('QUANTITY', 1); | |
// второй вариант | |
$basketItem = \Bitrix\Sale\BasketItem::create($basket, 'catalog', $productId); | |
$basketItem->setField('QUANTITY', 1); | |
$basket->addItem($basketItem); | |
// не забываем сохранить | |
$basket->save(); |
Из корзины можно получить объект интересующей нас позицию, зная ID:
<? | |
/** | |
* @var \Bitrix\Sale\BasketItem $basketItem | |
*/ | |
$basketItem = $basket->getItemById($basketId); // id позиции корзины | |
// какие-нибудь действия | |
$basketItem->setField('QUANTITY', 3); | |
\Bitrix\Main\Diag\Debug::dump($basketItem->getFieldValues()); | |
$basket->save(); |
Пример для демонстрации возможности работы с корзиной
<? | |
\Bitrix\Main\Loader::includeModule('sale'); | |
$fuser = \Bitrix\Sale\Fuser::getId(); | |
/** | |
* @var \Bitrix\Sale\Basket $basket | |
* @var \Bitrix\Sale\BasketItem $basketItem | |
*/ | |
$basket = Bitrix\Sale\Basket::loadItemsForFUser($fuser, SITE_ID); | |
foreach ($basket->getBasketItems() as $basketItem) | |
{ | |
// получение количества | |
$quantity = $basketItem->getField('QUANTITY'); // или getQuantity() | |
// запись количества | |
$basketItem->setField('QUANTITY', $quantity++); | |
\Bitrix\Main\Diag\Debug::dump($basketItem->getFieldValues()); // получить все поля позиции в корзине | |
// добавление или обновление свойства | |
$propCollection = $basketItem->getPropertyCollection(); | |
$props = $propCollection->getPropertyValues(); | |
$props['DESC'] = [ | |
'NAME' => 'Описание', | |
'CODE' => 'DESC', | |
'VALUE' => 'test', | |
]; | |
$propCollection->redefine($props); // или использовать старый setProperty | |
} | |
// не забываем сохранить | |
$basket->save(); |
Запомните, что для работы с полями используются getField и setField, для свойств – как на примере выше получаем коллекцию.
Часто используемые функции:
- Получить количество товара в корзине $basketItem->getQuantity()
- Получить идентификатор корзины $basketItem->getProductId()
- Получить идентификатор товара $basketItem->getId()
- Получить цену товара $basketItem->getPrice()
- Записать количество $basketItem->setField(‘QUANTITY’, 2)
- Получить название $basketItem->getField(‘NAME’)
- Удалить корзину $basketItem->delete()
- Возвратить объект заказа, к которому привязана корзина $basket->getOrder()
- Записать сразу несколько полей $basketItem->setFields([])
Вы можете получить все поля с помощью $basketItem->getFieldValues() и подглядеть коды полей, чтобы затем управлять с помощью методов getField и setField.
Пример создания новой корзины и привязки к заказу
<? | |
/** | |
* @var Bitrix\Sale\Order $order | |
* @var \Bitrix\Sale\Basket $basket | |
* @var \Bitrix\Sale\BasketItem $basketItem | |
*/ | |
\Bitrix\Main\Loader::includeModule('sale'); | |
\Bitrix\Main\Loader::includeModule('currency'); | |
$currencyCode = Bitrix\Currency\CurrencyManager::getBaseCurrency(); | |
$newBasket = Bitrix\Sale\Basket::create($siteId); | |
// добавляем id предложений из массива в корзину | |
foreach ($offerIds as $offerId) | |
{ | |
$basketItem = $newBasket->createItem('catalog', $offerId); | |
$basketItem->setFields([ | |
'QUANTITY' => 1, | |
'CURRENCY' => $currencyCode, | |
'LID' => Bitrix\Main\Context::getCurrent()->getSite(), | |
'PRODUCT_PROVIDER_CLASS' => '\Bitrix\Catalog\Product\CatalogProvider', | |
]); | |
$properties = []; | |
foreach ($props as $property) | |
{ | |
$properties[] = [ | |
'NAME' => $property['NAME'], | |
'CODE' => $property['CODE'], | |
'VALUE' => $property['VALUE'], | |
]; | |
} | |
$basketPropertyCollection = $basketItem->getPropertyCollection(); | |
$basketPropertyCollection->redefine($properties); | |
$newBasket->save(); | |
} | |
// привязываем корзину к заказу | |
$order = Bitrix\Sale\Order::load($orderId); | |
$order->setBasket($basket); | |
$order->save(); |
Заключение
На этом все. В документации Битрикса вы также можете найти подсказки и ответы на свои вопросы. Все моменты, конечно сложно рассмотреть в одной статье, поэтому если у вас есть вопросы, замечания или что добавить – пишите комментарии.