1

So background: I'm making a caching plugin that clears our site and CDN caches when content is saved in the administrator backend. In this instance, I want to clear the site cache for one group.

My original attempt looked something like this:

$cache = JFactory::getCache('cachegroup');
$cache->clear();

That didn't work. I did some research and saw SharkyKZ in the Joomla forums recommend this structure:

$cache = JCache::getInstance('callback');
$cache->clean('cachegroup');

That also didn't work for me. I suspected it had something to do with the fact that caching is disabled on our site, so I tried adding $cache->setCaching(1); to both sets of code and that didn't work either.

Finally I dug into the Joomla code and looked at how their cache component handles it; and ended up with this working code:

$conf = JFactory::getConfig();

$options = array(
    'defaultgroup' => '',
    'storage'      => $conf->get('cache_handler', ''),
    'caching'      => true,
    'cachebase'    => $conf->get('cache_path', JPATH_SITE . '/cache')
);

$cache = JCache::getInstance('', $options);
$cache->clean('cachegroup');

So I have working code, but I would...

  1. Like to understand why it works, and
  2. Like to know if there is a simpler or superior way to accomplish this.

Update

This problem doesn't seem to be reproducible within a site template, but I still have the problem within a plugin. So I'm going to give an expanded example of the code structure to help spot problems.

<?php

// No direct access.
defined('_JEXEC') or die;

class plgContentFncaching extends JPlugin
{
    function onContentAfterSave($context, $article, $isNew) {
        // Banner items
        if($context == "com_banners.banner") {
            // Does not work
            plgContentFNCaching::problemClearBannerCache();

            // Works
            plgContentFNCaching::workingClearBannerCache();
        }
    }

    function problemClearBannerCache() {
        $cache = JFactory::getCache('pinnedbanners');
        $cache->setCaching(1);
        $cache->clean();
    }

    function workingClearBannerCache() {
        $conf = JFactory::getConfig();

        $options = array(
            'defaultgroup' => '',
            'storage'      => $conf->get('cache_handler', ''),
            'caching'      => true,
            'cachebase'    => $conf->get('cache_path', JPATH_SITE . '/cache')
        );

        $cache = JCache::getInstance('', $options);
        $cache->clean('pinnedbanners');
    }
}
| improve this question | | | | |
  • I do not really understand what you would like to clean from the cache when the caching is disabled basically? Your last code sample In your question however shows that the caching is set to true. Your question is ambiguous this way. – Zollie May 22 at 9:55
  • So it looks like that your last code sample works because in the options caching gets enabled. Thus clean() method returns true. – Zollie May 22 at 9:59
  • I also do not see however why the other codes do not work at setCaching(1). – Zollie May 22 at 10:38
  • The reason is that I want to prevent Joomla and third party apps from caching. Then when I want to cache something, I just set caching to 1 for the group. This has worked pretty well until I wanted to clear the cache! – Obscerno May 22 at 11:30
  • 1
    :) we cleared that from every angle. – Zollie 2 days ago
1

I had some time to check this problem but I was not able to duplicate your issue. I created a short sample caching test in one of my layout files like:

    $myCache = \JFactory::getCache('my_cache');
    $myCache->setCaching(1);

    $dataToCache = "<h2>this works now</h2>";
    $myCache->store($data = $dataToCache, $id = 'yep1', $group = 'my_cache'); // you will find the cached data in the 'cache/my_cache' subfolder - if you do not run the clean() method.

    $myCache->clean('my_cache', 'group'); // this deletes the whole 'my_cache' subfolder from the cache directory

On my Joomla test site caching is turned off in Global configuration and system page caching is also turned off. But after the line setCaching(1); using the store() method the cache subfolder was created and then using the clean() method the subfolder was deleted.

After testing the above more it became obvious that clean() method deletes the particular cache folder even if it is not passed as the method's attribute explicitly.

UPDATE REGARDING PLUGIN EVENTS AND BASE CACHE DIRECTORY - USING THE ABOVE IN PLUGINS

After some more testing - and as @Obscerno stated - in some plugins the default cache directory is going to be on administrator path. It became obvious that depending on the triggered plugin events, the cache object is using different cachebase directory. If the plugin event is triggered from the back-end then the default cache directory is going to be on .../administrator/cache path on default administrator root, and if the plugin event is triggered from front-end then the normal default cache directory will be used. So, it depends on which plugin event you are running your cache handling methods.

Thus you can and you should define 'cachebase' after you called the Cache object:

    $myCache = \JFactory::getCache('my_cache_plugin');
    $myCache->options['cachebase'] = JPATH_SITE . '\cache';
    $myCache->setCaching(1);

    // var_dump($myCache); die; // debug/check

    $dataToCache = "<h2>From the content plugin on aftersave event this works now</h2>";

    $myCache->store($data = $dataToCache, $id = 'yep1', $group = 'my_cache_plugin'); // you will find the cached data in the 'cache/my_cache_plugin' subfolder

    $myCache->clean('my_cache_plugin', 'group'); // $myCache->clean(); also deletes this cache folder.
| improve this answer | | | | |
  • Thanks for looking into this @Zollie! I just tried this in a template and got the same result as you, the cache cleaning worked. I tried storing data in one page load and using clean() on it in the other, and it still worked. I tried cleaning the group I was having problems with initially, and it worked. I'm going to try again in the plugin code to make sure I didn't misspell it multiple times or something, and get back to you. – Obscerno May 23 at 16:57
  • I do still have the problem in the plugin, but not in the template, so maybe having the cache disabled was just a red herring and it has something to do with being run from within the plugin. I'll expand my example code to include more of the code structure. – Obscerno May 23 at 17:07
1

The problem has nothing to do with the cache being disabled. It is that the plugin is using a different cachebase setting than the cache that saved the data.

The cache that saved the data used the site cache folder located at /cache, while the plugin is using the cache folder located at /administrator/cache. It doesn't see the data because it's looking in the wrong place.

The reason the working code given in the question works is because it explicitly sets the cachebase to the site cache:

$options = array(
    'defaultgroup' => '',
    'storage'      => $conf->get('cache_handler', ''),
    'caching'      => true,
    'cachebase'    => $conf->get('cache_path', JPATH_SITE . '/cache') // <- Here.
);

As far as compacting the code goes, you can get away with this:

$options = array('caching' => true, 'cachebase' => JPATH_SITE . '/cache');
$cache = JCache::getInstance('',$options);
$cache->clean('cachegroup');
| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.