Начиная с 16 версии используется новая версия ядра магазина Битрикс, являющаяся частью ядра Битрикс D7. Но некоторые классы и методы доступны и в 15 версии магазина (sale, не main). Все классы для работы с магазином собраны в модуле sale, поэтому для работы с примерами в статье используем use для пространства имён модуля интернет-магазина.
use Bitrix\Sale;
Корзина (Sale\Basket)
Корзина представляет собой экземпляр класса Bitrix\Sale\Basket.
Корзину можно получить для текущего юзера:
$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), Bitrix\Main\Context::getCurrent()->getSite());
Примечание: getSite работает только в публичной части.
Или получить корзину заказа:
/** int $orderId номер заказа */
$basket = Sale\Order::load($orderId)->getBasket();
// или:
/** Sale\Basket $order объект заказа */
$basket = Sale\Basket::loadItemsForOrder($order);
Информация о корзине:
$price = $basket->getPrice(); // Цена с учетом скидок
$fullPrice = $basket->getBasePrice(); // Цена без учета скидок
$weight = $basket->getWeight(); // Общий вес корзины
Добавление товара в корзину (аналог CSaleBasket::Add), обновление записи и проверка наличия:
/** int $productId ID товара */
/** int $quantity количество */
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',
));
/*
Если вы хотите добавить товар с произвольной ценой, нужно сделать так:
$item->setFields(array(
'QUANTITY' => $quantity,
'CURRENCY' => Bitrix\Currency\CurrencyManager::getBaseCurrency(),
'LID' => Bitrix\Main\Context::getCurrent()->getSite(),
'PRICE' => $customPrice,
'CUSTOM_PRICE' => 'Y',
));
*/
}
$basket->save();
В одной из новых версий модуля catalog был добавлен функционал добавления в корзину:
Bitrix\Main\Loader::includeModule("catalog");
$fields = [
'PRODUCT_ID' => 98, // ID товара, обязательно
'QUANTITY' => 2, // количество, обязательно
'PROPS' => [
['NAME' => 'Test prop', 'CODE' => 'TEST_PROP', 'VALUE' => 'test value'],
],
];
$r = Bitrix\Catalog\Product\Basket::addProduct($fields);
if (!$r->isSuccess()) {
var_dump($r->getErrorMessages());
}
Данный метод проверяет доступность товара к покупке (при отсутствии будет возвращен результат с ошибкой "Товар отсутствует"), сам проверяет наличие товара в корзине и при наличии увеличивает количество товара в корзине. Также к товару добавляются свойства корзины, необходимые для обмена с 1С: PRODUCT.XML_ID и CATALOG.XML_ID. Но при этом нет возможности передать в корзину кастомную цену.
Получение записи по ID и удаление записи из корзины (аналог CSaleBasket::Delete):
/** int $id ID записи */
$basket->getItemById($id)->delete();
$basket->save();
Получение товаров в корзине, доступных для покупки (CAN_BUY=Y):
$orderBasket = $basket->getOrderableItems();
Также есть пара методов для получения корзины в виде, пригодной для использования в письме или для вывода количества товаров:
var_dump($basket->getListOfFormatText()); // возвращает корзину в читаемом виде:
// array(2) { [11]=> string(101) "Тарелка [Цвет: Кофе с молоком] - 2 : 2 199 руб." [12]=> string(65) "Кружка - 1 : 1 899 руб." }
var_dump($basket->getQuantityList()); // возвращает массив "количеств" товаров в корзине:
// array(3) { [11]=> float(2) [12]=> float(1) }
var_dump(array_sum($basket->getQuantityList())); // float(3) - количество товаров в корзине
var_dump(count($basket->getQuantityList())); // int(2) - количество позиций в корзине
Товар в корзине (Sale\BasketItem)
Товары в корзине представлены в виде коллекции объектов класса 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->getPrice(); // Цена за единицу
$item->getQuantity(); // Количество
$item->getFinalPrice(); // Сумма
$item->getWeight(); // Вес
$item->getField('NAME');// Любое поле товара в корзине
$item->canBuy(); // true, если доступно для покупки
$item->isDelay(); // true, если отложено
Также из записи можно получить другие сущности:
$item->getPropertyCollection(); // Свойства товара в корзине, коллекция объектов Sale\BasketPropertyItem, см. ниже
$item->getCollection(); // Корзина, в которой лежит товар
Действия над записями:
$item->setField('QUANTITY', $quantity); // Изменение поля
$item->setFields(array(
'QUANTITY' => $quantity,
'CUSTOM_PRICE' => $customPrice,
)); // Изменение полей
$item->delete(); // Удаление
$item->save(); // Сохранение изменения, можно использовать и $basket->save();
Свойства товаров в корзине (Sale\BasketPropertiesCollection)
У товара в корзине можно получить коллекцию свойств - объект Bitrix\Sale\BasketPropertiesCollection:
/** Sale\BasketItem $item объект товара в корзине */
$basketPropertyCollection = $item->getPropertyCollection();
$basketPropertyCollection->getPropertyValues();
Метод getPropertyValues возвращает массив свойств.
Добавить новое свойство или изменить существующие можно следующим образом:
$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();
ORM-классы
Обращаться напрямую к таблице корзины, без использования объектов можно с использованием 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);
}
Читайте также: