Florian Lemaitre
Florian Lemaitre

Reputation: 5748

How to handle cache expiration in Prestashop

We can set a cache for a block of code inside our module's hooks in Prestashop but we can't set a life time for this cache.

Here is a hook using the cache functionality:

protected function _prepareHook()
{
    if (!$this->isCached('homeslider.tpl', $this->getCacheId()))
    {
        $slides = $this->getSlides(true);
        if (is_array($slides))
            foreach ($slides as &$slide)
            {
                $slide['sizes'] = @getimagesize((dirname(__FILE__).DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$slide['image']));
                if (isset($slide['sizes'][3]) && $slide['sizes'][3])
                    $slide['size'] = $slide['sizes'][3];
            }

        if (!$slides)
            return false;

        $this->smarty->assign(array('homeslider_slides' => $slides));
    }

    return true;
}

Is there a way to force this cache to expire every hours?

Upvotes: 0

Views: 1516

Answers (1)

Florian Lemaitre
Florian Lemaitre

Reputation: 5748

Smarty can handle cache life time but Prestashop doesn't propose a way to use it.

We will have to override Module.php and Tools.php classes to add this functionality:

Tools.php:

<?php

class Tools extends ToolsCore
{
    public static function enableCache($level = 1, Context $context = null, $lifetime = null)
    {
        if (!$context) {
            $context = Context::getContext();
        }
        $smarty = $context->smarty;
        if (!Configuration::get('PS_SMARTY_CACHE')) {
            return;
        }
        if ($smarty->force_compile == 0 && $smarty->caching == $level) {
            return;
        }
        self::$_forceCompile = (int)$smarty->force_compile;
        self::$_caching = (int)$smarty->caching;
        $smarty->force_compile = 0;
        $smarty->caching = (int)$level;
        // If there is a lifetime provided then set the cache_lifetime to this value
        $smarty->cache_lifetime = is_null($lifetime) ? 31536000 : (int) $lifetime; // 1 Year
    }
}

By default, Prestashop set the cache life time to 1 Year. Here we have added a third parameter allowing us to define our own life time.

Module.php:

<?php

class Module extends ModuleCore {
    /**
     * @param string $template
     * @param null|string $cache_id
     * @param null|string $compile_id
     * @param int|null $lifetime cache life time
     * @return bool
     */
    public function isCached($template, $cache_id = null, $compile_id = null, $lifetime = null)
    {
        if (Tools::getIsset('live_edit') || Tools::getIsset('live_configurator_token')) {
            return false;
        }
        Tools::enableCache(1, null, $lifetime);
        $new_tpl = $this->getTemplatePath($template);
        $is_cached = $this->getCurrentSubTemplate($template, $cache_id, $compile_id)->isCached($new_tpl, $cache_id, $compile_id);
        Tools::restoreCacheSettings();
        return $is_cached;
    }
}

Here we add a new parameter to isCached() method that will be used in enableCache method altered in the Tools.php class above.

We need to delete the file cache/class_index.php so that Prestashop loads our newly created overrides.

We can now use this new parameter in our hook:

protected function _prepareHook()
{
    if (!$this->isCached('homeslider.tpl', $this->getCacheId(), null, 3600))
    {
        $slides = $this->getSlides(true);
        if (is_array($slides))
            foreach ($slides as &$slide)
            {
                $slide['sizes'] = @getimagesize((dirname(__FILE__).DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$slide['image']));
                if (isset($slide['sizes'][3]) && $slide['sizes'][3])
                    $slide['size'] = $slide['sizes'][3];
            }

        if (!$slides)
            return false;

        $this->smarty->assign(array('homeslider_slides' => $slides));
    }

    return true;
}

Upvotes: 1

Related Questions