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.

10
  • not sure but this might be helpful to you - magento.stackexchange.com/questions/178125/…
    – Mac
    Dec 27, 2018 at 14:20
  • No Rahul this is different case.
    – anonymous
    Dec 28, 2018 at 5:26
  • I am facing this same problem.
    – Jaimin
    Dec 28, 2018 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, 2019 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, 2019 at 4:55

1 Answer 1

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

7
  • Thanks for your effort Lee but same situation mini cart counter is there no changes there.
    – anonymous
    Jan 2, 2019 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, 2019 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, 2019 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, 2019 at 10:26
  • What about minicart ?
    – anonymous
    Jan 2, 2019 at 12:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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