V
V
Vladimir2018-11-19 17:33:22
1C-Bitrix
Vladimir, 2018-11-19 17:33:22

How to create a user cart using API without authorization, without $USER for any user?

API function call code that leads to the problem:

Loader::includeModule('catalog');
Loader::includeModule('sale');
            
arFUser = CSaleUser::GetList(['USER_ID' => $userId]);
 $basket = Sale\Basket::loadItemsForFUser($arFUser['ID'], SITE_ID);
        
 if ($item = $basket->getExistsItem('catalog', $productId)) {
       $item->setField('QUANTITY', $item->getQuantity() + $quantity);
 } else {
                
        $item = $basket->createItem('catalog', $productId);
       //функция которая вызывает ошибку "setFields"                
       $item->setFields([
            'QUANTITY' => $quantity,
            'CURRENCY' => \Bitrix\Currency\CurrencyManager::getBaseCurrency(),
            'LID' => SITE_ID,
            'PRODUCT_PROVIDER_CLASS' => \Bitrix\Catalog\Product\Basket::getDefaultProviderName(),
      ]);
     $basketPropertyCollection = $item->getPropertyCollection(); 
     $basketPropertyCollection->setProperty($arProps);              
}
            
  $saveResult = $basket->save(); 
   if(!$saveResult->isSuccess())
        $arError[] = implode(', ', $saveResult->getErrors());

Hello.
I am creating a mobile API for a store on Bitrix. I call a function that creates a shopping cart for the user specified in the request ($userId).
The code above only works if a shopping cart has already been created for the specified user.
If the basket is empty ($basket->isEmpty()), an error occurs at the stage specified in the code:
2018-11-19 10:00:24 - Host: www.....ru:443 - UNCAUGHT_EXCEPTION - [Error] Call to a member function GetID() on null (0)
/home/bitrix/ext_www/.../bitrix/modules/sale/lib/basketitemcollection.php:258
#0: Bitrix\Sale\BasketItemCollection->getContext()
/ home/bitrix/ext_www/.../bitrix/modules/sale/lib/basketbase.php:1075
#1: Bitrix\Sale\BasketBase->getContext()
/home/bitrix/ext_www/.../bitrix/modules/sale/lib/basketitembase.php:591
#2: Bitrix\Sale\BasketItemBase->onFieldModify(string, double, double)
/home/bitrix/ext_www/. ../bitrix/modules/sale/lib/basketitem.php:962
#3: Bitrix\Sale\BasketItem->onFieldModify(string, NULL, integer)
/home/bitrix/ext_www/.../bitrix/modules/sale /lib/internals/entity.php:217
#4: Bitrix\Sale\Internals\Entity->setField(string, integer)
/home/bitrix/ext_www/.../bitrix/modules/sale/lib/basketitembase.php :381
#5: Bitrix\Sale\BasketItemBase->setField(string, integer)
/home/bitrix/ext_www/.../bitrix/modules/sale/lib/internals/entity.php:399
#6: Bitrix\Sale \Internals\Entity->setFields(array)
/home/bitrix/ext_www/.../bitrix/modules/sale/lib/basketitembase.php:479
#7: Bitrix\Sale\BasketItemBase->setFields(array)
/home/bitrix/ext_www/.../api /controllers/v1/basket.php:172 - here is the code of my function
#8: Api\Controllers\v1\Basket->add()
/home/bitrix/ext_www/.../bitrix/modules/artamonov.api/lib /controller.php:99
#9: Artamonov\Api\Controller->startObjectOriented()
/home/bitrix/ext_www/.../bitrix/modules/artamonov.api/lib/controller.php:30
#10: Artamonov\ Api\Controller->run()
/home/bitrix/ext_www/.../bitrix/modules/artamonov.api/lib/router.php:71
#11: Artamonov\Api\Router->start()
/home/ bitrix/ext_www/.../bitrix/modules/artamonov.api/lib/init.php:29
#12: Artamonov\Api\Init->start()
/home/bitrix/ext_www/.../bitrix/php_interface/init.php:2
#13: include_once(string)
/home/bitrix/ext_www/.../bitrix/modules/main/include.php:234
# 14: require_once(string)
/home/bitrix/ext_www/.../bitrix/modules/main/include/prolog_before.php:14
#15: require_once(string)
/home/bitrix/ext_www/.../bitrix/ modules/main/include/prolog.php:10
#16: require_once(string)
/home/bitrix/ext_www/.../bitrix/header.php:1
#17: require(string)
/home/bitrix/ext_www/ .../404.php:7
#18: include_once(string)
/home/bitrix/ext_www/.../bitrix/urlrewrite.php:4
The following method is called in the basketitemcollection.php file:
public function getContext()   {      
global $USER;
      $context = array();

      /** @var BasketItem $basketItem */
      $basketItem = $this->rewind();
      if ($basketItem)
      {

         $siteId = $basketItem->getField('LID');
         $fuserId = $basketItem->getFUserId();
         $currency = $basketItem->getCurrency();

         $userId = Fuser::getUserIdById($fuserId);

         if (empty($context['SITE_ID']))
         {
            $context['SITE_ID'] = $siteId;
         }

         if (empty($context['USER_ID']) && $userId > 0)
         {
            $context['USER_ID'] = $userId;
         }

         if (empty($context['CURRENCY']) && !empty($siteId))
         {
            if (empty($currency))
            {
               $currency = Internals\SiteCurrencyTable::getSiteCurrency($siteId);
            }

            if (!empty($currency) && Currency\CurrencyManager::checkCurrencyID($currency))
            {
               $context['CURRENCY'] = $currency;
            }
         }
      }

      if (empty($context['SITE_ID']))
      {
         $context['SITE_ID'] = SITE_ID;
      }

      if (empty($context['USER_ID']))
      {
         $context['USER_ID'] = $USER->GetID() > 0 ? $USER->GetID() : 0;
      }

      if (empty($context['CURRENCY']))
      {
         Loader::includeModule('currency');
         $context['CURRENCY'] = Currency\CurrencyManager::getBaseCurrency();
      }

      return $context;
   }

In getContext() there is a call "$USER->GetID()" which leads to an error, because the user is not authorized by means of Bitrix and the global array $USER is not created.
How can the problem be solved? Maybe you can somehow pass the value of FUserId to the $item->setFields() method, so that the "$USER->GetID()" call would not occur?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
E
Eugene, 2018-11-19
@lycifep

Your call comes from init.php, at this stage there is no global object of the CUser class yet, it is created later, it is better to use the OnPageStart event.
But you can use the well-known "crutch", but this is not entirely correct,
global $USER;
$USER = new CUser();
And you will have a working instance of $USER, and the GetID method will return NULL, but there will be no more errors, and further along the code, the class will be re-initialized already by Bitrix as usual.

A
Alexey Bille, 2018-11-19
@alexey_bille

$userId = ...;
$fuserId = \Bitrix\Sale\Fuser::getIdByUserId($userID);
$basket = \Bitrix\Sale\Basket::loadItemsForFUser($fuserId , Bitrix\Main\Context::getCurrent()->getSite());

A
Andrey Nikolaev, 2018-11-19
@gromdron

You cannot create an order without having a user in the system while maintaining the normal operation of the system.
1C-Bitrix normally works only in two options:
1) You register a user and place an order for him
2) You must require authorization from the user before creating an order
As you can see, authorization is checked at a lower level and you will not be able to do it.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question