Working with a basket in Bitrix D7, bitrix.basket.basket
Rus
Eng
Работа с корзиной в Битрикс D7

All English-language materials have been translated fully automatically using the Google service

Section navigation:

Working with the basket in Bitrix D7

Starting from version 16, a new version of the Bitrix store core is used, which is part of the Bitrix D7 core. But some classes and methods are available in the 15 version of the store (sale, not main). All classes for working with the store are collected in the sale module, so to work with the examples in the article, we use use for the namespace of the online store module.

use Bitrix\Sale;

Sale \ Basket

The basket is an instance of the Bitrix \ Sale \ Basket class.

The shopping cart can be obtained for the current user:

$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), Bitrix\Main\Context::getCurrent()->getSite());

Note: getSite only works in the public area.

Or get an order basket:

/** int $orderId номер заказа */
$basket = Sale\Order::load($orderId)->getBasket();
// или:
/** Sale\Basket $order объект заказа */
$basket = Sale\Basket::loadItemsForOrder($order);

Shopping cart information:

$price = $basket->getPrice(); // Цена с учетом скидок
$fullPrice = $basket->getBasePrice(); // Цена без учета скидок
$weight = $basket->getWeight(); // Общий вес корзины

Adding a product to the cart (analogous to CSaleBasket :: Add ), update record and check for availability:

 // amount
$ quantity = 1;

// product ID (trade catalog)
$ productId = 233;

// Get the cart for the current user
$ basket = \ Bitrix \ Sale \ Basket :: loadItemsForFUser (
   \ Bitrix \ Sale \ Fuser :: getId (),
   \ Bitrix \ Main \ Context :: getCurrent () -> getSite ()
);

if ($ item = $ basket-> getExistsItem ("catalog", $ productId)) {

   // Update the item in the cart
   $ item-> setField ("QUANTITY", $ item-> getQuantity () + $ quantity);
} else {

   // Add product
   $ item = $ basket-> createItem ("catalog", $ productId);
   $ item-> setFields ([
      "QUANTITY" => $ quantity,
      "CURRENCY" => \ Bitrix \ Currency \ CurrencyManager :: getBaseCurrency (),
      "LID" => \ Bitrix \ Main \ Context :: getCurrent () -> getSite (),
      "PRODUCT_PROVIDER_CLASS" => \ Bitrix \ Catalog \ Product \ Basket :: getDefaultProviderName (),
   ]);
}

// Save changes
$ basket-> save ();
    / *
    If you want to add a product with an arbitrary price, you need to do this:
    $ item-> setFields (array (
        "QUANTITY" => $ quantity,
        "CURRENCY" => Bitrix \ Currency \ CurrencyManager :: getBaseCurrency (),
        "LID" => Bitrix \ Main \ Context :: getCurrent () -> getSite (),
        "PRICE" => $ customPrice,
        "CUSTOM_PRICE" => "Y",
   ));
   * /
 

In one of the new versions of the catalog module, the functionality of adding to cart has been added:

 require_once ($ _ SERVER ['DOCUMENT_ROOT']. '/ bitrix / modules / main / include / prolog_before.php');

use Bitrix \ Main \ Application;

Bitrix \ Main \ Loader :: includeModule ("catalog");

$ request = Application :: getInstance () -> getContext () -> getRequest ();

$ fields = [
    'PRODUCT_ID' => intval ($ request-> getPost ("id")), // product ID, required
    'QUANTITY' => intval ($ request-> getPost ("quantity")), // quantity, required
    'PROPS' => [
        ['NAME' => 'basket_detail', 'CODE' => 'basket_detail', 'VALUE' => $ request-> getPost ("basket_detail")],
    ],

];

$ r = Bitrix \ Catalog \ Product \ Basket :: addProduct ($ fields);
if (! $ r-> isSuccess ()) {
    var_dump ($ r-> getErrorMessages ());
}  

This method checks the availability of a product for purchase (if it is absent, the result will be returned with the error "Product is missing"), it checks the availability of the product in the basket and, if available, increases the quantity of the product in the basket. Also, cart properties are added to the product, which are necessary for exchange with 1C: PRODUCT.XML_ID and CATALOG.XML_ID. However, there is no way to transfer a custom price to the cart.

Retrieving an entry by ID and deleting an entry from the basket (analogous to CSaleBasket :: Delete ):

 / ** int $ id record ID * /
$ basket-> getItemById ($ id) -> delete ();
$ basket-> save ();  

Receiving items in the cart available for purchase (CAN_BUY = Y):

 $ orderBasket = $ basket-> getOrderableItems ();  

