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.