Creating a “Clear cart” button in PrestaShop 1.7

Let’ see how to create a button to empty the PrestaShop 1.7 shopping cart in one click!

  • Version used: Prestashop 1.7.2.4

In this tutorial we will see how to apply my previous guide on Creating a “Clear cart” button in PrestaShop to PrestaShop 1.7, as it doesn’t work out of the box because of the new template.

The basic code still works, and the process is more or less the same, though the files needing modifications are totally different. For this tutorial, I will be using the classic (or standard) template, so wherever you read “themename”, just put classic. As a side not, please notice some files might be different if you use a custom PrestaShop theme.

Adding the button to the cart page in PrestaShop 1.7

The PrestaShop 1.7 template structure is quite different from 1.6, so we need to account for that. The main view for the cart is now located at themes/*themename*/templates/checkout/, and it’s called cart.tpl. Open it up, and locat the following block:

      {block name='cart_overview'}
        {include file='checkout/_partials/cart-detailed.tpl' cart=$cart}
      {/block}

This represents the products list block, and we want to add the button right after it:

    <a class="btn btn-primary" style="float:right" id="removeAll" href="javascript:void(0)">
      Empty Cart
    </a>

At this point, unlike 1.6 where we could add our code directly to the template, with PrestaShop 1.7 we have to use a new file, named custom.js.

Adding new javascript to a PrestaShop 1.7 template

Open up custom.js, located in themes/*themename*/assets/js.
It’s empty by default, so if not (as in the case of custom templates), just add the code at the end.

This file is loaded on all pages, and since we only want to run it on the cart one, we have to wrap our snippet with a condition:

if(prestashop.page.page_name == 'cart')
{}

The prestashop javascript variable is a new global available in all pages of the shop, which contains a number of useful data that can be used in scripts. In this case, we use the current page name.

Here is all the rest of the code we need:

$(document).ready(function() {

	    $('#removeAll').click(function(e) {
	        e.preventDefault()
	        $.ajax({
	            type: 'POST',
	            headers: { "cache-control": "no-cache" },
	            url: prestashop.urls.base_url + "cart",
	            async: true,
	            cache: false,
	            data: 'deleteAll=1&token=' + prestashop.token + '&ajax=true',
	            success: function(data){	
	                window.location.reload();
	            }
	        })
	    });
	});	

Explanation: we are using the prestashop variable again, this time to fetch the base url. The cart controller, which we will be editing shortly, can be accessed at /cart by default, so we pass this url to the ajax call.
For the querystring, we pass in deleteAll, to make sure we can refer to this action in the next step, a token required by PrestaShop 1.7, and ajax=true, so that the cart know the action has to be run in ajax mode.
If the call is successful, we refresh the page to show that the cart is now empty.

Editing the CartController

PrestaShop 1.7 discourages the use of overrides, but we will use one in any case :)
Create a new file in override/controllers/front, and name it cartController.php. Reach back the original cart controller in the main controllers/front, and copy the whole updateCart method, pasting it into our new file:

    protected function updateCart()
    {
        // Update the cart ONLY if $this->cookies are available, in order to avoid ghost carts created by bots
        if ($this->context->cookie->exists() && !$this->errors && !($this->context->customer->isLogged() && !$this->isTokenValid())) {
            if (Tools::getIsset('add') || Tools::getIsset('update')) {
                $this->processChangeProductInCart();
            } elseif (Tools::getIsset('delete')) {
                $this->processDeleteProductInCart();
            } elseif (CartRule::isFeatureActive()) {
                if (Tools::getIsset('addDiscount')) {
                    if (!($code = trim(Tools::getValue('discount_name')))) {
                        $this->errors[] = $this->trans('You must enter a voucher code.', array(), 'Shop.Notifications.Error');
                    } elseif (!Validate::isCleanHtml($code)) {
                        $this->errors[] = $this->trans('The voucher code is invalid.', array(), 'Shop.Notifications.Error');
                    } else {
                        if (($cartRule = new CartRule(CartRule::getIdByCode($code))) && Validate::isLoadedObject($cartRule)) {
                            if ($error = $cartRule->checkValidity($this->context, false, true)) {
                                $this->errors[] = $error;
                            } else {
                                $this->context->cart->addCartRule($cartRule->id);
                            }
                        } else {
                            $this->errors[] = $this->trans('This voucher does not exist.', array(), 'Shop.Notifications.Error');
                        }
                    }
                } elseif (($id_cart_rule = (int)Tools::getValue('deleteDiscount')) && Validate::isUnsignedId($id_cart_rule)) {
                    $this->context->cart->removeCartRule($id_cart_rule);
                    CartRule::autoAddToCart($this->context);
                }
            }
        } elseif (!$this->isTokenValid() && Tools::getValue('action') !== 'show' && !Tools::getValue('ajax')) {
            Tools::redirect('index.php');
        }
    }

All we have to do now is add our condition, as part of all those ELSEIFs:

            elseif (Tools::getIsset('deleteAll')) {
                $this->context->cart->delete();
                $this->context->cookie->id_cart = 0;
                die(1);
            }

Here is the final code:

    protected function updateCart()
    {
        // Update the cart ONLY if $this->cookies are available, in order to avoid ghost carts created by bots
        if ($this->context->cookie->exists() && !$this->errors && !($this->context->customer->isLogged() && !$this->isTokenValid())) {
            if (Tools::getIsset('add') || Tools::getIsset('update')) {
                $this->processChangeProductInCart();
            } elseif (Tools::getIsset('delete')) {
                $this->processDeleteProductInCart();

            } elseif (Tools::getIsset('deleteAll')) { /* Nemo */
                $this->context->cart->delete();
                $this->context->cookie->id_cart = 0;
                die(1);
            } elseif (CartRule::isFeatureActive()) {
                if (Tools::getIsset('addDiscount')) {
                    if (!($code = trim(Tools::getValue('discount_name')))) {
                        $this->errors[] = $this->trans('You must enter a voucher code.', array(), 'Shop.Notifications.Error');
                    } elseif (!Validate::isCleanHtml($code)) {
                        $this->errors[] = $this->trans('The voucher code is invalid.', array(), 'Shop.Notifications.Error');
                    } else {
                        if (($cartRule = new CartRule(CartRule::getIdByCode($code))) && Validate::isLoadedObject($cartRule)) {
                            if ($error = $cartRule->checkValidity($this->context, false, true)) {
                                $this->errors[] = $error;
                            } else {
                                $this->context->cart->addCartRule($cartRule->id);
                            }
                        } else {
                            $this->errors[] = $this->trans('This voucher does not exist.', array(), 'Shop.Notifications.Error');
                        }
                    }
                } elseif (($id_cart_rule = (int)Tools::getValue('deleteDiscount')) && Validate::isUnsignedId($id_cart_rule)) {
                    $this->context->cart->removeCartRule($id_cart_rule);
                    CartRule::autoAddToCart($this->context);
                }
            }
        } elseif (!$this->isTokenValid() && Tools::getValue('action') !== 'show' && !Tools::getValue('ajax')) {
            Tools::redirect('index.php');
        }
    }

We are done! Reach the back office, Advanced Parameters, Performance, and hit the clear cache button on the top right, so that the override takes place.

Should it not work, check that Disable all overrides is set to no, right below on the same page. If it still doesn’t, try editing the core CartController.php.

You like the tuts and want to say "thank you"? Well, you can always feel free to donate:

You like the tuts and want to say "thank you"? Well, you can always feel free to donate: