prestashop-1.7

Add related products (product_accessories) in Prestashop 1.7 shopping cart modal


anyone knows how to add related products inside add to cart modal in prestashop 1.7.6?

I mean:

{block name='product_accessories'}
  {if $accessories}
    {foreach from=$accessories item="product_accessory"}
      {block name='product_miniature'}
        {include file='catalog/_partials/miniatures/product-related.tpl' product=$product_accessory}
      {/block}
    {/foreach}
  {/if}
{/block}

Do you know how to do that?

Thank you


Solution

  • It's trickier than it seems. It is trivial to modify the template as it would just be the case of overriding the file "modal.tpl" in the ps_shoppingcart module i.e. in your theme, create the file 'modules/ps_shoppingcart/modal.tpl' and then copy the original from the module and customise it. Adding something like this in the "modal-body" div:

        <div class="row">
          {if isset($accessories) && $accessories}
            {foreach from=$accessories item="product_accessory"}
                {include file="$theme_tpl_path" product=$product_accessory}
            {/foreach}
          {/if}
        </div>
    

    We'll come back to $theme_tpl_path in a bit. However it is a lot more difficult when it comes to the template variables...

    You need to get the accessories and this would have to be done in your own version of the ps_shoppingcart module (they would have to be assigned in the Ps_Shoppingcart::renderModal() member function). It could be done in an override of the FrontController class but that's not really any better. Regardless you need to replicate what's in the ProductController class in your version of the module (or modify the module and live with the consequences of remembering you can't update it without losing your changes):

    public function renderModal($id_product, $id_product_attribute, $id_customization)
    {
        $data = $this->getPresentedCart();
        $product = null;
        foreach ($data['products'] as $p) {
            if ((int) $p['id_product'] == $id_product &&
                (int) $p['id_product_attribute'] == $id_product_attribute &&
                (int) $p['id_customization'] == $id_customization) {
                $product = $p;
                break;
            }
        }
    
        $presenterFactory = new ProductPresenterFactory($this->context);
        $presentationSettings = $presenterFactory->getPresentationSettings();
        $presenter = new \PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingPresenter(
            new ImageRetriever(
                $this->context->link
            ),
            $this->context->link,
            new PriceFormatter(),
            new ProductColorsRetriever(),
            $this->context->getTranslator()
        );
        $tempProduct = new Product($product->id);
        $accessories = $tempProduct->getAccessories($this->context->language->id);
        if (is_array($accessories)) {
            foreach ($accessories as &$accessory) {
                $accessory = $presenter->present(
                    $presentationSettings,
                    Product::getProductProperties($this->context->language->id, $accessory, $this->context),
                    $this->context->language
                );
            }
            unset($accessory);
        }
        $this->smarty->assign([
            'accessories' => $accessories,
            'theme_tpl_path'=> _PS_THEME_DIR_.'templates/catalog/_partials/miniatures/product.tpl',
            'product' => $product,
            'cart' => $data,
            'cart_url' => $this->getCartSummaryURL(),
        ]);
    
        return $this->fetch('module:ps_shoppingcart/modal.tpl');
    }
    

    The above will use the template file for product miniatures from your theme and the template has to be passed via that variable otherwise it complains. There might be a better way but honestly it isn't something I do often and this works.

    Note that you will need to include the following above the module class definition also:

    use PrestaShop\PrestaShop\Adapter\Image\ImageRetriever;
    use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter;
    use PrestaShop\PrestaShop\Adapter\Product\ProductColorsRetriever;
    

    (Edit: This code will only work with PS 1.7.5 onwards I believe.)