6

I've written plugin for Magento\Checkout\Controller\Cart::Delete

Plugin works great and removed my desirable product from cart.

As much as I know Minicart is render with local storage. So that we have to update it with sections.xml.

But I looked into it and found that sections.xml only contains actions.

So How can I reload minicart whenever I use plugin ?

UPDATE

Thing is like I want to remove one specific product when any changes made to the cart Like, Update qty, Remove existing item from cart etc.

If any of above changes occur than let's say I've product ID-5 that product needs to be remove from automatically.

Example:

I've 4 products in cart including my free product(has price USD 0)

Item Name  -   Qty    
Product-1  -   1
Product-2  -   2
Product-3  -   1
Product-4  -   1
(Free product) 

If any changes to qty happens to products expect free product than free product needs to be removed and qty update will be there for that product.

PS: I've disabled qty update for free product.

What I've tried.

public function beforeExecute(
        \Magento\Checkout\Controller\Cart\Delete $subject
    )
    {
        $items = $this->checkoutSession->getQuote()->getAllVisibleItems();

        foreach ($items as $item) {
            $product = $this->product->load($item->getProductId());
            if($product->getSku() == $this->helperData->getGeneralConfig('free_product')){ // get product sku 
                $this->cart->removeItem($item->getItemId())->save();

                $this->checkoutSession->getQuote()->collectTotals()->save();
            }
         }

        $customerBeforeAuthUrl = $this->url->getUrl('checkout/cart/');
        $this->responseFactory->create()->setRedirect($customerBeforeAuthUrl)->sendResponse();
        die();

    }

Above is working but minicart isn't update. along with side bar total on cart page.

If you have any other solution rather than plugin than add your solution too.

Any help would be appreciated. Thanks in Advance.

  • not sure but this might be helpful to you - magento.stackexchange.com/questions/178125/… – Rahul Makwana Dec 27 '18 at 14:20
  • No Rahul this is different case. – anonymous Dec 28 '18 at 5:26
  • I am facing this same problem. – Jaimin Dec 28 '18 at 5:53
  • 1
    since minicart is private content, it needs to be invalidated and requested again using javascript to be re-rendered correctly on the frontend, sections.xml is a system to do that, but it can be triggered manually too, are you interested in such an answer? asking because of the "I'm stuck with Plugin only" sentence. – igrossiter Jan 1 at 12:46
  • @igrossiter, Well I have idea about sections.xml but the thing I wanted to achieve i think possible with plugin only. So i added 'i'm stuck with plugin only', but I've added whole thing that needs to be achieve If you have solution for this without plugin.Than I'm glad to look into this. – anonymous Jan 2 at 4:55
1
+25

In your case, you should use checkout_cart_save_before to add/remove your free product whenever cart is saved. You can see my solution here:

  1. app/code/YourVendor/YourModule/etc/frontend/events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_cart_save_before">
        <observer name="training_test_checkout" instance="YourVendor\YourModule\Observer\ValidateFreeProduct"/>
    </event>
</config>
  1. app/code/YourVendor/YourModule/Observer/ValidateFreeProduct.php
<?php

namespace YourVendor\YourModule\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\Checkout\Model\Cart;

class ValidateFreeProduct implements ObserverInterface
{

    /**
     * @param Observer $observer
     * @return void
     */
    public function execute(Observer $observer)
    {
        $event = $observer->getEvent();
        /** @var Cart $cart */
        $cart = $event->getCart();
        if (!$cart instanceof Cart) {
            return;
        }
        $yourCondition = false;
        if (!$yourCondition) {
            $sku = 'your_free_product_sku';
            foreach ($cart->getItems() as $item) {
                if ($item->getProduct()->getSku() == $sku) {
                    $cart->removeItem($item->getItemId());
                }
            }
        }
    }
}

By using this event, when you delete/update your cart, the mini cart will be updated automatically

Cheers

  • Thanks for your effort Lee but same situation mini cart counter is there no changes there. – anonymous Jan 2 at 8:35
  • I tested it's working for me on Magento 2.1.10. Did you try to run php bin/magento clean:cache ? – bachlee89 Jan 2 at 8:38
  • Looks like I can't add my free product to cart due to observer is preventing it. Actually Free product is add to cart by user himself. When quote is more than 50 USD than he will get a pop up with free product and from there he can add free product to cart. So if I use your answer than free product can't be added to cart. – anonymous Jan 2 at 9:20
  • $yourCondition = false; ==> You should change this to your condition, something like $cartTotal>50 or any condition that you need to validate. I think you are a developer so you should know how to make my solution so that it fits you – bachlee89 Jan 2 at 10:26
  • What about minicart ? – anonymous Jan 2 at 12:03

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.