Source for file cache.php
Documentation is available at cache.php
* @package Joomla.Platform
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
* Joomla! Cache base object
* @package Joomla.Platform
* @var object Storage handler
public static $_handler =
array();
* @param array $options options
'lifetime' => (int)
$conf->get('cachetime'),
'language' =>
$conf->get('language', 'en-GB'),
'storage' =>
$conf->get('cache_handler', ''),
'defaultgroup' =>
'default',
'caching' =>
($conf->get('caching') >=
1) ?
true :
false);
// Overwrite default options with given options
foreach ($options as $option =>
$value)
if (isset
($options[$option]) &&
$options[$option] !==
'')
$this->_options[$option] =
$options[$option];
* Returns a reference to a cache adapter object, always creating it
* @param string $type The cache object type to instantiate
* @param array $options The array of options
* @return JCache A JCache object
public static function getInstance($type =
'output', $options =
array())
* Get the storage handlers
* @return array An array of available storage handlers
// Get an iterator and loop trough the driver classes.
$iterator =
new DirectoryIterator(__DIR__ .
'/storage');
foreach ($iterator as $file)
$fileName =
$file->getFilename();
// Only load for php files.
// Note: DirectoryIterator::getExtension only available PHP >= 5.3.6
||
$fileName ==
'helper.php')
// Derive the class name from the type.
// If the class doesn't exist we have nothing left to do but look at the next type. We did our best.
// Sweet! Our class exists, so now we just need to know if it passes its test method.
if ($class::isSupported())
// Connector names should not have file extensions.
* Set caching enabled state
* @param boolean $enabled True to enable caching
* @return boolean Caching state
* @param integer $lt Cache lifetime
* Get cached data by id and group
* @param string $id The cache data id
* @param string $group The cache data group
* @return mixed boolean False on failure or a cached data string
public function get($id, $group =
null)
$group =
($group) ?
$group :
$this->_options['defaultgroup'];
if (!($handler instanceof
Exception) &&
$this->_options['caching'])
return $handler->get($id, $group, $this->_options['checkTime']);
* Get a list of all cached data
* @return mixed Boolean false on failure or an object with a list of cache groups and data
if (!($handler instanceof
Exception) &&
$this->_options['caching'])
return $handler->getAll();
* Store the cached data by id and group
* @param mixed $data The data to store
* @param string $id The cache data id
* @param string $group The cache data group
* @return boolean True if cache stored
public function store($data, $id, $group =
null)
$group =
($group) ?
$group :
$this->_options['defaultgroup'];
// Get the storage and store the cached data
if (!($handler instanceof
Exception) &&
$this->_options['caching'])
$handler->_lifetime =
$this->_options['lifetime'];
return $handler->store($id, $group, $data);
* Remove a cached data entry by id and group
* @param string $id The cache data id
* @param string $group The cache data group
* @return boolean True on success, false otherwise
public function remove($id, $group =
null)
$group =
($group) ?
$group :
$this->_options['defaultgroup'];
if (!($handler instanceof
Exception))
return $handler->remove($id, $group);
* Clean cache for a group given a mode.
* group mode : cleans all cache in the group
* notgroup mode : cleans all cache not in the group
* @param string $group The cache data group
* @param string $mode The mode for cleaning cache [group|notgroup]
* @return boolean True on success, false otherwise
public function clean($group =
null, $mode =
'group')
$group =
($group) ?
$group :
$this->_options['defaultgroup'];
// Get the storage handler
if (!($handler instanceof
Exception))
return $handler->clean($group, $mode);
* Garbage collect expired cache data
* @return boolean True on success, false otherwise.
// Get the storage handler
if (!($handler instanceof
Exception))
* Set lock flag on cached item
* @param string $id The cache data id
* @param string $group The cache data group
* @param string $locktime The default locktime for locking the cache.
* @return object Properties are lock and locklooped
public function lock($id, $group =
null, $locktime =
null)
$returning =
new stdClass;
$returning->locklooped =
false;
$group =
($group) ?
$group :
$this->_options['defaultgroup'];
// Get the default locktime
$locktime =
($locktime) ?
$locktime :
$this->_options['locktime'];
// Allow storage handlers to perform locking on their own
// NOTE drivers with lock need also unlock or unlocking will fail because of false $id
if (!($handler instanceof
Exception) &&
$this->_options['locking'] ==
true &&
$this->_options['caching'] ==
true)
$locked =
$handler->lock($id, $group, $locktime);
$curentlifetime =
$this->_options['lifetime'];
// Set lifetime to locktime for storing in children
$this->_options['lifetime'] =
$locktime;
$looptime =
$locktime *
10;
$data_lock =
$this->get($id2, $group);
$returning->locked =
false;
if ($data_lock !==
false)
// Loop until you find that the lock has been released.
// That implies that data get from other thread has finished
while ($data_lock !==
false)
if ($lock_counter >
$looptime)
$returning->locked =
false;
$returning->locklooped =
true;
$data_lock =
$this->get($id2, $group);
$returning->locked =
$this->store(1, $id2, $group);
// Revert lifetime to previous one
$this->_options['lifetime'] =
$curentlifetime;
* Unset lock flag on cached item
* @param string $id The cache data id
* @param string $group The cache data group
* @return boolean True on success, false otherwise.
public function unlock($id, $group =
null)
$group =
($group) ?
$group :
$this->_options['defaultgroup'];
// Allow handlers to perform unlocking on their own
if (!($handler instanceof
Exception) &&
$this->_options['caching'])
$unlocked =
$handler->unlock($id, $group);
$unlock =
$this->remove($id .
'_lock', $group);
* Get the cache storage handler
* @return JCacheStorage A JCacheStorage object
if (isset
(self::$_handler[$hash]))
return self::$_handler[$hash];
self::$_handler[$hash] =
JCacheStorage::getInstance($this->_options['storage'], $this->_options);
return self::$_handler[$hash];
* Perform workarounds on retrieved cached data
* @param string $data Cached data
* @param array $options Array of options
* @return string Body of cached data
$app =
JFactory::getApplication();
// Get the document head out of the cache.
if (isset
($options['mergehead']) &&
$options['mergehead'] ==
1 && isset
($data['head']) &&
!empty($data['head']))
$document->mergeHeadData($data['head']);
elseif (isset
($data['head']) &&
method_exists($document, 'setHeadData'))
$document->setHeadData($data['head']);
// If the pathway buffer is set in the cache data, get it.
if (isset
($data['pathway']) &&
is_array($data['pathway']))
// Push the pathway data into the pathway object.
$pathway =
$app->getPathWay();
$pathway->setPathway($data['pathway']);
// @todo check if the following is needed, seems like it should be in page cache
// If a module buffer is set in the cache data, get it.
if (isset
($data['module']) &&
is_array($data['module']))
// Iterate through the module positions and push them into the document buffer.
foreach ($data['module'] as $name =>
$contents)
$document->setBuffer($contents, 'module', $name);
if (isset
($data['headers']) &&
$data['headers'])
foreach($data['headers'] as $header)
$app->setHeader($header['name'], $header['value']);
// The following code searches for a token in the cached page and replaces it with the
if (isset
($data['body']))
$search =
'#<input type="hidden" name="[0-9a-f]{32}" value="1" />#';
$replacement =
'<input type="hidden" name="' .
$token .
'" value="1" />';
$data['body'] =
preg_replace($search, $replacement, $data['body']);
// Get the document body out of the cache.
* Create workarounded data to be cached
* @param string $data Cached data
* @param array $options Array of options
* @return string Data to be cached
if (isset
($options['nopathway']))
$loptions['nopathway'] =
$options['nopathway'];
if (isset
($options['nohead']))
$loptions['nohead'] =
$options['nohead'];
if (isset
($options['nomodules']))
$loptions['nomodules'] =
$options['nomodules'];
if (isset
($options['modulemode']))
$loptions['modulemode'] =
$options['modulemode'];
if ($loptions['nomodules'] !=
1)
// Get the modules buffer before component execution.
$buffer1 =
$document->getBuffer();
// Make sure the module buffer is an array.
if (!isset
($buffer1['module']) ||
!is_array($buffer1['module']))
$buffer1['module'] =
array();
if ($loptions['nohead'] !=
1 &&
method_exists($document, 'getHeadData'))
if ($loptions['modulemode'] ==
1)
$headnow =
$document->getHeadData();
$unset =
array('title', 'description', 'link', 'links', 'metaTags');
unset
($options['headerbefore'][$un]);
$cached['head'] =
array();
// Only store what this module has added
foreach ($headnow as $now =>
$value)
if (isset
($options['headerbefore'][$now]))
// We have to serialize the content of the arrays because the may contain other arrays which is a notice in PHP 5.4 and newer
$nowvalue =
array_map('serialize', $headnow[$now]);
$beforevalue =
array_map('serialize', $options['headerbefore'][$now]);
$newvalue =
array_map('unserialize', $newvalue);
$newvalue =
$headnow[$now];
$cached['head'][$now] =
$newvalue;
$cached['head'] =
$document->getHeadData();
if ($app->isSite() &&
$loptions['nopathway'] !=
1)
$pathway =
$app->getPathWay();
$cached['pathway'] = isset
($data['pathway']) ?
$data['pathway'] :
$pathway->getPathway();
if ($loptions['nomodules'] !=
1)
// @todo Check if the following is needed, seems like it should be in page cache
// Get the module buffer after component execution.
$buffer2 =
$document->getBuffer();
// Make sure the module buffer is an array.
if (!isset
($buffer2['module']) ||
!is_array($buffer2['module']))
$buffer2['module'] =
array();
// Compare the second module buffer against the first buffer.
if (isset
($options['headers']) &&
$options['headers'])
$cached['headers'] =
$app->getHeaders();
* Create safe id for cached data from url parameters set by plugins and framework
* @return string md5 encoded cacheid
public static function makeId()
// Get url parameters set by plugins
if (!empty($app->registeredurlparams))
$registeredurlparams =
$app->registeredurlparams;
$registeredurlparams->format =
'WORD';
$registeredurlparams->option =
'WORD';
$registeredurlparams->view =
'WORD';
$registeredurlparams->layout =
'WORD';
$registeredurlparams->tpl =
'CMD';
$registeredurlparams->id =
'INT';
$safeuriaddon =
new stdClass;
foreach ($registeredurlparams as $key =>
$value)
$safeuriaddon->$key =
$app->input->get($key, null, $value);
* Add a directory where JCache should search for handlers. You may
* either pass a string or an array of directories.
* @param string $path A path to search.
* @return array An array with directory elements
if (!empty($path) &&
!in_array($path, $paths))
Documentation generated on Tue, 19 Nov 2013 14:54:52 +0100 by phpDocumentor 1.4.3