File "cache.php"
Full Path: /home/asmplong/www/ancien-site-2019/site/libraries/joomla/document/html/cache.php
File size: 15.36 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* @package Joomla.Platform
* @subpackage Cache
*
* @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
//Register the storage class with the loader
JLoader::register('JCacheStorage', dirname(__FILE__) . '/storage.php');
//Register the controller class with the loader
JLoader::register('JCacheController', dirname(__FILE__) . '/controller.php');
/**
* Joomla! Cache base object
*
* @package Joomla.Platform
* @subpackage Cache
* @since 11.1
*/
// Almost everything must be public here to allow overloading.
/**
* Class that handles cache routines.
*
* @package Joomla.Platform
* @subpackage Access
* @since 11.1
*/
class JCache extends JObject
{
/**
* Storage handler
*
* @var object
* @since 11.1
*/
public static $_handler = array();
/**
* Options
*
* @var Array
* @since 11.1
*/
public $_options;
/**
* Constructor
*
* @param array $options options
*
* @since 11.1
*/
public function __construct($options)
{
$conf = JFactory::getConfig();
$this->_options = array(
'cachebase' => $conf->get('cache_path', JPATH_CACHE),
'lifetime' => (int)$conf->get('cachetime'),
'language' => $conf->get('language', 'en-GB'),
'storage' => $conf->get('cache_handler', ''),
'defaultgroup' => 'default',
'locking' => true,
'locktime' => 15,
'checkTime' => true,
'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];
}
}
if (empty($this->_options['storage'])) {
$this->_options['caching'] = false;
}
}
/**
* 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
*
* @since 11.1
*/
public static function getInstance($type = 'output', $options = array())
{
return JCacheController::getInstance($type, $options);
}
/**
* Get the storage handlers
*
* @return array An array of available storage handlers
*
* @since 11.1
*/
public static function getStores()
{
jimport('joomla.filesystem.folder');
$handlers = JFolder::files(dirname(__FILE__) . '/storage', '.php');
$names = array();
foreach($handlers as $handler) {
$name = substr($handler, 0, strrpos($handler, '.'));
$class = 'JCacheStorage'.$name;
if (!class_exists($class)) {
require_once dirname(__FILE__) . '/storage/' . $name.'.php';
}
if (call_user_func_array(array(trim($class), 'test'), array())) {
$names[] = $name;
}
}
return $names;
}
/**
* Set caching enabled state
*
* @param boolean $enabled True to enable caching
*
* @return void
*
* @since 11.1
*/
public function setCaching($enabled)
{
$this->_options['caching'] = $enabled;
}
/**
* Get caching state
*
* @return boolean Caching state
*
* @since 11.1
*/
public function getCaching()
{
return $this->_options['caching'];
}
/**
* Set cache lifetime
*
* @param integer $lt Cache lifetime
*
* @return void
*
* @since 11.1
*/
public function setLifeTime($lt)
{
$this->_options['lifetime'] = $lt;
}
/**
* 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
*
* @since 11.1
*/
public function get($id, $group=null)
{
// Get the default group
$group = ($group) ? $group : $this->_options['defaultgroup'];
// Get the storage
$handler = $this->_getStorage();
if (!JError::isError($handler) && $this->_options['caching']) {
return $handler->get($id, $group, $this->_options['checkTime']);
}
return false;
}
/**
* Get a list of all cached data
*
* @return mixed Boolean false on failure or an object with a list of cache groups and data
*
* @since 11.1
*/
public function getAll()
{
// Get the storage
$handler = $this->_getStorage();
if (!JError::isError($handler) && $this->_options['caching']) {
return $handler->getAll();
}
return false;
}
/**
* Store the cached data by id and group
*
* @param string $id The cache data id
* @param string $group The cache data group
* @param mixed $data The data to store
*
* @return boolean True if cache stored
*
* @since 11.1
*/
public function store($data, $id, $group=null)
{
// Get the default group
$group = ($group) ? $group : $this->_options['defaultgroup'];
// Get the storage and store the cached data
$handler = $this->_getStorage();
if (!JError::isError($handler) && $this->_options['caching']) {
$handler->_lifetime = $this->_options['lifetime'];
return $handler->store($id, $group, $data);
}
return false;
}
/**
* 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
*
* @since 11.1
*/
public function remove($id, $group=null)
{
// Get the default group
$group = ($group) ? $group : $this->_options['defaultgroup'];
// Get the storage
$handler = $this->_getStorage();
if (!JError::isError($handler)) {
return $handler->remove($id, $group);
}
return false;
}
/**
* 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
*
* @since 11.1
*/
public function clean($group=null, $mode='group')
{
// Get the default group
$group = ($group) ? $group : $this->_options['defaultgroup'];
// Get the storage handler
$handler = $this->_getStorage();
if (!JError::isError($handler)) {
return $handler->clean($group, $mode);
}
return false;
}
/**
* Garbage collect expired cache data
*
* @return boolean True on success, false otherwise.
*
* @since 11.1
*/
public function gc()
{
// Get the storage handler
$handler = $this->_getStorage();
if (!JError::isError($handler)) {
return $handler->gc();
}
return false;
}
/**
* Set lock flag on cached item
*
* @param string $id The cache data id
* @param string $group The cache data group
* @param $locktime
*
* @return boolean True on success, false otherwise.
*
* @since 11.1
*/
public function lock($id,$group=null,$locktime=null)
{
$returning = new stdClass;
$returning->locklooped = false;
// Get the default group
$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
$handler = $this->_getStorage();
if (!JError::isError($handler) && $this->_options['locking'] == true && $this->_options['caching'] == true) {
$locked = $handler->lock($id, $group, $locktime);
if ($locked !== false) {
return $locked;
}
}
// fallback
$curentlifetime = $this->_options['lifetime'];
// set lifetime to locktime for storing in children
$this->_options['lifetime'] = $locktime;
$looptime = $locktime * 10;
$id2 = $id.'_lock';
if ($this->_options['locking'] == true && $this->_options['caching'] == true ) {
$data_lock = $this->get($id2, $group);
} else {
$data_lock = false;
$returning->locked = false;
}
if ( $data_lock !== false ) {
$lock_counter = 0;
// 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;
break;
}
usleep(100);
$data_lock = $this->get($id2, $group);
$lock_counter++;
}
}
if ($this->_options['locking'] == true && $this->_options['caching'] == true ) {
$returning->locked = $this->store(1, $id2, $group);
}
// revert lifetime to previous one
$this->_options['lifetime'] = $curentlifetime;
return $returning;
}
/**
* 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.
*
* @since 11.1
*/
public function unlock($id,$group=null)
{
$unlock = false;
// Get the default group
$group = ($group) ? $group : $this->_options['defaultgroup'];
//allow handlers to perform unlocking on their own
$handler = $this->_getStorage();
if (!JError::isError($handler) && $this->_options['caching']) {
$unlocked = $handler->unlock($id, $group);
if ($unlocked !== false) return $unlocked;
}
// fallback
if ($this->_options['caching']) {
$unlock = $this->remove($id.'_lock', $group);
}
return $unlock;
}
/**
* Get the cache storage handler
*
* @return JCacheStorage A JCacheStorage object
*
* @since 11.1
*/
public function &_getStorage()
{
if (!isset($this->_handler)) {
$this->_handler = JCacheStorage::getInstance($this->_options['storage'], $this->_options);
}
return $this->_handler;
}
/**
* Perform workarounds on retrieved cached data
*
* @param string Cached data
* @param array Array of options
*
* @return string Body of cached data
*
* @since 11.1
*/
public static function getWorkarounds($data, $options = array())
{
// Initialise variables.
$app = JFactory::getApplication();
$document = JFactory::getDocument();
$body = null;
// 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']);
} else if (isset($data['head'])){
$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['body'])) {
// The following code searches for a token in the cached page and replaces it with the
// proper token.
$token = JUtility::getToken();
$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']);
$body = $data['body'];
}
// Get the document body out of the cache.
return $body;
}
/**
* Create workarounded data to be cached
*
* @param string $data Cached data
* @param array $options Array of options
*
* @return string Data to be cached
*
* @since 11.1
*/
public static function setWorkarounds($data,$options=array())
{
$loptions=array();
$loptions['nopathway'] = 0;
$loptions['nohead'] = 0;
$loptions['nomodules'] = 0;
$loptions['modulemode'] = 0;
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'];
}
// Initialise variables.
$app = JFactory::getApplication();
$document = JFactory::getDocument();
// 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();
}
// View body data
$cached['body'] = $data;
// Document head data
if ($loptions['nohead'] != 1) {
$cached['head'] = $document->getHeadData();
if ($loptions['modulemode'] == 1) {
unset($cached['head']['title']);
unset($cached['head']['description']);
unset($cached['head']['link']);
unset($cached['head']['links']);
unset($cached['head']['metaTags']);
}
}
// Pathway data
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.
$cached['module'] = array_diff_assoc($buffer2['module'], $buffer1['module']);
}
return $cached;
}
/**
* Create safe id for cached data from url parameters set by plugins and framework
*
* @return string md5 encoded cacheid
*
* @since 11.1
*/
public static function makeId()
{
$app = JFactory::getApplication();
// Get url parameters set by plugins
$registeredurlparams = $app->get('registeredurlparams');
if (empty($registeredurlparams)) {
/*
$registeredurlparams = new stdClass;
$registeredurlparams->Itemid = 'INT';
$registeredurlparams->catid = 'INT';
$registeredurlparams->id = 'INT';
*/
return md5(serialize(JRequest::getURI())); // provided for backwards compatibility - THIS IS NOT SAFE!!!!
}
// Framework defaults
$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 = JRequest::getVar($key, null, 'default', $value);
}
return md5(serialize($safeuriaddon));
}
/**
* Add a directory where JCache should search for handlers. You may
* either pass a string or an array of directories.
*
* @param string A path to search.
*
* @return array An array with directory elements
*
* @since 11.1
*/
public static function addIncludePath($path='')
{
static $paths;
if (!isset($paths)) {
$paths = array();
}
if (!empty($path) && !in_array($path, $paths)) {
jimport('joomla.filesystem.path');
array_unshift($paths, JPath::clean($path));
}
return $paths;
}
}