У платформы 1С-Битрикс: Управление сайтом есть одна интересная особенность. Неавторизованный пользователь накидывает корзину, потом решает авторизоваться и... теряет все то, что накидал в корзину.
Это происходит потому, что у неавторизованного и авторизованного пользователей разный FUSER и при авторизации происходит переключение с одного на другого.
Есть простое решение
Просто в файл bitrix/php_interface/init.php добавляем следующий код
use Bitrix\Sale\Basket;
use Bitrix\Sale\Fuser;
use Bitrix\Main\Context;
Loader::includeModule('sale');
Loader::includeModule('catalog');
{
$siteId = Context::getCurrent()->getSite();
$fuserId = Fuser::getId();
$basket = Basket::loadItemsForFUser($fuserId, $siteId);
}
В данном случае мы просто подставляем корзину неавторизованного пользователя авторизованному. Но, теряем корзину авторизованного.
Делаем красивее
Все работы ведем там же или делаем подключаемый файл, тут как вам удобнее. И подключаем все необходимые классы.
use Bitrix\Main\Loader;
use Bitrix\Main\Context;
use Bitrix\Sale\Basket;
use Bitrix\Sale\Fuser;
use Bitrix\Sale\Internals\FuserTable;
use Bitrix\Main\Engine\CurrentUser;
Loader::includeModule('sale');
Loader::includeModule('catalog');
Loader::includeModule('iblock');
Работаем с двумя типами юзеров
Получим текущий FUSER - анонимный до авторизации, после же тот, что будет в сессии
$currentFuserId = Fuser::getId();
FUSER, который уже был привязан к авторизованному пользователю - это его старая корзинка
$userId = (int)CurrentUser::get()->getId();
if ($userId <= 0)
{
return;
}
$oldFuserId = Fuser::getIdByUserId($userId); // может совпасть с currentFuserId
Если старого FUSER нет или он совпадает с текущим — делать нечего
if (!$oldFuserId || $oldFuserId == $currentFuserId)
{
return;
}
Теперь работаем непосредственно с корзинками
Загружаем корзины и сохраняем их данные
Текущую корзину ставим основной
$currentBasket = Basket::loadItemsForFUser($currentFuserId, $siteId);
Старую же корзину всю переводим в статус отложенной
$oldBasket = Basket::loadItemsForFUser($oldFuserId, $siteId);
foreach ($oldBasket as $basketItem)
{
// Только не оформленные заказом позиции
if ($basketItem->getField('ORDER_ID') === null)
{
$basketItem->setField('DELAY', 'Y');
}
}
Таким образом мы те товары, что пользователи ранее накидывали себе в корзину просто будут в отложенных и всегда могут быть возвращены в основную корзину.
Если есть ошибки то их нужно обработать
$result = $oldBasket->save();
if (!$result->isSuccess())
{
// обработать ошибки при необходимости
}
Ну и наконец привязываем текущую корзину к пользователю, т.е. гостевую делаем боевой.
FuserTable::update($currentFuserId, [
'USER_ID' => $userId,
]);
Вот собственно и все.
Подпишитесь на наш телеграм - https://t.me/official_3rednet
#bitrix #разработка #корзина