如何以编程方式将产品添加到购物车

redmaomail 2024-07-24 18:18 阅读数 68 #Magento

红帽云邮外贸主机

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

本文假设:

  • 我们正在将代码添加到名为 Magenest\Example 的自定义模块中,路径为“example”
  • 自定义添加到购物车功能在 Magenest\Example\Controller\Product 的控制器中执行

如何使用报价模型将产品添加到购物车

控制器 AddToCart 处理发送到路径“example/product/addToCart”的 GET 请求,并使用存储在请求参数中的信息将产品添加到购物车。

<?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。

如何使用其他选项将产品添加到购物车

addProduct 函数可以适应简单参数格式和高级参数格式。这允许您向购物车项目添加其他选项和数据。

/**
* @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();
}

Product 的“additional_options”将显示在购物车页面上:

购物车页面上的产品附加选项

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

将一些具有特殊类型的产品添加到购物车可能需要提供额外的选项。假设您知道所需的具体参数值,您还可以将这些产品添加到购物车中。以下是将捆绑产品添加到购物车的一般格式:

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

   $buyRequest = new \Magento\Framework\DataObject([ 
       // super_group 用于设置分组产品中子项目的数量
       'super_group' => [ 
           10 => "1", // value is pass as $sub-productId => $qty 
           20 => "2" 
       ], 

       // 添加捆绑产品需要两个选项:'bundle_option' 和 'bundle_option_qty' 
       // 两个选项都作为索引数组传递,
       'bundle_option' => ["2", "4", "5"], // 使用捆绑产品 'selection_id' 添加项目,而不是实际产品 ID 
       'bundle_option_qty' => ["1", "2", " 3"], 

       // 可配置的产品选项使用 'super_attribute' 传递 option 
       'super_attribute' => [ 
           143 => "168", // 格式为 $optionId => $optionValue 
           93 => "58" 
       ] 
   ]); 

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

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

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

例如,可以使用函数 getConfigurableAttributes() 或 getConfigurableAttributesAsArray() 提取可配置产品属性。这使我们可以使用其简单的 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:

可配置产品的可配置 SKU

以编程方式添加到购物车时触发迷你购物车更新

与每次访问时都请求最新数据的购物车页面不同,迷你购物车内容使用 Magento 的 customer-data.js 库缓存在客户端。

这个缓存只能通过在客户端机器上执行Javascript来清除;因为服务器通常不能请求清除客户端上保存的数据。因此,customer-data.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 允许使用sections.xml 配置文件来配置这些端点服务器端:

Magenest/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 请求都将触发重新加载“购物车”数据,而无需手动向 AJAX 请求添加回调。


红帽云邮外贸主机

分享到:
版权声明:本站内容源自互联网,如有内容侵犯了你的权益,请联系删除相关内容。
    红帽云邮外贸主机
热门
    红帽云邮外贸主机
    红帽云邮外贸主机