9

What I want to do is if my custom attribute is set in quote then i do not want any product to be added in cart. My custom attribute is being set correctly.

To stop product from getting added to cart, I have written an Observer which observes this event controller_action_predispatch_checkout_cart_add

My observer file code:

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

With this code, I am able not able to stop the add to cart process.

So as per this answer of Magento1 - https://stackoverflow.com/questions/14190358/stop-add-to-cart-and-supply-message-to-user-in-magento . I tried replacing

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

with (This is not the best way of doing it. If there is any better way, please suggest)

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

This ultimately stops the add to cart process but the add to cart button still keeps on showing "Adding". How can i perform this correctly so that add to cart button goes back to its previous state and the product too does not get added to cart ?

enter image description here

  • hi @reena can you help me how you did that – mcoder Apr 18 '16 at 10:15
  • @mcoder - i did it with a plugin. u can refer the accepted answer below for more details. – Reena Parekh Apr 18 '16 at 11:12
  • i tried but can not do can you please help me how you did that i have same issue as you see what i tried : magento.stackexchange.com/questions/111231/… but it did not worked – mcoder Apr 18 '16 at 13:07
  • i want to redirect to external url like google.com i tried below one it redirect to to ajax add cart url , i am stuck for two days but could not do it :(. I will try to donate for you help – mcoder Apr 18 '16 at 13:10
  • How can you get solution?? can you give me all the file whith code ? i have the same problem – Jigs Parmar Mar 22 '18 at 10:48
20

you could try to set the product param to false and then set the return_url param:

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

The cart controller checks if the product param is set here: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L99

and if it is not, it calls goBack. the goBack method checks if you made an ajax request (I think you did) and then returns an additional param backUrl in the ajax response.

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

The getBackUrl method then returns the return_url param:

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

===UPDATE===

ok since the message adding does not work here, you should try another way (it's also more straight forward)

create a Plugin to Intercetp before this function: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Model/Cart.php#L341

If you do not want your product added, just throw an Exception with the desired Message. You find a nice tutorial for creating plugins here: http://alanstorm.com/magento_2_object_manager_plugin_system

The Product adding should be interrupted and the Exception should be rendered as message https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L137

add the following type to your modules 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>

Then the class Vendor/Module/Model/Checkout/Cart/Plugin should look like this:

<?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
    Thank you David. Your solution works, upvote from me. However, the error message does not get displayed. I am assuming because of this line : github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/… ? Can you suggest how can i resolve that ? – Reena Parekh Feb 13 '16 at 6:23
  • 1
    yes, jut added another solution. Be sure to clean the var/generation folder and the configuration cache to have these changes applied – David Verholen Feb 13 '16 at 7:10
  • Used your 1st method but not able to get the error message, How can i set the return url and message in your 2nd method. – Amit Singh Dec 29 '16 at 11:25
  • 1
    Can you tell, how can I get custom option values here? – anujeet Apr 24 '17 at 10:12
  • +1 Absolutely brilliant! Perfect solution (the update). Works with 2.1.5. – Dave May 12 '17 at 0:10
0

Remove the last three line code

And add this one line: return false; And set value of product param: false Then you get error message and loader is hide... Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.