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
  • [phpBB3] Upgrade to phpBB 3.2.3
    Hello.. after Upgrade to phpBB 3.2.3 I am getting this message.. How can I solve this issue..? Thank you
    by ingbrzy
  • [phpBB3] URL path changed
    Hello.. I have changed my site path after moving to new hosting and now can not activate SEO module.. new path http://www.miuios.cz/domains/miuios.cz/ could you help me? thank you
    by ingbrzy2
  • [phpBB3] Chinese language support
    Hi, i bought magic seo for phpbb because it says that it supports a wide range of alphabets and UTF-8, however i found that it doesn't. I'm preparing a website in Chinese and all forums having a...
    by iwsmike
  • [WP2PS] Yoast SEO plugin
    Thanks for your support installing the PS-WP integration. However there is some errors when PS-WP integration is activated. 1. Error generating sitemap with Yoas SEO plugin (it disappears when...
    by argidomin
  • [Zen Cart] How to exclude words from URLs
    I'd like to know if it's possible to configure some stop words (in italian language) to remove from SEO URL. Thanks
    by incircolo
Join our support forum » Pre-Sales Questions »
Featured Testimonials

I have checked our website and it works faster than before, thank you very much!

Jorge, the owner of TN-TOOLS

Magic SEO URLs for osCommerce are amazing product, helps my site a lot with SEO. The biggest advance of Magic SEO URLs is excellent service support. I know what I'm talking about because I had already bought web software from about 10 different companies. Magic SEO URLs is the best one. Keep the quality of the product and service and...

Jacek, the owner of Agro-Modele.pl

More Testimonials »