There are also a couple of methods for getting the cart in a form suitable for use in a letter or for displaying the number of products:

 var_dump ($ basket-> getListOfFormatText ()); // returns the cart in readable form:
// array (2) {[11] => string (101) "Plate [Color: Coffee with milk] - 2: 2 199 rubles." [12] => string (65) "Mug - 1: 1 899 rubles." }
var_dump ($ basket-> getQuantityList ()); // returns an array of "quantities" of items in the cart:
// array (3) {[11] => float (2) [12] => float (1)}

var_dump (array_sum ($ basket-> getQuantityList ())); // float (3) - the number of items in the cart
var_dump (count ($ basket-> getQuantityList ())); // int (2) - the number of items in the cart  

Product in the basket (Sale \ BasketItem)

Products in the basket are presented as a collection of objects of the Bitrix \ Sale \ BasketItem class:

 $ basketItems = $ basket-> getBasketItems (); // array of Sale \ BasketItem objects  

Sale \ Basket implements the \ ArrayAccess, \ Countable, and \ IteratorAggregate interfaces, so the cart object can be treated like an array, retrieving items in the cart by index or iterating over records using foreach:

 foreach ($ basket as $ basketItem) {
    echo $ basketItem-> getField ("NAME"). "-". $ basketItem-> getQuantity (). "
";
}  

Information about items in the cart:

 $ item = $ basketItems [0];
$ item-> getId (); // ID of the item in the cart
$ item-> getProductId (); // product ID
$ item-> getPrice (); // Unit price
$ item-> getQuantity (); // Number
$ item-> getFinalPrice (); // Sum
$ item-> getWeight (); // The weight
$ item-> getField ("NAME"); // Any field of the item in the cart
$ item-> canBuy (); // true if available for purchase
$ item-> isDelay (); // true if deferred  

You can also get other entities from the record:

 $ item-> getPropertyCollection (); // Properties of the item in the cart, collection of Sale \ BasketPropertyItem objects, see below
$ item-> getCollection (); // Cart containing the product  

Actions on records:

 $ item-> setField ("QUANTITY", $ quantity); // Change the field
$ item-> setFields (array (
    "QUANTITY" => $ quantity,
    "CUSTOM_PRICE" => $ customPrice,
)); // Change fields

$ item-> delete (); // Delete
$ item-> save (); // Save changes, you can also use $ basket-> save ();  

Properties of items in the cart (Sale \ BasketPropertiesCollection)

You can get a collection of properties for the item in the basket - the Bitrix \ Sale \ BasketPropertiesCollection object:

 / ** Sale \ BasketItem $ item item in the basket * /
$ basketPropertyCollection = $ item-> getPropertyCollection ();
$ basketPropertyCollection-> getPropertyValues ​​();  

The getPropertyValues ​​method returns an array of properties.

You can add a new property or change existing ones as follows:

 $ basketPropertyCollection-> setProperty (array (
    array (
       "NAME" => "Color",
       "CODE" => "COLOR",
       "VALUE" => "Coffee with milk",
       "SORT" => 100,
    ),
));
$ basketPropertyCollection-> save ();  

An example of removing a property:

 foreach ($ basketPropertyCollection as $ propertyItem) {
    if ($ propertyItem-> getField ("CODE") == "COLOR") {
        $ propertyItem-> delete ();
        break;
    }
}
$ basketPropertyCollection-> save ();  

Updating product properties when added to cart

Let's say we need to update or add some properties of an item in the cart before adding it there, depending on the parameters.

In my case, I needed to display the checkbox in the cart. And depending on the combination of the request POST conditions and product properties, set its checked value as true or false

Add to init.php

  use Bitrix \ Main \ EventManager;

$ eventManager = EventManager :: getInstance ();

$ eventManager-> addEventHandler ('sale', 'OnSaleBasketBeforeSaved', ["AvtoHandlers", "OnSaleBasketBeforeSaved"]);

