PrestaShop: Cart cache optimization

This howto will explain how to stop dozens of extra queries that are made by an empty cart and significantly speed-up PrestaShop 1.3.

Note: This howto applies only to PrestaShop 1.3.

Open classes/Cart.php and find

if ($this->_products AND !$refresh)
	return $this->_products;

and replace with:

// Product cache must be strictly compared to NULL, or else an empty cart will add dozens of queries
if ($this->_products !== NULL AND !$refresh) {
	// Return product row with specified ID if it exists
	if (is_int($id_product))
	{
		foreach ($this->_products as $product)
			if ($product['id_product'] == $id_product)
				return array($product);
		return array();
	}
	return $this->_products;
}

Find:

/**
 * Return cart products quantity
 *
 * @result integer Products quantity
 */
public	function nbProducts()

Before, add:

public static function cacheSomeAttributesLists($ipaList, $id_lang)
{
	$paImplode = array();
	foreach ($ipaList as $id_product_attribute)
		if (intval($id_product_attribute) AND !array_key_exists($id_product_attribute.'-'.$id_lang, self::$_attributesLists))
		{
			$paImplode[] = intval($id_product_attribute);
			self::$_attributesLists[intval($id_product_attribute).'-'.$id_lang] = array('attributes' => '', 'attributes_small' => '');
		}
	if (!count($paImplode))
		return;

	$result = Db::getInstance()->ExecuteS('
	SELECT pac.`id_product_attribute`, agl.`public_name` AS public_group_name, al.`name` AS attribute_name
	FROM `'._DB_PREFIX_.'product_attribute_combination` pac
	LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute`
	LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
	LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.intval($id_lang).')
	LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.intval($id_lang).')
	WHERE pac.`id_product_attribute` IN ('.implode($paImplode, ',').')
	ORDER BY agl.`public_name` ASC');

	foreach ($result as $row)
	{
		self::$_attributesLists[$row['id_product_attribute'].'-'.$id_lang]['attributes'] .= $row['public_group_name'].' : '.$row['attribute_name'].', ';
		self::$_attributesLists[$row['id_product_attribute'].'-'.$id_lang]['attributes_small'] .= $row['attribute_name'].', ';
	}

	foreach ($paImplode as $id_product_attribute)
	{
		self::$_attributesLists[$id_product_attribute.'-'.$id_lang]['attributes'] = rtrim(self::$_attributesLists[$id_product_attribute.'-'.$id_lang]['attributes'], ', ');
		self::$_attributesLists[$id_product_attribute.'-'.$id_lang]['attributes_small'] = rtrim(self::$_attributesLists[$id_product_attribute.'-'.$id_lang]['attributes_small'], ', ');
	}
}

Find:

public static function getNbProducts($id)
{
	if (self::$_nbProducts > 0)
		return self::$_nbProducts;
	self::$_nbProducts = intval(Db::getInstance()->getValue('SELECT SUM(`quantity`) FROM `'._DB_PREFIX_.'cart_product` WHERE `id_cart` = '.intval($id)));
	return self::$_nbProducts;

Replace with:

public static function getNbProducts($id)
{
	// Must be strictly compared to NULL, or else an empty cart will bypass the cache and add dozens of queries
	if (isset(self::$_nbProducts[$id]) && self::$_nbProducts[$id] !== NULL)
		return self::$_nbProducts[$id];
	self::$_nbProducts[$id] = intval(Db::getInstance()->getValue('
		SELECT SUM(`quantity`)
		FROM `'._DB_PREFIX_.'cart_product`
		WHERE `id_cart` = '.intval($id)));
	return self::$_nbProducts[$id];
}

Open class/Product.php file:

Find:

/**
* Admin panel product search
*
* @param integer $id_lang Language id
* @param string $query Search query
* @return array Matching products
*/
static public function searchByName($id_lang, $query)

Before, add:

public static function cacheProductsFeatures($productIds)
{
	$productImplode = array();
	foreach ($productIds as $id_product)
		if (intval($id_product) AND !array_key_exists($id_product, self::$_cacheFeatures))
			$productImplode[] = intval($id_product);
	if (!count($productImplode))
		return;

	$result = Db::getInstance()->ExecuteS('
	SELECT id_feature, id_product, id_feature_value
	FROM `'._DB_PREFIX_.'feature_product`
	WHERE `id_product` IN ('.implode($productImplode, ',').')');
	foreach ($result as $row)
	{
		if (!array_key_exists($row['id_product'], self::$_cacheFeatures))
			self::$_cacheFeatures[$row['id_product']] = array();
		self::$_cacheFeatures[$row['id_product']][] = $row;
	}
}

Save and close all files and it’s done.

Leave a Reply

Your email address will not be published. Required fields are marked *

Cart  
(empty)

Cart Check out  »

Prices are tax inclusive.

The VAT rate for your country (US) * is 0,0 % because it is not a member of the European Union (EU).

* Please create an account if your country does not match.

Community feed
  • [phpBB] Issue with Activation
    Hi, I just bought the SEO Magic Url Plugin for phpbb 3.2 I am having issue with activation. I have the php 7 install in my site/server. Read me file says its 5.6 , do i need the 5.6 or it...
    by pornera
  • [phpBB] Issue with Tapatalk
    After Installation of Magic SEO URLs for phpBB v3.0/3.1/3.2 5.1 we have an issue with viewing some random threads in Tapatalk app which shows this issue My config: PHP 5.4 PhpBB 3.0.12...
    by ingbrzy
  • [PrestaShop] Theme Provider FREE 1.4
    where I can download this plugin for testing mode before I byu it? thank you. DB
    by daryl0
  • [phpBB3] How to disable Magic SEO URL for phpBB?
    Moderator note: A new update of the Magic SEO URLs for phpBB 3.0/3.1/3.2 has been released. It comes with the phpBB 3.0/3.1/3.2 support as well as PHP 7.0 support. Hello ! I want to...
    by Binano
  • [Zen Cart] How to add .html to urls
    How do I get .html added to the product url? I could not find any mention in the documentation.
    by jekingwws
Join our support forum » Pre-Sales Questions »
Featured Testimonials

Great work - great support - great tool! Thank you for your whole work and your great support. We're very glad with the plugin and our online portals now run much faster than before.

Alexander, the owner of Die Wirtschaft Köln

Search friendly URL's are very important for marketing any site, let alone an e-commerce site like CRE Loaded. A client site built on CRE Loaded needed a plug-in to fix the PHP based URL's. Magic SEO URLs are running flawlessly and doing exactly what it is supposed to: providing those search friendly URL's. I had them install it as well...

Chad, the owner of Website Marketing & Website Development

More Testimonials »