Merge pull request #2689 from splitbrain/refactorCachePSR2
Refactor cache.php to better conform with PSR 2
This commit is contained in:
commit
d8b492882d
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use dokuwiki\Cache\CacheRenderer;
|
||||
|
||||
class cache_stalecheck_test extends DokuWikiTest {
|
||||
function test_staleness() {
|
||||
global $ID;
|
||||
|
@ -11,7 +13,7 @@ class cache_stalecheck_test extends DokuWikiTest {
|
|||
saveWikiText($ID, 'Fresh', 'Created');
|
||||
|
||||
# Create stale cache
|
||||
$cache = new cache_renderer($ID, $file, 'xhtml');
|
||||
$cache = new CacheRenderer($ID, $file, 'xhtml');
|
||||
$cache->storeCache('Stale');
|
||||
$stale = $cache->retrieveCache();
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use dokuwiki\Cache\CacheRenderer;
|
||||
|
||||
/**
|
||||
* Class cache_use_test
|
||||
*
|
||||
|
@ -8,7 +10,7 @@
|
|||
* @todo tests marked as flaky until Ticket #694 has been fixed
|
||||
*/
|
||||
class cache_use_test extends DokuWikiTest {
|
||||
/** @var cache_renderer $cache */
|
||||
/** @var CacheRenderer $cache */
|
||||
private $cache;
|
||||
|
||||
function setUp() {
|
||||
|
@ -21,7 +23,7 @@ class cache_use_test extends DokuWikiTest {
|
|||
|
||||
saveWikiText($ID, 'Content', 'Created');
|
||||
|
||||
$this->cache = new cache_renderer($ID, $file, 'xhtml');
|
||||
$this->cache = new CacheRenderer($ID, $file, 'xhtml');
|
||||
$this->cache->storeCache('Test');
|
||||
|
||||
// set the modification times explicitly (overcome Issue #694)
|
||||
|
@ -76,6 +78,6 @@ class cache_use_test extends DokuWikiTest {
|
|||
$conf['cachetime'] = -1; // disables renderer caching
|
||||
|
||||
$this->assertFalse($this->cache->useCache());
|
||||
$this->assertNotEmpty($this->cache->_nocache);
|
||||
$this->assertNotEmpty($this->cache->isNoCache());
|
||||
}
|
||||
}
|
||||
|
|
5
feed.php
5
feed.php
|
@ -9,6 +9,7 @@
|
|||
* @global Input $INPUT
|
||||
*/
|
||||
|
||||
use dokuwiki\Cache\Cache;
|
||||
use dokuwiki\ChangeLog\MediaChangeLog;
|
||||
use dokuwiki\ChangeLog\PageChangeLog;
|
||||
|
||||
|
@ -31,7 +32,7 @@ $opt = rss_parseOptions();
|
|||
// the feed is dynamic - we need a cache for each combo
|
||||
// (but most people just use the default feed so it's still effective)
|
||||
$key = join('', array_values($opt)).'$'.$_SERVER['REMOTE_USER'].'$'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'];
|
||||
$cache = new cache($key, '.feed');
|
||||
$cache = new Cache($key, '.feed');
|
||||
|
||||
// prepare cache depends
|
||||
$depends['files'] = getConfigFiles('main');
|
||||
|
@ -45,7 +46,7 @@ header('Pragma: public');
|
|||
header('Content-Type: application/xml; charset=utf-8');
|
||||
header('X-Robots-Tag: noindex');
|
||||
if($cache->useCache($depends)) {
|
||||
http_conditionalRequest($cache->_time);
|
||||
http_conditionalRequest($cache->getTime());
|
||||
if($conf['allowdebug']) header("X-CacheUsed: $cache->cache");
|
||||
print $cache->retrieveCache();
|
||||
exit;
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
<?php
|
||||
|
||||
namespace dokuwiki\Cache;
|
||||
|
||||
use \dokuwiki\Debug\PropertyDeprecationHelper;
|
||||
|
||||
/**
|
||||
* Generic handling of caching
|
||||
*/
|
||||
class Cache
|
||||
{
|
||||
use PropertyDeprecationHelper;
|
||||
|
||||
public $key = ''; // primary identifier for this item
|
||||
public $ext = ''; // file ext for cache data, secondary identifier for this item
|
||||
public $cache = ''; // cache file name
|
||||
public $depends = array(); // array containing cache dependency information,
|
||||
// used by makeDefaultCacheDecision to determine cache validity
|
||||
|
||||
// phpcs:disable
|
||||
/**
|
||||
* @deprecated since 2019-02-02 use the respective getters instead!
|
||||
*/
|
||||
protected $_event = ''; // event to be triggered during useCache
|
||||
protected $_time;
|
||||
protected $_nocache = false; // if set to true, cache will not be used or stored
|
||||
// phpcs:enable
|
||||
|
||||
/**
|
||||
* @param string $key primary identifier
|
||||
* @param string $ext file extension
|
||||
*/
|
||||
public function __construct($key, $ext)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->ext = $ext;
|
||||
$this->cache = getCacheName($key, $ext);
|
||||
|
||||
/**
|
||||
* @deprecated since 2019-02-02 use the respective getters instead!
|
||||
*/
|
||||
$this->deprecatePublicProperty('_event');
|
||||
$this->deprecatePublicProperty('_time');
|
||||
$this->deprecatePublicProperty('_nocache');
|
||||
}
|
||||
|
||||
public function getTime()
|
||||
{
|
||||
return $this->_time;
|
||||
}
|
||||
|
||||
public function getEvent()
|
||||
{
|
||||
return $this->_event;
|
||||
}
|
||||
|
||||
public function setEvent($_event)
|
||||
{
|
||||
$this->_event = $_event;
|
||||
}
|
||||
|
||||
/**
|
||||
* public method to determine whether the cache can be used
|
||||
*
|
||||
* to assist in centralisation of event triggering and calculation of cache statistics,
|
||||
* don't override this function override makeDefaultCacheDecision()
|
||||
*
|
||||
* @param array $depends array of cache dependencies, support dependecies:
|
||||
* 'age' => max age of the cache in seconds
|
||||
* 'files' => cache must be younger than mtime of each file
|
||||
* (nb. dependency passes if file doesn't exist)
|
||||
*
|
||||
* @return bool true if cache can be used, false otherwise
|
||||
*/
|
||||
public function useCache($depends = array())
|
||||
{
|
||||
$this->depends = $depends;
|
||||
$this->addDependencies();
|
||||
|
||||
if ($this->_event) {
|
||||
return $this->stats(trigger_event($this->_event, $this, array($this, 'makeDefaultCacheDecision')));
|
||||
} else {
|
||||
return $this->stats($this->makeDefaultCacheDecision());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* internal method containing cache use decision logic
|
||||
*
|
||||
* this function processes the following keys in the depends array
|
||||
* purge - force a purge on any non empty value
|
||||
* age - expire cache if older than age (seconds)
|
||||
* files - expire cache if any file in this array was updated more recently than the cache
|
||||
*
|
||||
* Note that this function needs to be public as it is used as callback for the event handler
|
||||
*
|
||||
* can be overridden
|
||||
*
|
||||
* @internal This method may only be called by the event handler! Call \dokuwiki\Cache\Cache::useCache instead!
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
public function makeDefaultCacheDecision()
|
||||
{
|
||||
|
||||
if ($this->_nocache) {
|
||||
return false;
|
||||
} // caching turned off
|
||||
if (!empty($this->depends['purge'])) {
|
||||
return false;
|
||||
} // purge requested?
|
||||
if (!($this->_time = @filemtime($this->cache))) {
|
||||
return false;
|
||||
} // cache exists?
|
||||
|
||||
// cache too old?
|
||||
if (!empty($this->depends['age']) && ((time() - $this->_time) > $this->depends['age'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($this->depends['files'])) {
|
||||
foreach ($this->depends['files'] as $file) {
|
||||
if ($this->_time <= @filemtime($file)) {
|
||||
return false;
|
||||
} // cache older than files it depends on?
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* add dependencies to the depends array
|
||||
*
|
||||
* this method should only add dependencies,
|
||||
* it should not remove any existing dependencies and
|
||||
* it should only overwrite a dependency when the new value is more stringent than the old
|
||||
*/
|
||||
protected function addDependencies()
|
||||
{
|
||||
global $INPUT;
|
||||
if ($INPUT->has('purge')) {
|
||||
$this->depends['purge'] = true;
|
||||
} // purge requested
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the cached data
|
||||
*
|
||||
* @param bool $clean true to clean line endings, false to leave line endings alone
|
||||
* @return string cache contents
|
||||
*/
|
||||
public function retrieveCache($clean = true)
|
||||
{
|
||||
return io_readFile($this->cache, $clean);
|
||||
}
|
||||
|
||||
/**
|
||||
* cache $data
|
||||
*
|
||||
* @param string $data the data to be cached
|
||||
* @return bool true on success, false otherwise
|
||||
*/
|
||||
public function storeCache($data)
|
||||
{
|
||||
if ($this->_nocache) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return io_savefile($this->cache, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove any cached data associated with this cache instance
|
||||
*/
|
||||
public function removeCache()
|
||||
{
|
||||
@unlink($this->cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record cache hits statistics.
|
||||
* (Only when debugging allowed, to reduce overhead.)
|
||||
*
|
||||
* @param bool $success result of this cache use attempt
|
||||
* @return bool pass-thru $success value
|
||||
*/
|
||||
protected function stats($success)
|
||||
{
|
||||
global $conf;
|
||||
static $stats = null;
|
||||
static $file;
|
||||
|
||||
if (!$conf['allowdebug']) {
|
||||
return $success;
|
||||
}
|
||||
|
||||
if (is_null($stats)) {
|
||||
$file = $conf['cachedir'] . '/cache_stats.txt';
|
||||
$lines = explode("\n", io_readFile($file));
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$i = strpos($line, ',');
|
||||
$stats[substr($line, 0, $i)] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($stats[$this->ext])) {
|
||||
list($ext, $count, $hits) = explode(',', $stats[$this->ext]);
|
||||
} else {
|
||||
$ext = $this->ext;
|
||||
$count = 0;
|
||||
$hits = 0;
|
||||
}
|
||||
|
||||
$count++;
|
||||
if ($success) {
|
||||
$hits++;
|
||||
}
|
||||
$stats[$this->ext] = "$ext,$count,$hits";
|
||||
|
||||
io_saveFile($file, join("\n", $stats));
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isNoCache()
|
||||
{
|
||||
return $this->_nocache;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace dokuwiki\Cache;
|
||||
|
||||
/**
|
||||
* Caching of parser instructions
|
||||
*/
|
||||
class CacheInstructions extends \dokuwiki\Cache\CacheParser
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $id page id
|
||||
* @param string $file source file for cache
|
||||
*/
|
||||
public function __construct($id, $file)
|
||||
{
|
||||
parent::__construct($id, $file, 'i');
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the cached data
|
||||
*
|
||||
* @param bool $clean true to clean line endings, false to leave line endings alone
|
||||
* @return array cache contents
|
||||
*/
|
||||
public function retrieveCache($clean = true)
|
||||
{
|
||||
$contents = io_readFile($this->cache, false);
|
||||
return !empty($contents) ? unserialize($contents) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* cache $instructions
|
||||
*
|
||||
* @param array $instructions the instruction to be cached
|
||||
* @return bool true on success, false otherwise
|
||||
*/
|
||||
public function storeCache($instructions)
|
||||
{
|
||||
if ($this->_nocache) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return io_savefile($this->cache, serialize($instructions));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace dokuwiki\Cache;
|
||||
|
||||
/**
|
||||
* Parser caching
|
||||
*/
|
||||
class CacheParser extends Cache
|
||||
{
|
||||
|
||||
public $file = ''; // source file for cache
|
||||
public $mode = ''; // input mode (represents the processing the input file will undergo)
|
||||
public $page = '';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $id page id
|
||||
* @param string $file source file for cache
|
||||
* @param string $mode input mode
|
||||
*/
|
||||
public function __construct($id, $file, $mode)
|
||||
{
|
||||
if ($id) {
|
||||
$this->page = $id;
|
||||
}
|
||||
$this->file = $file;
|
||||
$this->mode = $mode;
|
||||
|
||||
$this->_event = 'PARSER_CACHE_USE';
|
||||
parent::__construct($file . $_SERVER['HTTP_HOST'] . $_SERVER['SERVER_PORT'], '.' . $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* method contains cache use decision logic
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
public function makeDefaultCacheDecision()
|
||||
{
|
||||
|
||||
if (!file_exists($this->file)) {
|
||||
return false;
|
||||
} // source exists?
|
||||
return parent::makeDefaultCacheDecision();
|
||||
}
|
||||
|
||||
protected function addDependencies()
|
||||
{
|
||||
|
||||
// parser cache file dependencies ...
|
||||
$files = array(
|
||||
$this->file, // ... source
|
||||
DOKU_INC . 'inc/parser/Parser.php', // ... parser
|
||||
DOKU_INC . 'inc/parser/handler.php', // ... handler
|
||||
);
|
||||
$files = array_merge($files, getConfigFiles('main')); // ... wiki settings
|
||||
|
||||
$this->depends['files'] = !empty($this->depends['files']) ?
|
||||
array_merge($files, $this->depends['files']) :
|
||||
$files;
|
||||
parent::addDependencies();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace dokuwiki\Cache;
|
||||
|
||||
/**
|
||||
* Caching of data of renderer
|
||||
*/
|
||||
class CacheRenderer extends CacheParser
|
||||
{
|
||||
|
||||
/**
|
||||
* method contains cache use decision logic
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
public function makeDefaultCacheDecision()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!parent::makeDefaultCacheDecision()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($this->page)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// meta cache older than file it depends on?
|
||||
if ($this->_time < @filemtime(metaFN($this->page, '.meta'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check current link existence is consistent with cache version
|
||||
// first check the purgefile
|
||||
// - if the cache is more recent than the purgefile we know no links can have been updated
|
||||
if ($this->_time >= @filemtime($conf['cachedir'] . '/purgefile')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// for wiki pages, check metadata dependencies
|
||||
$metadata = p_get_metadata($this->page);
|
||||
|
||||
if (!isset($metadata['relation']['references']) ||
|
||||
empty($metadata['relation']['references'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($metadata['relation']['references'] as $id => $exists) {
|
||||
if ($exists != page_exists($id, '', false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function addDependencies()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
// default renderer cache file 'age' is dependent on 'cachetime' setting, two special values:
|
||||
// -1 : do not cache (should not be overridden)
|
||||
// 0 : cache never expires (can be overridden) - no need to set depends['age']
|
||||
if ($conf['cachetime'] == -1) {
|
||||
$this->_nocache = true;
|
||||
return;
|
||||
} elseif ($conf['cachetime'] > 0) {
|
||||
$this->depends['age'] = isset($this->depends['age']) ?
|
||||
min($this->depends['age'], $conf['cachetime']) : $conf['cachetime'];
|
||||
}
|
||||
|
||||
// renderer cache file dependencies ...
|
||||
$files = array(
|
||||
DOKU_INC . 'inc/parser/' . $this->mode . '.php', // ... the renderer
|
||||
);
|
||||
|
||||
// page implies metadata and possibly some other dependencies
|
||||
if (isset($this->page)) {
|
||||
|
||||
// for xhtml this will render the metadata if needed
|
||||
$valid = p_get_metadata($this->page, 'date valid');
|
||||
if (!empty($valid['age'])) {
|
||||
$this->depends['age'] = isset($this->depends['age']) ?
|
||||
min($this->depends['age'], $valid['age']) : $valid['age'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->depends['files'] = !empty($this->depends['files']) ?
|
||||
array_merge($files, $this->depends['files']) :
|
||||
$files;
|
||||
|
||||
parent::addDependencies();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace dokuwiki\Debug;
|
||||
|
||||
use Doku_Event;
|
||||
|
||||
class DebugHelper
|
||||
{
|
||||
const INFO_DEPRECATION_LOG_EVENT = 'INFO_DEPRECATION_LOG';
|
||||
|
||||
/**
|
||||
* Log accesses to deprecated fucntions to the debug log
|
||||
*
|
||||
* @param string $alternative (optional) The function or method that should be used instead
|
||||
* @param int $callerOffset (optional) How far the deprecated method is removed from this one
|
||||
*
|
||||
* @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT
|
||||
*/
|
||||
public static function dbgDeprecatedFunction($alternative = '', $callerOffset = 1)
|
||||
{
|
||||
global $conf;
|
||||
global $EVENT_HANDLER;
|
||||
if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) {
|
||||
// avoid any work if no one cares
|
||||
return;
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace();
|
||||
for ($i = 0; $i < $callerOffset; $i += 1) {
|
||||
array_shift($backtrace);
|
||||
}
|
||||
|
||||
list($self, $call) = $backtrace;
|
||||
|
||||
self::triggerDeprecationEvent(
|
||||
$backtrace,
|
||||
$alternative,
|
||||
trim($self['class'] . '::' . $self['function'] . '()', ':'),
|
||||
trim($call['class'] . '::' . $call['function'] . '()', ':'),
|
||||
$call['file'],
|
||||
$call['line']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This marks logs a deprecation warning for a property that should no longer be used
|
||||
*
|
||||
* This is usually called withing a magic getter or setter.
|
||||
* For logging deprecated functions or methods see dbgDeprecatedFunction()
|
||||
*
|
||||
* @param string $class The class with the deprecated property
|
||||
* @param string $propertyName The name of the deprecated property
|
||||
*
|
||||
* @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT
|
||||
*/
|
||||
public static function dbgDeprecatedProperty($class, $propertyName)
|
||||
{
|
||||
global $conf;
|
||||
global $EVENT_HANDLER;
|
||||
if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) {
|
||||
// avoid any work if no one cares
|
||||
return;
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace();
|
||||
array_shift($backtrace);
|
||||
$call = $backtrace[1];
|
||||
$caller = trim($call['class'] . '::' . $call['function'] . '()', ':');
|
||||
$qualifiedName = $class . '::$' . $propertyName;
|
||||
self::triggerDeprecationEvent(
|
||||
$backtrace,
|
||||
'',
|
||||
$qualifiedName,
|
||||
$caller,
|
||||
$backtrace[0]['file'],
|
||||
$backtrace[0]['line']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $backtrace
|
||||
* @param string $alternative
|
||||
* @param string $deprecatedThing
|
||||
* @param string $caller
|
||||
* @param string $file
|
||||
* @param int $line
|
||||
*/
|
||||
private static function triggerDeprecationEvent(
|
||||
array $backtrace,
|
||||
$alternative,
|
||||
$deprecatedThing,
|
||||
$caller,
|
||||
$file,
|
||||
$line
|
||||
) {
|
||||
$data = [
|
||||
'trace' => $backtrace,
|
||||
'alternative' => $alternative,
|
||||
'called' => $deprecatedThing,
|
||||
'caller' => $caller,
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
];
|
||||
$event = new Doku_Event(self::INFO_DEPRECATION_LOG_EVENT, $data);
|
||||
if ($event->advise_before()) {
|
||||
$msg = $event->data['called'] . ' is deprecated. It was called from ';
|
||||
$msg .= $event->data['caller'] . ' in ' . $event->data['file'] . ':' . $event->data['line'];
|
||||
if ($event->data['alternative']) {
|
||||
$msg .= ' ' . $event->data['alternative'] . ' should be used instead!';
|
||||
}
|
||||
dbglog($msg);
|
||||
}
|
||||
$event->advise_after();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
/**
|
||||
* Trait for issuing warnings on deprecated access.
|
||||
*
|
||||
* Adapted from https://github.com/wikimedia/mediawiki/blob/4aedefdbfd193f323097354bf581de1c93f02715/includes/debug/DeprecationHelper.php
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace dokuwiki\Debug;
|
||||
|
||||
/**
|
||||
* Use this trait in classes which have properties for which public access
|
||||
* is deprecated. Set the list of properties in $deprecatedPublicProperties
|
||||
* and make the properties non-public. The trait will preserve public access
|
||||
* but issue deprecation warnings when it is needed.
|
||||
*
|
||||
* Example usage:
|
||||
* class Foo {
|
||||
* use DeprecationHelper;
|
||||
* protected $bar;
|
||||
* public function __construct() {
|
||||
* $this->deprecatePublicProperty( 'bar', '1.21', __CLASS__ );
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* $foo = new Foo;
|
||||
* $foo->bar; // works but logs a warning
|
||||
*
|
||||
* Cannot be used with classes that have their own __get/__set methods.
|
||||
*
|
||||
*/
|
||||
trait PropertyDeprecationHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* List of deprecated properties, in <property name> => <class> format
|
||||
* where <class> is the the name of the class defining the property
|
||||
*
|
||||
* E.g. [ '_event' => '\dokuwiki\Cache\Cache' ]
|
||||
* @var string[]
|
||||
*/
|
||||
protected $deprecatedPublicProperties = [];
|
||||
|
||||
/**
|
||||
* Mark a property as deprecated. Only use this for properties that used to be public and only
|
||||
* call it in the constructor.
|
||||
*
|
||||
* @param string $property The name of the property.
|
||||
* @param null $class name of the class defining the property
|
||||
* @see DebugHelper::dbgDeprecatedProperty
|
||||
*/
|
||||
protected function deprecatePublicProperty(
|
||||
$property,
|
||||
$class = null
|
||||
) {
|
||||
$this->deprecatedPublicProperties[$property] = $class ?: get_class();
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
if (isset($this->deprecatedPublicProperties[$name])) {
|
||||
$class = $this->deprecatedPublicProperties[$name];
|
||||
DebugHelper::dbgDeprecatedProperty($class, $name);
|
||||
return $this->$name;
|
||||
}
|
||||
|
||||
$qualifiedName = get_class() . '::$' . $name;
|
||||
if ($this->deprecationHelperGetPropertyOwner($name)) {
|
||||
// Someone tried to access a normal non-public property. Try to behave like PHP would.
|
||||
trigger_error("Cannot access non-public property $qualifiedName", E_USER_ERROR);
|
||||
} else {
|
||||
// Non-existing property. Try to behave like PHP would.
|
||||
trigger_error("Undefined property: $qualifiedName", E_USER_NOTICE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
if (isset($this->deprecatedPublicProperties[$name])) {
|
||||
$class = $this->deprecatedPublicProperties[$name];
|
||||
DebugHelper::dbgDeprecatedProperty($class, $name);
|
||||
$this->$name = $value;
|
||||
return;
|
||||
}
|
||||
|
||||
$qualifiedName = get_class() . '::$' . $name;
|
||||
if ($this->deprecationHelperGetPropertyOwner($name)) {
|
||||
// Someone tried to access a normal non-public property. Try to behave like PHP would.
|
||||
trigger_error("Cannot access non-public property $qualifiedName", E_USER_ERROR);
|
||||
} else {
|
||||
// Non-existing property. Try to behave like PHP would.
|
||||
$this->$name = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like property_exists but also check for non-visible private properties and returns which
|
||||
* class in the inheritance chain declared the property.
|
||||
* @param string $property
|
||||
* @return string|bool Best guess for the class in which the property is defined.
|
||||
*/
|
||||
private function deprecationHelperGetPropertyOwner($property)
|
||||
{
|
||||
// Easy branch: check for protected property / private property of the current class.
|
||||
if (property_exists($this, $property)) {
|
||||
// The class name is not necessarily correct here but getting the correct class
|
||||
// name would be expensive, this will work most of the time and getting it
|
||||
// wrong is not a big deal.
|
||||
return __CLASS__;
|
||||
}
|
||||
// property_exists() returns false when the property does exist but is private (and not
|
||||
// defined by the current class, for some value of "current" that differs slightly
|
||||
// between engines).
|
||||
// Since PHP triggers an error on public access of non-public properties but happily
|
||||
// allows public access to undefined properties, we need to detect this case as well.
|
||||
// Reflection is slow so use array cast hack to check for that:
|
||||
$obfuscatedProps = array_keys((array)$this);
|
||||
$obfuscatedPropTail = "\0$property";
|
||||
foreach ($obfuscatedProps as $obfuscatedProp) {
|
||||
// private props are in the form \0<classname>\0<propname>
|
||||
if (strpos($obfuscatedProp, $obfuscatedPropTail, 1) !== false) {
|
||||
$classname = substr($obfuscatedProp, 1, -strlen($obfuscatedPropTail));
|
||||
if ($classname === '*') {
|
||||
// sanity; this shouldn't be possible as protected properties were handled earlier
|
||||
$classname = __CLASS__;
|
||||
}
|
||||
return $classname;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
355
inc/cache.php
355
inc/cache.php
|
@ -1,342 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* Generic class to handle caching
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Chris Smith <chris@jalakai.co.uk>
|
||||
*/
|
||||
// phpcs:ignoreFile
|
||||
use dokuwiki\Cache\CacheParser;
|
||||
use dokuwiki\Cache\CacheInstructions;
|
||||
use dokuwiki\Cache\CacheRenderer;
|
||||
use dokuwiki\Debug\DebugHelper;
|
||||
|
||||
/**
|
||||
* Generic handling of caching
|
||||
* @deprecated since 2019-02-02 use \dokuwiki\Cache\Cache instead!
|
||||
*/
|
||||
class cache {
|
||||
public $key = ''; // primary identifier for this item
|
||||
public $ext = ''; // file ext for cache data, secondary identifier for this item
|
||||
public $cache = ''; // cache file name
|
||||
public $depends = array(); // array containing cache dependency information,
|
||||
// used by _useCache to determine cache validity
|
||||
class cache extends \dokuwiki\Cache\Cache
|
||||
{
|
||||
|
||||
public $_event = ''; // event to be triggered during useCache
|
||||
public $_time;
|
||||
public $_nocache = false; // if set to true, cache will not be used or stored
|
||||
|
||||
/**
|
||||
* @param string $key primary identifier
|
||||
* @param string $ext file extension
|
||||
*/
|
||||
public function __construct($key,$ext) {
|
||||
$this->key = $key;
|
||||
$this->ext = $ext;
|
||||
$this->cache = getCacheName($key,$ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* public method to determine whether the cache can be used
|
||||
*
|
||||
* to assist in centralisation of event triggering and calculation of cache statistics,
|
||||
* don't override this function override _useCache()
|
||||
*
|
||||
* @param array $depends array of cache dependencies, support dependecies:
|
||||
* 'age' => max age of the cache in seconds
|
||||
* 'files' => cache must be younger than mtime of each file
|
||||
* (nb. dependency passes if file doesn't exist)
|
||||
*
|
||||
* @return bool true if cache can be used, false otherwise
|
||||
*/
|
||||
public function useCache($depends=array()) {
|
||||
$this->depends = $depends;
|
||||
$this->_addDependencies();
|
||||
|
||||
if ($this->_event) {
|
||||
return $this->_stats(trigger_event($this->_event, $this, array($this,'_useCache')));
|
||||
} else {
|
||||
return $this->_stats($this->_useCache());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* private method containing cache use decision logic
|
||||
*
|
||||
* this function processes the following keys in the depends array
|
||||
* purge - force a purge on any non empty value
|
||||
* age - expire cache if older than age (seconds)
|
||||
* files - expire cache if any file in this array was updated more recently than the cache
|
||||
*
|
||||
* Note that this function needs to be public as it is used as callback for the event handler
|
||||
*
|
||||
* can be overridden
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
public function _useCache() {
|
||||
|
||||
if ($this->_nocache) return false; // caching turned off
|
||||
if (!empty($this->depends['purge'])) return false; // purge requested?
|
||||
if (!($this->_time = @filemtime($this->cache))) return false; // cache exists?
|
||||
|
||||
// cache too old?
|
||||
if (!empty($this->depends['age']) && ((time() - $this->_time) > $this->depends['age'])) return false;
|
||||
|
||||
if (!empty($this->depends['files'])) {
|
||||
foreach ($this->depends['files'] as $file) {
|
||||
if ($this->_time <= @filemtime($file)) return false; // cache older than files it depends on?
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* add dependencies to the depends array
|
||||
*
|
||||
* this method should only add dependencies,
|
||||
* it should not remove any existing dependencies and
|
||||
* it should only overwrite a dependency when the new value is more stringent than the old
|
||||
*/
|
||||
protected function _addDependencies() {
|
||||
global $INPUT;
|
||||
if ($INPUT->has('purge')) $this->depends['purge'] = true; // purge requested
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the cached data
|
||||
*
|
||||
* @param bool $clean true to clean line endings, false to leave line endings alone
|
||||
* @return string cache contents
|
||||
*/
|
||||
public function retrieveCache($clean=true) {
|
||||
return io_readFile($this->cache, $clean);
|
||||
}
|
||||
|
||||
/**
|
||||
* cache $data
|
||||
*
|
||||
* @param string $data the data to be cached
|
||||
* @return bool true on success, false otherwise
|
||||
*/
|
||||
public function storeCache($data) {
|
||||
if ($this->_nocache) return false;
|
||||
|
||||
return io_savefile($this->cache, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove any cached data associated with this cache instance
|
||||
*/
|
||||
public function removeCache() {
|
||||
@unlink($this->cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record cache hits statistics.
|
||||
* (Only when debugging allowed, to reduce overhead.)
|
||||
*
|
||||
* @param bool $success result of this cache use attempt
|
||||
* @return bool pass-thru $success value
|
||||
*/
|
||||
protected function _stats($success) {
|
||||
global $conf;
|
||||
static $stats = null;
|
||||
static $file;
|
||||
|
||||
if (!$conf['allowdebug']) { return $success; }
|
||||
|
||||
if (is_null($stats)) {
|
||||
$file = $conf['cachedir'].'/cache_stats.txt';
|
||||
$lines = explode("\n",io_readFile($file));
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$i = strpos($line,',');
|
||||
$stats[substr($line,0,$i)] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($stats[$this->ext])) {
|
||||
list($ext,$count,$hits) = explode(',',$stats[$this->ext]);
|
||||
} else {
|
||||
$ext = $this->ext;
|
||||
$count = 0;
|
||||
$hits = 0;
|
||||
}
|
||||
|
||||
$count++;
|
||||
if ($success) $hits++;
|
||||
$stats[$this->ext] = "$ext,$count,$hits";
|
||||
|
||||
io_saveFile($file,join("\n",$stats));
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parser caching
|
||||
*/
|
||||
class cache_parser extends cache {
|
||||
|
||||
public $file = ''; // source file for cache
|
||||
public $mode = ''; // input mode (represents the processing the input file will undergo)
|
||||
public $page = '';
|
||||
|
||||
public $_event = 'PARSER_CACHE_USE';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $id page id
|
||||
* @param string $file source file for cache
|
||||
* @param string $mode input mode
|
||||
*/
|
||||
public function __construct($id, $file, $mode) {
|
||||
if ($id) $this->page = $id;
|
||||
$this->file = $file;
|
||||
$this->mode = $mode;
|
||||
|
||||
parent::__construct($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],'.'.$mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* method contains cache use decision logic
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
public function _useCache() {
|
||||
|
||||
if (!file_exists($this->file)) return false; // source exists?
|
||||
return parent::_useCache();
|
||||
}
|
||||
|
||||
protected function _addDependencies() {
|
||||
|
||||
// parser cache file dependencies ...
|
||||
$files = array($this->file, // ... source
|
||||
DOKU_INC.'inc/parser/Parser.php', // ... parser
|
||||
DOKU_INC.'inc/parser/handler.php', // ... handler
|
||||
);
|
||||
$files = array_merge($files, getConfigFiles('main')); // ... wiki settings
|
||||
|
||||
$this->depends['files'] = !empty($this->depends['files']) ?
|
||||
array_merge($files, $this->depends['files']) :
|
||||
$files;
|
||||
parent::_addDependencies();
|
||||
public function __construct($key, $ext)
|
||||
{
|
||||
DebugHelper::dbgDeprecatedFunction(dokuwiki\Cache\Cache::class);
|
||||
parent::__construct($key, $ext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Caching of data of renderer
|
||||
* @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheParser instead!
|
||||
*/
|
||||
class cache_renderer extends cache_parser {
|
||||
class cache_parser extends \dokuwiki\Cache\CacheParser
|
||||
{
|
||||
|
||||
/**
|
||||
* method contains cache use decision logic
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
public function _useCache() {
|
||||
global $conf;
|
||||
|
||||
if (!parent::_useCache()) return false;
|
||||
|
||||
if (!isset($this->page)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// meta cache older than file it depends on?
|
||||
if ($this->_time < @filemtime(metaFN($this->page,'.meta'))) return false;
|
||||
|
||||
// check current link existence is consistent with cache version
|
||||
// first check the purgefile
|
||||
// - if the cache is more recent than the purgefile we know no links can have been updated
|
||||
if ($this->_time >= @filemtime($conf['cachedir'].'/purgefile')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// for wiki pages, check metadata dependencies
|
||||
$metadata = p_get_metadata($this->page);
|
||||
|
||||
if (!isset($metadata['relation']['references']) ||
|
||||
empty($metadata['relation']['references'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($metadata['relation']['references'] as $id => $exists) {
|
||||
if ($exists != page_exists($id,'',false)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
public function __construct($id, $file, $mode)
|
||||
{
|
||||
DebugHelper::dbgDeprecatedFunction(CacheParser::class);
|
||||
parent::__construct($id, $file, $mode);
|
||||
}
|
||||
|
||||
protected function _addDependencies() {
|
||||
global $conf;
|
||||
}
|
||||
|
||||
// default renderer cache file 'age' is dependent on 'cachetime' setting, two special values:
|
||||
// -1 : do not cache (should not be overridden)
|
||||
// 0 : cache never expires (can be overridden) - no need to set depends['age']
|
||||
if ($conf['cachetime'] == -1) {
|
||||
$this->_nocache = true;
|
||||
return;
|
||||
} elseif ($conf['cachetime'] > 0) {
|
||||
$this->depends['age'] = isset($this->depends['age']) ?
|
||||
min($this->depends['age'],$conf['cachetime']) : $conf['cachetime'];
|
||||
}
|
||||
/**
|
||||
* @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheRenderer instead!
|
||||
*/
|
||||
class cache_renderer extends \dokuwiki\Cache\CacheRenderer
|
||||
{
|
||||
|
||||
// renderer cache file dependencies ...
|
||||
$files = array(
|
||||
DOKU_INC.'inc/parser/'.$this->mode.'.php', // ... the renderer
|
||||
);
|
||||
|
||||
// page implies metadata and possibly some other dependencies
|
||||
if (isset($this->page)) {
|
||||
|
||||
// for xhtml this will render the metadata if needed
|
||||
$valid = p_get_metadata($this->page, 'date valid');
|
||||
if (!empty($valid['age'])) {
|
||||
$this->depends['age'] = isset($this->depends['age']) ?
|
||||
min($this->depends['age'],$valid['age']) : $valid['age'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->depends['files'] = !empty($this->depends['files']) ?
|
||||
array_merge($files, $this->depends['files']) :
|
||||
$files;
|
||||
|
||||
parent::_addDependencies();
|
||||
public function __construct($id, $file, $mode)
|
||||
{
|
||||
DebugHelper::dbgDeprecatedFunction(CacheRenderer::class);
|
||||
parent::__construct($id, $file, $mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Caching of parser instructions
|
||||
* @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheInstructions instead!
|
||||
*/
|
||||
class cache_instructions extends cache_parser {
|
||||
|
||||
/**
|
||||
* @param string $id page id
|
||||
* @param string $file source file for cache
|
||||
*/
|
||||
public function __construct($id, $file) {
|
||||
parent::__construct($id, $file, 'i');
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the cached data
|
||||
*
|
||||
* @param bool $clean true to clean line endings, false to leave line endings alone
|
||||
* @return array cache contents
|
||||
*/
|
||||
public function retrieveCache($clean=true) {
|
||||
$contents = io_readFile($this->cache, false);
|
||||
return !empty($contents) ? unserialize($contents) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* cache $instructions
|
||||
*
|
||||
* @param array $instructions the instruction to be cached
|
||||
* @return bool true on success, false otherwise
|
||||
*/
|
||||
public function storeCache($instructions) {
|
||||
if ($this->_nocache) return false;
|
||||
|
||||
return io_savefile($this->cache,serialize($instructions));
|
||||
class cache_instructions extends \dokuwiki\Cache\CacheInstructions
|
||||
{
|
||||
public function __construct($id, $file)
|
||||
{
|
||||
DebugHelper::dbgDeprecatedFunction(CacheInstructions::class);
|
||||
parent::__construct($id, $file);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
|
||||
use dokuwiki\Cache\CacheInstructions;
|
||||
use dokuwiki\Cache\CacheRenderer;
|
||||
use dokuwiki\ChangeLog\PageChangeLog;
|
||||
|
||||
/**
|
||||
|
@ -1293,7 +1295,7 @@ function detectExternalEdit($id) {
|
|||
$sizechange
|
||||
);
|
||||
// remove soon to be stale instructions
|
||||
$cache = new cache_instructions($id, $fileLastMod);
|
||||
$cache = new CacheInstructions($id, $fileLastMod);
|
||||
$cache->removeCache();
|
||||
}
|
||||
}
|
||||
|
@ -1423,7 +1425,7 @@ function saveWikiText($id, $text, $summary, $minor = false) {
|
|||
if(useHeading('content')) {
|
||||
$pages = ft_backlinks($id, true);
|
||||
foreach($pages as $page) {
|
||||
$cache = new cache_renderer($page, wikiFN($page), 'xhtml');
|
||||
$cache = new CacheRenderer($page, wikiFN($page), 'xhtml');
|
||||
$cache->removeCache();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -450,40 +450,11 @@ function dbglog($msg,$header=''){
|
|||
* Log accesses to deprecated fucntions to the debug log
|
||||
*
|
||||
* @param string $alternative The function or method that should be used instead
|
||||
* @param string|null $deprecatedThing What is deprecated if not the current method
|
||||
* @triggers INFO_DEPRECATION_LOG
|
||||
*/
|
||||
function dbg_deprecated($alternative = '') {
|
||||
global $conf;
|
||||
global $EVENT_HANDLER;
|
||||
if(!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent('INFO_DEPRECATION_LOG')) {
|
||||
// avoid any work if no one cares
|
||||
return;
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace();
|
||||
array_shift($backtrace);
|
||||
$self = $backtrace[0];
|
||||
$call = $backtrace[1];
|
||||
|
||||
$data = [
|
||||
'trace' => $backtrace,
|
||||
'alternative' => $alternative,
|
||||
'called' => trim($self['class'] . '::' . $self['function'] . '()', ':'),
|
||||
'caller' => trim($call['class'] . '::' . $call['function'] . '()', ':'),
|
||||
'file' => $call['file'],
|
||||
'line' => $call['line'],
|
||||
];
|
||||
|
||||
$event = new Doku_Event('INFO_DEPRECATION_LOG', $data);
|
||||
if($event->advise_before()) {
|
||||
$msg = $event->data['called'] . ' is deprecated. It was called from ';
|
||||
$msg .= $event->data['caller'] . ' in ' . $event->data['file'] . ':' . $event->data['line'];
|
||||
if($event->data['alternative']) {
|
||||
$msg .= ' ' . $event->data['alternative'] . ' should be used instead!';
|
||||
}
|
||||
dbglog($msg);
|
||||
}
|
||||
$event->advise_after();
|
||||
\dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction($alternative, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
|
||||
use dokuwiki\Cache\CacheInstructions;
|
||||
use dokuwiki\Cache\CacheRenderer;
|
||||
use dokuwiki\Parsing\Parser;
|
||||
|
||||
/**
|
||||
|
@ -127,7 +129,7 @@ function p_locale_xhtml($id){
|
|||
function p_cached_output($file, $format='xhtml', $id='') {
|
||||
global $conf;
|
||||
|
||||
$cache = new cache_renderer($id, $file, $format);
|
||||
$cache = new CacheRenderer($id, $file, $format);
|
||||
if ($cache->useCache()) {
|
||||
$parsed = $cache->retrieveCache(false);
|
||||
if($conf['allowdebug'] && $format=='xhtml') {
|
||||
|
@ -167,7 +169,7 @@ function p_cached_instructions($file,$cacheonly=false,$id='') {
|
|||
static $run = null;
|
||||
if(is_null($run)) $run = array();
|
||||
|
||||
$cache = new cache_instructions($id, $file);
|
||||
$cache = new CacheInstructions($id, $file);
|
||||
|
||||
if ($cacheonly || $cache->useCache() || (isset($run[$file]) && !defined('DOKU_UNITTEST'))) {
|
||||
return $cache->retrieveCache();
|
||||
|
@ -254,7 +256,7 @@ function p_get_metadata($id, $key='', $render=METADATA_RENDER_USING_CACHE){
|
|||
if (!$recursion && $render != METADATA_DONT_RENDER && !isset($rendered_pages[$id])&& page_exists($id)){
|
||||
$recursion = true;
|
||||
|
||||
$cachefile = new cache_renderer($id, wikiFN($id), 'metadata');
|
||||
$cachefile = new CacheRenderer($id, wikiFN($id), 'metadata');
|
||||
|
||||
$do_render = false;
|
||||
if ($render & METADATA_RENDER_UNLIMITED || $render_count < P_GET_METADATA_RENDER_LIMIT) {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
|
||||
use dokuwiki\Cache\Cache;
|
||||
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
|
||||
if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
|
||||
if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here
|
||||
|
@ -100,7 +102,7 @@ function css_out(){
|
|||
}
|
||||
|
||||
// The generated script depends on some dynamic options
|
||||
$cache = new cache(
|
||||
$cache = new Cache(
|
||||
'styles' .
|
||||
$_SERVER['HTTP_HOST'] .
|
||||
$_SERVER['SERVER_PORT'] .
|
||||
|
@ -110,7 +112,7 @@ function css_out(){
|
|||
$type,
|
||||
'.css'
|
||||
);
|
||||
$cache->_event = 'CSS_CACHE_USE';
|
||||
$cache->setEvent('CSS_CACHE_USE');
|
||||
|
||||
// check cache age & handle conditional request
|
||||
// This may exit if a cache can be used
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use dokuwiki\Cache\Cache;
|
||||
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/../../');
|
||||
if(!defined('NOSESSION')) define('NOSESSION', true); // we do not use a session or authentication here (better caching)
|
||||
if(!defined('NL')) define('NL', "\n");
|
||||
|
@ -19,7 +21,7 @@ jquery_out();
|
|||
* uses cache or fills it
|
||||
*/
|
||||
function jquery_out() {
|
||||
$cache = new cache('jquery', '.js');
|
||||
$cache = new Cache('jquery', '.js');
|
||||
$files = array(
|
||||
DOKU_INC . 'lib/scripts/jquery/jquery.min.js',
|
||||
DOKU_INC . 'lib/scripts/jquery/jquery-ui.min.js',
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
|
||||
use dokuwiki\Cache\Cache;
|
||||
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
|
||||
if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
|
||||
if(!defined('NL')) define('NL',"\n");
|
||||
|
@ -76,8 +78,8 @@ function js_out(){
|
|||
trigger_event('JS_SCRIPT_LIST', $files);
|
||||
|
||||
// The generated script depends on some dynamic options
|
||||
$cache = new cache('scripts'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].md5(serialize($files)),'.js');
|
||||
$cache->_event = 'JS_CACHE_USE';
|
||||
$cache = new Cache('scripts'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].md5(serialize($files)),'.js');
|
||||
$cache->setEvent('JS_CACHE_USE');
|
||||
|
||||
$cache_files = array_merge($files, getConfigFiles('main'));
|
||||
$cache_files[] = __FILE__;
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* @author Michael Hamann <michael@content-space.de>
|
||||
*/
|
||||
|
||||
use dokuwiki\Cache\Cache;
|
||||
|
||||
/**
|
||||
* Class helper_plugin_extension_repository provides access to the extension repository on dokuwiki.org
|
||||
*/
|
||||
|
@ -29,7 +31,7 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin
|
|||
$request_data = array('fmt' => 'php');
|
||||
$request_needed = false;
|
||||
foreach ($list as $name) {
|
||||
$cache = new cache('##extension_manager##'.$name, '.repo');
|
||||
$cache = new Cache('##extension_manager##'.$name, '.repo');
|
||||
|
||||
if (!isset($this->loaded_extensions[$name]) &&
|
||||
$this->hasAccess() &&
|
||||
|
@ -47,7 +49,7 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin
|
|||
if ($data !== false) {
|
||||
$extensions = unserialize($data);
|
||||
foreach ($extensions as $extension) {
|
||||
$cache = new cache('##extension_manager##'.$extension['plugin'], '.repo');
|
||||
$cache = new Cache('##extension_manager##'.$extension['plugin'], '.repo');
|
||||
$cache->storeCache(serialize($extension));
|
||||
}
|
||||
} else {
|
||||
|
@ -65,7 +67,7 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin
|
|||
public function hasAccess()
|
||||
{
|
||||
if ($this->has_access === null) {
|
||||
$cache = new cache('##extension_manager###hasAccess', '.repo');
|
||||
$cache = new Cache('##extension_manager###hasAccess', '.repo');
|
||||
|
||||
if (!$cache->useCache(array('age' => 3600 * 24, 'purge'=>1))) {
|
||||
$httpclient = new DokuHTTPClient();
|
||||
|
@ -93,7 +95,7 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin
|
|||
*/
|
||||
public function getData($name)
|
||||
{
|
||||
$cache = new cache('##extension_manager##'.$name, '.repo');
|
||||
$cache = new Cache('##extension_manager##'.$name, '.repo');
|
||||
|
||||
if (!isset($this->loaded_extensions[$name]) &&
|
||||
$this->hasAccess() &&
|
||||
|
@ -137,7 +139,7 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin
|
|||
// store cache info for each extension
|
||||
foreach ($result as $ext) {
|
||||
$name = $ext['plugin'];
|
||||
$cache = new cache('##extension_manager##'.$name, '.repo');
|
||||
$cache = new Cache('##extension_manager##'.$name, '.repo');
|
||||
$cache->storeCache(serialize($ext));
|
||||
$ids[] = $name;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue