Magento2 如何往购物车添加商品

在本文中,我们将向您展示如何在Magento 2中以编程方式将产品添加到购物车中。当您想向购物车中的项目添加其他数据、添加需要自定义逻辑的产品或只是为购买您产品的客户添加礼物时,这是最有用的

使用Quote Model往购物车添加商品

controller

<?php
namespace Magenest\Example\Controller\Product;

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Exception\LocalizedException;

/**
* Class AddToCart
* @package Magenest\BookingReservation\Controller\Product
*/
class AddToCart extends Action implements HttpGetActionInterface
{
   /** @var \Magento\Checkout\Model\SessionFactory */
   private $checkoutSession;

   /** @var \Magento\Quote\Api\CartRepositoryInterface */
   private $cartRepository;

   /** @var \Magento\Catalog\Api\ProductRepositoryInterface */
   private $productRepository;

   /** @var \Magento\Framework\Serialize\Serializer\Json */
   private $json;

   /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable */
   private $configurableType;

   /**
     * AddToCart constructor.
     * @param Context $context
     * @param \Magento\Framework\Serialize\Serializer\Json $json
     * @param \Magento\Checkout\Model\SessionFactory $checkoutSession
     * @param \Magento\Quote\Api\CartRepositoryInterface $cartRepository
     * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
     * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableType
     */
   public function __construct(
       Context $context,
       \Magento\Framework\Serialize\Serializer\Json $json,
       \Magento\Checkout\Model\SessionFactory $checkoutSession,
       \Magento\Quote\Api\CartRepositoryInterface $cartRepository,
       \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
       \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableType
   ) {
       $this->checkoutSession = $checkoutSession;
       $this->cartRepository = $cartRepository;
       $this->productRepository = $productRepository;
       $this->json = $json;
       $this->configurableType = $configurableType;
       parent::__construct($context);
   }

   /**
    * @return ResultInterface
    * @throws LocalizedException
    */
   public function execute()
   {
       $product = $this->productRepository->getById($this->getRequest()->getParam('id'));
       $qty = $this->getRequest()->getParam('qty');

       $session = $this->checkoutSession->create();
       $quote = $session->getQuote();
       $quote->addProduct($product, $qty);

       $this->cartRepository->save($quote);
       $session->replaceQuote($quote)->unsLastRealOrderId();
   }
}

您可以仅使用产品ID将产品添加到购物车。数量参数是可选的:如果参数为空,报价模型将假定数量为1

添加带有Custom Option的购物车

/**
* @throws LocalizedException
*/
public function addProductWithOptions()
{
   $productSku = $this->getRequest()->getParam('sku');
   $qty       = $this->getRequest()->getParam('qty');

   /**
    * You can specify custom options for a product before adding it to cart
    */
   $product = $this->productRepository->get($productSku);
   $product->addCustomOption('additional_options', $this->json->serialize([
       'custom_option_1' => [
           'label' => __("Custom Option 1"),
           'value' => 10
       ],
       'custom_option_2' => [
           'label' => __("Custom Option 2"),
           'value' => 20
       ]
   ]));

   /**
    * The second parameter of addProduct function can either be an integer, or a Magento DataObject
    * An integer will be interpreted as quantity added
    * Using a DataObject will allow adding custom data to cart items; these data will be saved and can be retrieved as info_buyRequest of quote/order items
    */
   $buyRequest = new \Magento\Framework\DataObject([
       'qty' => $qty,
       'related_product' => '',
       'custom_option' => '?'
   ]);

   $session = $this->checkoutSession->create();
   $quote = $session->getQuote();
   $quote->addProduct($product, $buyRequest);

   $this->cartRepository->save($quote);
   $session->replaceQuote($quote)->unsLastRealOrderId();
}

购物车页面会显示Custom Option


image.png

将特殊类型的产品添加到购物车

将某些特殊类型的产品添加到购物车可能需要提供其他选项。假设您知道所需的特定参数值,也可以将这些产品添加到购物车中。以下是将捆绑产品添加到购物车的一般格式

