Magento2-如何阻止以编程方式将产品添加到购物车?


13

我想做的是,如果在引号中设置了我的自定义属性,那么我不想在购物车中添加任何产品。我的自定义属性已正确设置。

为了阻止产品添加到购物车,我编写了一个观察该事件的观察者 controller_action_predispatch_checkout_cart_add

我的观察者文件代码:

public function execute(\Magento\Framework\Event\Observer $observer) {
    $addedItemId = $observer->getRequest()->getParam('product');
    $quote       = $this->_cart->getQuote();

    if(!empty($quote)) {
        $customAttribute = $quote->getData('custom_attribute');

        if(!empty($customAttribute)) {
             $controller = $observer->getControllerAction();
             $storeId     = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getId();
             $product    = $this->_productRepository->getById($addedItemId, false, $storeId);
             $observer->getRequest()->setParam('product', null);

             $this->_messageManager->addError(__('This product cannot be added to your cart.'));
             echo false;            

             $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
             $this->redirect->redirect($controller->getResponse(), 'checkout/cart/index');          
        }
    }       
}

使用此代码,我无法停止添加到购物车的过程。

所以,按照Magento1的这个答案- /programming/14190358/stop-add-to-cart-and-supply-message-to-user-in-magento。我尝试更换

$this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
$this->redirect->redirect($controller->getResponse(), 'checkout/cart/index');  

与(这不是最好的方法。如果有更好的方法,请提出建议)

header("Location: " . $product->getProductUrl());
die();

最终,这将停止添加到购物车过程,但是“添加到购物车”按钮仍保持显示“正在添加”。如何正确执行此操作,以便“添加到购物车”按钮返回到其先前的状态,并且产品也不会添加到购物车?

在此处输入图片说明


喜@reena你能帮助我,你是怎么做的
mcoder

@mcoder-我是用插件做的。您可以参考以下接受的答案以获取更多详细信息。
Reena Parekh

我尝试了但不能做,您能不能帮我解决您遇到的问题?magento.stackexchange.com/questions/111231/… 但是它没有用
mcoder

我想重定向到google.com之类的外部URL,我尝试将其重定向到ajax,然后添加购物车url,我被困了两天,但做不到:(。我会尽力为您提供帮助
mcoder

您如何获得解决方案?您能给我所有文件和代码吗?我有同样的问题
Jigs Parmar

Answers:


22

您可以尝试将产品参数设置为false,然后设置return_url参数:

$observer->getRequest()->setParam('product', false);
$observer->getRequest()->setParam('return_url', $this->_redirect->getRefererUrl());
$this->_messageManager->addError(__('This product cannot be added to your cart.'));

购物车控制器检查是否在此处设置了产品参数:https : //github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L99

如果不是,它将调用goBack。goBack方法检查您是否提出了ajax请求(我认为您已经这样做了),然后在ajax响应中返回了另一个参数backUrl。

https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L165

然后,getBackUrl方法返回return_url参数:

https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart.php#L113

===更新===

好的,因为添加消息在这里不起作用,您应该尝试其他方法(这也更直接)

在此功能之前创建一个Intercetp插件:https : //github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Model/Cart.php#L341

如果您不希望添加产品,则只需将异常与所需的消息一起抛出即可。您可以在此处找到用于创建插件的不错的教程:http : //alanstorm.com/magento_2_object_manager_plugin_system

产品添加应被中断,并且异常应显示为消息https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L137

将以下类型添加到模块中etc / frontend / di.xml

<type name="Magento\Checkout\Model\Cart">
    <plugin name="interceptAddingProductToCart"
            type="Vendor\Module\Model\Checkout\Cart\Plugin"
            sortOrder="10"
            disabled="false"/>
</type>

然后该类Vendor/Module/Model/Checkout/Cart/Plugin应如下所示:

<?php
namespace Vendor\Module\Model\Checkout\Cart;

use Magento\Framework\Exception\LocalizedException;

class Plugin
{
    /**
     * @var \Magento\Quote\Model\Quote
     */
    protected $quote;

    /**
     * Plugin constructor.
     *
     * @param \Magento\Checkout\Model\Session $checkoutSession
     */
    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession
    ) {
        $this->quote = $checkoutSession->getQuote();
    }

    /**
     * beforeAddProduct
     *
     * @param      $subject
     * @param      $productInfo
     * @param null $requestInfo
     *
     * @return array
     * @throws LocalizedException
     */
    public function beforeAddProduct($subject, $productInfo, $requestInfo = null)
    {
        if ($this->quote->hasData('custom_attribute')) {
            throw new LocalizedException(__('Could not add Product to Cart'));
        }

        return [$productInfo, $requestInfo];
    }
}

1
谢谢大卫。您的解决方案有效,请向我投票。但是,错误消息不会显示。我假设因为这一行:github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/…?你能建议我如何解决吗?
Reena Parekh

1
是的,突出添加了另一个解决方案。确保清除var / generation文件夹和配置缓存以应用这些更改
David Verholen

使用了您的第一种方法,但无法获得错误消息,如何在第二种方法中设置返回网址和消息。
阿米特·辛格

1
您能告诉我如何在此处获取自定义选项值吗?
anujeet

+1绝对辉煌!完美的解决方案(更新)。适用于2.1.5。
戴夫

2

下面是我的代码,用于阻止将产品添加到购物车并使用观察器显示错误消息。

<?php
use Magento\Framework\Event\ObserverInterface;

class ProductAddCartBefore implements ObserverInterface
{

    protected $_request;
    protected $_checkoutSession;
    protected $_messageManager;

    public function __construct(
        \Magento\Framework\App\RequestInterface $request,  
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Checkout\Model\SessionFactory $checkoutSession
    )
    {
        $this->_request = $request;
        $this->_messageManager = $messageManager;
        $this->_checkoutSession = $checkoutSession;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $productId = $observer->getRequest()->getParam('product');

        $quote = $this->_checkoutSession->create()->getQuote();

        $itemsCount = $quote->getItemsSummaryQty();

        if($itemsCount > 0 && $productId != 1949)
        {
            if($quote->hasProductId(1949)) 
            {   
                $observer->getRequest()->setParam('product', false);
                $observer->getRequest()->setParam('return_url', false);
                $this->_messageManager->addErrorMessage(__('To proceed please remove other items from the cart.'));
            }
        }
    }
}

您可以根据需要设置条件,以防止产品添加到购物车中。


这对我有用。
哈桑·杰西

0

删除最后三行代码

并添加这一行:return false; 并设置产品参数的值:false然后您将收到错误消息,并且装载程序处于隐藏状态...谢谢

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.