Search code examples
smartyprestashopprestashop-1.6

Prestashop: how to display messages in the cart


i'm working in a quota module for PrestaShop 1.6 and in one of the features is that a need to display a message in the cart's page and in that modal that opens when you add an item to the cart from the home page.

I'm working with the hookCart the hook function, public function hookCart($params), is in my module's class. From it I can get the instance of the Controller like this $this->context->controller

My question is how to display messages in these two views? I tried adding them to the errors array. I can see the message but not the way I'm supposed to display. I would like to display in those alert classes from bootstrap.

The views: enter image description here

enter image description here

Can you help me?


Solution

  • To display a message on the checkout page you can use whatever front controller hook you want. I guess the one that makes most sense would be displayTop. We won't be outputting any html to the top but just add a message to the controller's errors array.

    public function hookDisplayTop()
    {
        $controller = $this->context->controller;
        if ($controller->php_self != 'order' && $controller->php_self != 'order-opc') {
            return false;
        }
        /* 
            You can do custom logic here if you want to display message only
            on some conditions or only on specific step of the checkout
        */
        $controller->errors[] = $this->l('Some message');
    
        return false;
    }
    

    For the popup the things get messy because:

    1. Popup doesn't have an error display area
    2. Blockcart AJAX uses weird logic that calls CartController which includes blockcart-ajax.php which loads blockcart module method which loads a JSON template file to output data (???)

    One way to do this is to use the hook actionCartSave. This hook gets executed on pretty much all cart operations, so we need to make sure we are adding our message when a product is added to cart, uses ajax etc.

    public function hookActionCartSave()
    {
        // If cart doesn't exist or product is not being added to cart in ajax mode - do nothing
        if (!$this->context->cart || !Tools::getValue('id_product) || !Tools::getValue('add') || !Tools::getValue('ajax')) {
            return false;
        }
        /* 
            You can do custom logic here if you want to display message only
            on some conditions
        */
        $this->context->smarty->assign('mycartpopupmessage', $this->l('Message');
    
        return false;
    }
    

    Then you will have to modify themes/default-bootstrap/modules/blockcart/blockcart-json.tpl file to add your message into JSON template.

    ...
    "wrappingCost": {$wrapping_cost|json_encode},
    "nbTotalProducts": {$nb_total_products|intval},
    "total": {$total|json_encode},
    {if isset($mycartpopupmessage)}
        "mycartpopupmessage": {$mycartpopupmessage|json_encode},
    {/if}
    ....
    

    Then you need to modify themes/default-bootstrap/js/modules/blockcart/ajax-cart.js and add the following

    if (jsonData.mycartpopupmessage) {
        $('#layer_cart .alert-message').html(jsonData.mycartpopupmessage);
        $('#layer_cart .alert').removeClass('hidden');
    }
    else {
        $('#layer_cart .alert').addClass('hidden');
    }
    

    And at last modify themes/default-bootstrap/modules/blockcart/blockcart.tpl and add alert div

    <div class="alert alert-danger hidden">
        <button data-dismiss="alert" type="button" class="close">×</button>
        <p>{l s='There is 1 error' mod='mymodule'}</p>
        <ol>
            <li class="alert-message"></li>
        </ol>
    </div>
    

    Now you should be getting a bootstrap alert inside a popup.

    Quite some native prestashop modules haven't been (I guess) updated in years as a lot of them are good candidates for an extensive rework or at least compliant with the MVC workflow which would make modifications like yours much more simple.