/**
* @throws LocalizedException
*/
public function addSpecialProduct()
{
   $productId = $this->getRequest()->getParam('id');
   $product = $this->productRepository->getById($productId);

   $buyRequest = new \Magento\Framework\DataObject([
       // super_group is used to set quantity for sub-items in grouped product
       'super_group' => [
           10 => "1", // value is pass as $sub-productId => $qty
           20 => "2"
       ],

       // adding bundle product require two options: 'bundle_option' and 'bundle_option_qty'
       // both options are passed as indexed array, and items in two array will be matched using their index
       'bundle_option'     => ["2", "4", "5"], // items are added using bundle product 'selection_id', not actual product id
       'bundle_option_qty' => ["1", "2", "3"],

       // configurable product options are passed using 'super_attribute' option
       'super_attribute' => [
           143 => "168", // the format are $optionId => $optionValue
           93 => "58"
       ]
   ]);

   $session = $this->checkoutSession->create();
   $quote = $session->getQuote();
   $quote->addProduct($product, $buyRequest);

   $this->cartRepository->save($quote);
   $session->replaceQuote($quote)->unsLastRealOrderId();
}

每个特殊产品类型都有自己的函数来获取特殊属性。请参阅这些产品的类型模型,以了解如何手动添加它们。

例如,可以使用函数getConfigurableAttributes()或getConfiguraableAttributesAsArray()提取可配置产品属性。这允许我们使用简单的SKU将可配置产品添加到购物车中:

/**
* @throws LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
private function addConfigurableProduct()
{
   $childId = $this->getRequest()->getParam('id');
   $childProduct = $this->productRepository->getById($childId);

   /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable configurableType */
   $parentId = $this->configurableType->getParentIdsByChild($childId);
   if (($parentId = reset($parentId)) !== false) {
       $parentProduct = $this->productRepository->getById($parentId);
       $productAttributeOptions = $this->configurableType->getConfigurableAttributesAsArray($parentProduct);

       $options = [];
       foreach ($productAttributeOptions as $option) {
           $options[$option['attribute_id']] =  $childProduct->getData($option['attribute_code']);
       }
       $buyRequest = new \Magento\Framework\DataObject(['super_attribute' => $options]);

       $session = $this->checkoutSession->create();
       $quote = $session->getQuote();
       $quote->addProduct($parentProduct, $buyRequest);

       $this->cartRepository->save($quote);
       $session->replaceQuote($quote)->unsLastRealOrderId();
   }
}

应始终将可配置产品添加为具有自定义选项的可配置SKU,而不是简单的SKU:


image.png

迷你购物车更新

与每次访问时都请求最新数据的购物车页面不同,迷你购物车内容使用Magento的客户数据缓存在客户端。js库。
此缓存只能通过在客户端机器上执行Javascript来清除;因为服务器通常无法请求清除保存在客户端上的数据。因此,对客户数据进行缓存失效和重新加载。js通常发生在客户端触发事件时,如成功的AJAX请求。

可以将迷你购物车配置为在完成对addToCart端点的AJAX请求时进行更新:

require([
   'jquery',
   'mage/url',
   'Magento_Customer/js/customer-data'
], function ($, urlBuilder, customerData) {
   $.ajax({
       type: 'POST',
       data: {
           product_id: ...,
           qty: ...
       },
       url: urlBuilder.build('example/product/addToCart'),
       complete: function () {
           // you might not need this section if you're using sections.xml instead
           customerData.invalidate(['cart']);
           customerData.reload(['cart'], true);
       },
       success: ...,
       error: ...
   })
});

然而,每次直接调用这些函数并不是很有效。Magento允许使用节配置这些端点服务器端。改为xml配置文件:
Example/etc/frontend/sections.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
   <action name="example/product/addToCart">
       <section name="cart"/>
   </action>
</config>

现在,所有使用Magento 2 AJAX库发送到“example/product/addToCart”的AJAX请求都将触发重新加载“cart”数据,而无需手动向AJAX申请添加回调。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容