Caching Modules on PrestaShop

Let’s see an important examples: the category tree block (/modules/blockcategories.php)

i will show only the function that does the sql queries (that we are going to cache!).
Watch out for the Tools::getCache and Tools::setCache!

function hookLeftColumn($params)
	global $smarty, $cookie;

	global $link;

	if (!$catOldTheme=Tools::getCache('blockCatOldTheme'.((!is_null($cookie->id_lang))?'_'.$cookie->id_lang:''))) //read cache
		$catOldTheme=Category::getHomeCategories(intval($params['cookie']->id_lang), true);
		Tools::setCache('blockCatOldTheme'.((!is_null($cookie->id_lang))?'_'.$cookie->id_lang:''),$catOldTheme); //set cache

		'categories' => $catOldTheme,
		'link' => $link
	/* ELSE */

	$id_customer = intval($params['cookie']->id_customer);
	$maxdepth = Configuration::get('BLOCK_CATEG_MAX_DEPTH');

	if (!$result=Tools::getCache('blockCatNewTheme'.((!is_null($cookie->id_lang))?'_'.$cookie->id_lang:''))) //read cache
		FROM `'._DB_PREFIX_.'category` c
		LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (c.`id_category` = cl.`id_category` AND `id_lang` = '.intval($params['cookie']->id_lang).')
		LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category`)
		WHERE 1'
		.(intval($maxdepth) != 0 ? ' AND `level_depth` <= '.intval($maxdepth) : '').'
		AND (c.`active` = 1 OR c.`id_category`= '.Configuration::get('PS_DB_macroCatIdHome').')
		AND cg.`id_group` '.(!$cookie->id_customer ?  '= 1' : 'IN (SELECT id_group FROM '._DB_PREFIX_.'customer_group WHERE id_customer = '.intval($cookie->id_customer).')').'
		ORDER BY `level_depth` ASC, cl.`name` ASC');
		Tools::setCache('blockCatNewTheme'.((!is_null($cookie->id_lang))?'_'.$cookie->id_lang:''),$result); //set cache

	if (!$result)
	$resultParents = array();
	$resultIds = array();

	foreach ($result as $row)
		$row['name'] = Category::hideCategoryPosition($row['name']);
		$resultParents[$row['id_parent']][] = $row;
		$resultIds[$row['id_category']] = $row;

	$blockCategTree = $this->getTree($resultParents, $resultIds, Configuration::get('BLOCK_CATEG_MAX_DEPTH'));
	$isDhtml = (Configuration::get('BLOCK_CATEG_DHTML') == 1 ? true : false);
	$smarty->assign('isDhtml', $isDhtml);

	$this->currentCategoryId = NULL;
	if (isset($_GET['id_category']))
		$cookie->last_visited_category = intval($_GET['id_category']);
		$this->currentCategoryId = intval($_GET['id_category']);
	if (isset($_GET['id_product']))
		if (!isset($cookie->last_visited_category) OR !Product::idIsOnCategoryId(intval($_GET['id_product']), array('0' => array('id_category' => $cookie->last_visited_category))))
			$product = new Product(intval($_GET['id_product']));
			if (isset($product) AND Validate::isLoadedObject($product))
				$cookie->last_visited_category = intval($product->id_category_default);
		$this->currentCategoryId = intval($cookie->last_visited_category);

	$htmlOutput = $this->htmlTree($blockCategTree);
	$smarty->assign('htmlOutput', $htmlOutput);
	return $this->display(__FILE__, 'blockcategoriesnew.tpl');

with the first call, the getCache, we are checking if there is cached content on disk, and if it’s true, the cached content will be returned inside the $result variable.
If there is no cache content, the prestashop’s original code will run and the saved to disk with setCache method! easy uh?
The only thing that is missing is the deleting of this cached content (needed to update cached content with updated database data). I found to way to do this.

  • crontab: put a script that directly delete cached file on disk every hour/day (as you like)
  • right after database changes: put a delCache call inside postProcess() method definition on administration class (the ones that extends AdminTab) eg.: /admin/tabs/AdminCategories.php (we will see that more in details on last caching tutorial)
  • manually: delete cache manually when you have updated the interested records (in this example, the categories tables)

See you on next post to learn how cache modules!

Leave a Reply

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