class AvtoHandlers
{
    function OnSaleBasketBeforeSaved (Main \ Event $ event)
    {
        \ CModule :: IncludeModule ('iblock');

        $ request = Application :: getInstance () -> getContext () -> getRequest ();

        / ** @var Basket $ basket * /
        $ basket = $ event-> getParameter ("ENTITY");
        $ basketItems = $ basket-> getBasketItems ();
        foreach ($ basketItems as $ basketItem) {
            if ($ basketItem-> getProductId ()! = $ request-> get ('id')) {
                continue;
            }

            $ rs = CIBlockElement :: GetList (
                Array (),
                Array ("ID" => $ basketItem-> getProductId ()),
                false,
                false,
                array ('ID', 'IBLOCK_ID', 'PROPERTY_STOIMOST_DONORSKOY_ZAPCHASTI')
            ) -> fetch ();
            if (! $ rs || empty ($ rs ['PROPERTY_STOIMOST_DONORSKOY_ZAPCHASTI_VALUE'])) {
                continue;
            }

            $ isCustomPrice = $ basketItem-> getField ('CUSTOM_PRICE')? $ basketItem-> getField ('CUSTOM_PRICE'): 'N';

            // POST property and product do not match
            if ($ request-> get ('basket_detail') == 'N' && $ isCustomPrice == 'N') {
                $ basketItem-> setFields (array (
                    'PRICE' => $ basketItem-> getPrice () + $ rs ['PROPERTY_STOIMOST_DONORSKOY_ZAPCHASTI_VALUE'],
                    'CUSTOM_PRICE' => 'Y',
                ));
            }

            // POST property and product are the same
            if ($ request-> get ('basket_detail') == 'Y' && $ isCustomPrice == 'Y') {
                $ basketItem-> setFields (array (
                    'PRICE' => $ basketItem-> getPrice () - $ rs ['PROPERTY_STOIMOST_DONORSKOY_ZAPCHASTI_VALUE'],
                    'CUSTOM_PRICE' => 'N',
                ));
            }
        }

        return new Main \ EventResult (Main \ EventResult :: SUCCESS);

    }
}  

