Magento – Magento 2 – Setting “Continue Shopping Url” programmatically

magento-2.1shopping-cart

I have a custom module that will do some processing on a product when it receives a POST and then it will add that product to the cart and redirect the user to the checkout/cart page.

When on the Cart page, the "Continue Shopping" button simply redirects the user to the home page. As part of the original POST product processing, I have the fully qualified domain URL the user came from (same domain).

Is there a way to set the "Continue Shopping" url before I redirect the user to the Cart?

class Add extends Cart
{
    $resultRedirect = $this->resultRedirectFactory->create(); // DI from Cart.php

    $returnUrl = $post['returnUrl'];

    // ... some data processing ...

    $this->cart->addProduct($product, $params);
    $this->cart->save();

    // Set the "Continue Shopping" button URL
    // ??

    // Redirect to Shopping Cart page
    return $resultRedirect->setPath('checkout/cart');
}

I noticed in the Cart block vendor\magento\module-checkout\Block\Cart.php there is a getContinueShoppingUrl() method…

// vendor\magento\module-checkout\Block\Cart.php
public function getContinueShoppingUrl()
{
    $url = $this->getData('continue_shopping_url');
    if ($url === null) {
        $url = $this->_checkoutSession->getContinueShoppingUrl(true);
        if (!$url) {
            $url = $this->_urlBuilder->getUrl();
        }
        $this->setData('continue_shopping_url', $url);
    }
    return $url;
}

And it looks like it's pulling some data from either a view bag or session with a key of continue_shopping_url. I'm wondering how I can set this value from my custom Controller such that when I redirect the page, it can pick up the URL I'd like it to use?

I tried setting the registry but that didn't seem to work:

$this->registry->register('continue_shopping_url', $returnUrl);

Thanks!

Best Answer

You need to write a plugin to achieve this. For that define di.xml file in your module.

File: app/code/<Namespace>/<Module>/etc/frontend/di.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Cart">
        <plugin disabled="false" name="NamespaceModuleBlockCartBeforePlugin" sortOrder="1" type="Namespace\Module\Plugin\Magento\Checkout\Block\Cart"/>
    </type>
</config>

Then in your plugin class, add the below code:

File: app/code/<Namespace>/<Module>/Plugin/Magento/Checkout/Block/Cart.php

<?php

namespace Namespace\Module\Plugin\Magento\Checkout\Block;

use Magento\Checkout\Block\Cart as CheckoutCart;
use Magento\Checkout\Model\Session;

class Cart
{
    protected $_checkoutSession;

    public function __construct(Session $session) {
        $this->_checkoutSession   = $session;
    }

    public function beforeGetContinueShoppingUrl(CheckoutCart $subject)
    {
        $url = $subject->getData('continue_shopping_url');
        if ($url === null) {
            $url = $this->_checkoutSession->getContinueShoppingUrl(true);
            if (!$url) {
                $url = $this->getCustomUrl();
            }
            $subject->setData('continue_shopping_url', $url);
        }

        return $this;
    }

    public function getCustomUrl()
    {
        //add the logic to get your custom url
        return $customUrl;
    }
}

As you can see, our plugin method is beforeGetContinueShoppingUrl here. The code is similar to the method \Magento\Checkout\Block\Cart::getContinueShoppingUrl(), except that we are setting the default URL with the call $this->getCustomUrl(). In this way, we are respecting the core code and hence an update to the core code logic to generate (in future) continue_shopping_url will not be altered.

Now you need to define the method getCustomUrl() as you needed.

After the changes made, it is good to perform php bin/magento setup:di:compile and php bin/magento cache:flush.

You are done.