Cache Basic API Guide: Difference between revisions

From Joomla! Documentation

Robbiej (talk | contribs)
half of overview written
Robbiej (talk | contribs)
Cache classes and storage sections done
Line 50: Line 50:
</source>
</source>
Similarly if you have a multilingual site then you may want to incorporate the language tag (<tt>Factory::getLanguage()->getTag()</tt>) within the cache id.
Similarly if you have a multilingual site then you may want to incorporate the language tag (<tt>Factory::getLanguage()->getTag()</tt>) within the cache id.
'''Step 4'''
The Joomla code checks that caching is enabled and if so it attempts to find the file which contains the cache. If it finds it then it reads the data from the file and returns the (deserialized) data to the calling function.
'''Step 5''' Still within the case of caching being enabled, if the cached file can't be found then the Joomla code calls the callback function and captures the returned data. It then creates a cache file and stores the (serialized) data in it, and returns the data to the calling function.
'''Step 6''' If caching is not enabled then the code simply calls the callback function, captures the results and returns them to the calling function. It doesn't attempt to store the data in a cache file.
== Joomla Cache Classes and Methods ==
[[File:cache-classes.jpg|500px|right|Joomla Cache Classes]]
The Joomla cache classes are shown in the diagram. There are 3 fundamental classes (shown along the bottom):
# CacheController – this acts as a parent class for the specific type of cache controller class which interacts with your code, as determined by your second parameter (<tt>$handler</tt>) in your <tt>Factory::getCache()</tt> call.
# Cache – a central Joomla cache class
# CacheStorage – this acts as a parent class for the specific type of cache storage class which interacts with your operating system's caching mechanism. The cache storage type used is determined by the setting of the System Cache Handler parameter within the Joomla Global Configuration.
In this API guide we are focussing on Callback Cache and File storage, which means that we will end up with <tt>CallbackController</tt> and <tt>FileStorage</tt> class objects. Our code interacts with the methods of the <tt>CallbackController</tt> object, and the <tt>FileStorage</tt> object handles the interaction with the cache files in the system filestore.
'''Important''' If you look at the Joomla 3.x APIs for the classes which inherit from <tt>CacheController</tt> (eg https://api.joomla.org/cms-3/classes/Joomla.CMS.Cache.Controller.CallbackController.html) you will see that the methods <tt>get</tt> and <tt>store</tt> are marked as deprecated. However, this isn't actually the case. It is the <tt>get</tt> and <tt>store</tt> methods within the <tt>CacheController</tt> class which are deprecated, the intention being that they will be removed from the parent <tt>CacheController</tt> in Joomla v4 and these methods would be present only in the subclasses. However the PHP documenter sees the deprecated mark against the method in the parent class and automatically applies it (incorrectly) to the associated method in the subclass.
Also if you look at the php source code for the <tt>CallbackController</tt> class (currently in libraries/src/Cache/Controller/CallbackController.php) you will see that the signature of the <tt>get</tt> method in that class is different from that of the <tt>get</tt> method in the parent <tt>CacheController</tt> class, and again the php documenter outputs the method API incorrectly, based on the parent class rather than on the subclass.
These problems should disappear with the Joomla v4 APIs, when the <tt>get</tt> and <tt>store</tt> methods are removed from the parent <tt>CacheController</tt> class.
== File Cache Storage ==
The use of File as the cache storage mechanism means that Joomla will write files in the folder defined by the Global Configuration parameter (System tab) "Path to Cache Folder". If this is blank then the default folder is used (as defined by JPATH_CACHE in includes/defines.php), which is /cache under the document root for Joomla 3.x and /administrator/cache under the document root for Joomla v4.
Assuming you are using Conservative Caching then each component / module / plugin has its own folder under the generic cache folder. (The folder name is based on the <tt>$group</tt> parameter which you pass to <tt>Factory::getCache()</tt>).
Within each folder are the cached files which you can edit and view the cached serialized data. The filename of each file is based (partly) on the <tt>$id</tt> parameter in your <tt>$cache->get()</tt> call described above.

Revision as of 19:50, 23 March 2020

Introduction

This is one of a series of API guides, which aim to help you understand how to use the Joomla APIs through providing detailed explanations and sample code which you can easily install and run.

This API guide explains in basic terms how to use the Joomla Cache API, and focuses on the Callback type of CacheController and File type of CacheStorage. Other types are mentioned, but not described in detail.

At the end of the guide you can find the code for a simple Joomla module which you can use and adapt to experiment with the Cache APIs.

As a general rule, you should use cache on the Joomla site only, not on the administrator back-end, and the descriptions below relate to when you have the Global Configuration (System tab) parameter System Cache set to "On – Conservative caching" and the "System – Page Cache" plugin is disabled.

Overall Description

Joomla Cache Overview
Joomla Cache Overview

The diagram provides an overview of how Joomla cache works and the description below relates to the circled steps in the diagram. The code in green is your code: the code in yellow is Joomla code.

Let's imagine that in the main code of our extension we have to get some data and we separate out this code into a function getData(). Typically this function will involve a database query which may take a significant amount of time.

Step 1 relates to the case where we don't use cache – we simply call getData() and store the results returned.

Steps 2 to 5 relate to the case where we use cache.

Step 2: we call $cache = Factory::getCache() with the following parameters:

  • parameter 1 ($group) should be set to the name of our extension. This is so that an administrator can see which extensions are storing cache, and can clear cache for specific extensions. (Some core Joomla code passes "_system" as parameter 1). For cache stored in the file system this also relates to the subdirectory of the cache folder in which the cache files are stored.
  • parameter 2 ($handler) is the type of cache controller, which is this guide is "callback". Other types which Joomla supports are "output", "page" and "view".
  • parameter 3 ($storage) should really be left null, so that Joomla picks up the cache storage mechanism from Global Configuration.

What is returned into $cache is a pointer to an instance of a CacheController subclass, based on what we pass as parameter 2. When we pass "callback" we get returned an instance of CallbackController.

Step 3: we call $data = $cache->get() with 3 parameters:

  • parameter 1 ($callback) is the name of the callback function, which in our case is "getData". You can also pass an anonymous function by eg
$myFunc = function() {  };
$cache->get($myFunc, );
  • parameter 2 ($args) is an array of the arguments to pass to the callback function.
  • parameter 3 ($id) is an id to be associated with our cache. For file storage this will factor into the name of the file in which the cached data is stored, so if your extension caches data in several places you must use different ids for each.

Important If the data you're caching involves a database query whose results differ for different users then you should take that into account when generating this cache id. Otherwise users may see cached results which don't reflect what their privileges allow, causing possible confusion or security breaches.

If the query takes into account the Access field of a database record, then you can lump together the cache for users with the same Access rights by using:

$groups = implode(',', Factory::getUser()->getAuthorisedViewLevels());
$cacheId = $groups . "some text string";

Similarly if you have a multilingual site then you may want to incorporate the language tag (Factory::getLanguage()->getTag()) within the cache id.

Step 4 The Joomla code checks that caching is enabled and if so it attempts to find the file which contains the cache. If it finds it then it reads the data from the file and returns the (deserialized) data to the calling function.

Step 5 Still within the case of caching being enabled, if the cached file can't be found then the Joomla code calls the callback function and captures the returned data. It then creates a cache file and stores the (serialized) data in it, and returns the data to the calling function.

Step 6 If caching is not enabled then the code simply calls the callback function, captures the results and returns them to the calling function. It doesn't attempt to store the data in a cache file.

Joomla Cache Classes and Methods

Joomla Cache Classes
Joomla Cache Classes

The Joomla cache classes are shown in the diagram. There are 3 fundamental classes (shown along the bottom):

  1. CacheController – this acts as a parent class for the specific type of cache controller class which interacts with your code, as determined by your second parameter ($handler) in your Factory::getCache() call.
  2. Cache – a central Joomla cache class
  3. CacheStorage – this acts as a parent class for the specific type of cache storage class which interacts with your operating system's caching mechanism. The cache storage type used is determined by the setting of the System Cache Handler parameter within the Joomla Global Configuration.

In this API guide we are focussing on Callback Cache and File storage, which means that we will end up with CallbackController and FileStorage class objects. Our code interacts with the methods of the CallbackController object, and the FileStorage object handles the interaction with the cache files in the system filestore.

Important If you look at the Joomla 3.x APIs for the classes which inherit from CacheController (eg https://api.joomla.org/cms-3/classes/Joomla.CMS.Cache.Controller.CallbackController.html) you will see that the methods get and store are marked as deprecated. However, this isn't actually the case. It is the get and store methods within the CacheController class which are deprecated, the intention being that they will be removed from the parent CacheController in Joomla v4 and these methods would be present only in the subclasses. However the PHP documenter sees the deprecated mark against the method in the parent class and automatically applies it (incorrectly) to the associated method in the subclass.

Also if you look at the php source code for the CallbackController class (currently in libraries/src/Cache/Controller/CallbackController.php) you will see that the signature of the get method in that class is different from that of the get method in the parent CacheController class, and again the php documenter outputs the method API incorrectly, based on the parent class rather than on the subclass.

These problems should disappear with the Joomla v4 APIs, when the get and store methods are removed from the parent CacheController class.

File Cache Storage

The use of File as the cache storage mechanism means that Joomla will write files in the folder defined by the Global Configuration parameter (System tab) "Path to Cache Folder". If this is blank then the default folder is used (as defined by JPATH_CACHE in includes/defines.php), which is /cache under the document root for Joomla 3.x and /administrator/cache under the document root for Joomla v4.

Assuming you are using Conservative Caching then each component / module / plugin has its own folder under the generic cache folder. (The folder name is based on the $group parameter which you pass to Factory::getCache()).

Within each folder are the cached files which you can edit and view the cached serialized data. The filename of each file is based (partly) on the $id parameter in your $cache->get() call described above.