In the basket itself, go to the file /local/templates/Your_site_template/components/bitrix/sale.basket.basket/Your_basket_template/mutator.php and add in the loop foreach ($ this- > basketItems as $ row) {

  // Additional parameter
if (! empty ($ row ['PROPERTY_STOIMOST_DONORSKOY_ZAPCHASTI_VALUE'])) {
$ rowData ['DONOR_PRICE'] = $ row ['PROPERTY_STOIMOST_DONORSKOY_ZAPCHASTI_VALUE'];
if ($ row ['CUSTOM_PRICE'] == 'N') {
$ rowData ['DONOR_GIVE'] = true;
}
}  

And in the file local / templates / Your_site_template / components / bitrix / sale.basket.basket / Your_basket_template / js-templates / basket-item.php paste in the right place

 {{#DONOR_PRICE}}
<input data-donor-checker = "Y" data-basket-item-id = "{{ID}}" data-product-id = "{{PRODUCT_ID}}"
data-quantity = "{{QUANTITY}}" id = "basket_detail _ {{ID}}" name = "basket_detail _ {{ID}}"
class = "js - basket_detail" value = "Y" type = "checkbox" {{#DONOR_GIVE}} checked = "checked" {{/ DONOR_GIVE}} />
<label for = "basket_detail _ {{ID}}"> Text of your checkbox </label>
{{/ DONOR_PRICE}} 

The solution was applied at the Small Business v18.1.8 edition

ORM classes

You can directly access the basket table, without using objects, using the ORM class Bitrix \ Sale \ Internals \ BasketTable. For example, iterate over the items in the current user's cart:

 $ 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);
}  

And in this way we can get the number and amount of goods in the basket of the current user:

 $ 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 ();  

The Bitrix \ Sale \ Internals \ BasketPropertyTable class will help to get the properties of goods in the basket:

 $ basketPropRes = Sale \ Internals \ BasketPropertyTable :: getList (array (
   "filter" => array (
      "BASKET_ID" => $ basketItemId,
   ),
));

while ($ property = $ basketPropRes-> fetch ()) {
   var_dump ($ property);
}  

Updating the sale.basket.basket component after ajax request

  BX.Sale.BasketComponent.sendRequest ('refreshAjax', {fullRecalculation: 'Y'});

BX.Sale.BasketComponent.fillTotalBlocks ();
for (itemId in BX.Sale.BasketComponent.items) {
if (BX.Sale.BasketComponent.items.hasOwnProperty (itemId)) {
BX.Sale.BasketComponent.redrawBasketItemNode (itemId);
}
}  

Updating the sale.basket.line component after ajax request

Defining an event in the template.php

template
  BX.addCustomEvent (window, 'OnBasketChange', sbbl.refreshCart);  

Raising an event in a script

BX.onCustomEvent('OnBasketChange');</code> </pre>
<h3 id = 'floatAnimation'> Animation for adding a product to cart </h3>
<p> Let's say we have a button to the cart with the class <code>js-basket-simple</code> </p>
<p> And we need the animation of adding an item to the cart when clicking on it. We will go the simplest way - add elements in place of the button and animate the path from it to our cart. The whole code will look like this: </p>
<pre><code> function sSend (e) {
// Get the coordinates of the element where the additional flying layer should be displayed
    var x = e.pageX,
        y = e.pageY;

// Insert a new div with a svg basket image that will fly to the basket and shrink
    $ ('body'). append ('<div class = "toCart" style = "position: absolute; fill: # FF0000; width: 25px; height: 25px; border-radius: 100px; z-index: 9999999999; left : '+ x +' px; top: '+ y +' px; "> <svg width =" 25 "height =" 25 "style =" max-width: 100% "viewBox =" 0 0 32 32 "fill =" none "xmlns =" ​​http://www.w3.org/2000/svg "> \ n '+
        '\ t \ t \ t \ t \ t \ t \ t \ t \ t <path d = "M30.5255 31.203L28.1345 8.92653C28.0947 8.56787 27.7758 8.28892 27.4172 8.28892H22.9938V6.934C22.9938 3.10834 19.8854 0 16.0598 0C12.2341 0 9.12579 3.10834 9.12579 6.934V8.28892H4.58282C4.22417 8.28892 3.90536 8.56787 3.86551 8.92653L1.47448 31.203C1.43463 31.4022 1.51433 31.6015 1.63388 31.7609C1.75343.831 C30.4857 31.6015 30.5654 31.4022 30.5255 31.203ZM22.2765 12.3138C22.6351 12.3138 22.9141 12.5928 22.9141 12.9514C22.9141 13.3101 22.6351 13.589 22.2765 13.589C21.9178 13.589 21.6389 13.589C21.9178 13.589 21.6389 13.910.5 5604 3.90535 13.0311 1.43462 16.0598 1.43462C19.0884 1.43462 21.5592 3.90535 21.5592 6.934V8.28892H10.5604V6.934ZM9.8431 12.3138C10.2018 12.3138 10.4807 12.5928 10.4807 12.9514C10.4807 13.49.59. 20549 12.5928 9.48444 12.3138 9.8431 12.3138 ZM2.9888 30.5255L5.22043 9.68369H9.12579V10.9988C8.32877 11.2777 7.77087 12.0349 7.77087 12.9116C7.77087 14.0274 8.68743 14.944 9.80325 14.944C10.9191 14.944 11.8356 14.0276117C10.9356 11.8356 14.027677 11.8356 9988C20.6824 11.2777 20.1245 12.0349 20.1245 12.9116C20.1245 14.0274 21.0411 14.944 22.1569 14.944C23.2727 14.944 24.1893 14.0274 24.1893 12.9116C24.1893 12.0349 23.6314 11.2777 22.8348 30H2529.529. > </path> \ n '+
        '\ t \ t \ t \ t \ t \ t \ t \ t </svg> </div>');

// The class of our basket, the element will fly here
    var cart = $ ('. header-cart'). offset ();

    $ ('. toCart'). animate ({top: cart.top + 'px', left: cart.left + 'px', width: 0, height: 0}, 1300, function () {
        $ (this) .remove ();
    });

}

(function ($) {
    $ (document) .on ('click', '. js-basket-simple', function (e) {
        sSend (e);
    });
}) (jQuery);

Information from the site mrcappuccino

Comments

There are no comments yet, you can be the first to leave it

Leave a comment

The site uses a comment pre-moderation system, so your message will be published only after approval by the moderator

You are replying to a user's comment

Send

FEEDBACK

Email me

Are you developing a new service, making improvements to the existing one and want to be better than your competitors? You have come to the right place. I offer you a comprehensive studio-level website development. From me you can order design, layout, programming, development of non-traditional functionality, implementation of communication between CMS, CRM and Data Analitics, as well as everything else related to sites, except for promotion.

Contact, I will always advise on all questions and help you find the most effective solution for your business. I am engaged in the creation of sites in Novosibirsk and in other regions of Russia, I also work with the CIS countries. You will be satisfied with our cooperation

An error occurred while sending, please try again after a while
Message sent successfully

Phones

+7(993) 007-18-96

Email

info@tichiy.ru

Address

Россия, г. Москва

By submitting the form, you automatically confirm that you have read and accept the Privacy Policy site

Contact with me
Send message
By submitting the form, you automatically confirm that you have read and accept Privacy policy of site
Sending successful!
Thank you for contacting :) I will contact you as soon as possible
Sending failed
An error occurred while sending the request. Please wait and try again after a while or call my phone number