在本文中,我们将向您展示如何在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
将特殊类型的产品添加到购物车
将某些特殊类型的产品添加到购物车可能需要提供其他选项。假设您知道所需的特定参数值,也可以将这些产品添加到购物车中。以下是将捆绑产品添加到购物车的一般格式
/**
* @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:
迷你购物车更新
与每次访问时都请求最新数据的购物车页面不同,迷你购物车内容使用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申请添加回调。