Commit 3778f5b4 authored by Christian Kuhn's avatar Christian Kuhn
Browse files

[!!!][FEATURE] Update cache framework to latest FLOW3 version

Update the caching framework to FLOW3 version 868e073b98

Main changes:

[!!!][FEATURE] Make cache backends more flexible
This change makes cache backends more flexible. It adds a new
interface "TaggableBackendInterface" and a new "SimpleFileBackend".
The latter does not support tagging but is faster in certain cases
(where with a lot of tags/entries flushing everything is faster than
flushing by tag).
If you have implemented a cache backend and support tagging, you must
add the "TaggableBackendInterface" to the list of interfaces implemented
by your backend.

[BUGFIX] Fix default lifetime use in cache backend

[FEATURE] Freezable Cache Backend
Introduce a new type of cache backends which supports freezing.
In a frozen state no modifications are allowed and thus enables the
cache implementation to optimize its tasks for speed.
The FileBackend was extended to support freezing.

Change-Id: Id4c609ecfcbb223cf6bc99202ef41b436e21ef78
Resolves: #39430
Related: #36563
Related: #33562
Related: #32398
Related: #36564
Releases: 6.0
Reviewed-on: http://review.typo3.org/13390
Reviewed-by: Helmut Hummel
Tested-by: Helmut Hummel
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
parent f2673678
......@@ -77,7 +77,7 @@ abstract class t3lib_cache_backend_AbstractBackend implements t3lib_cache_backen
*/
public function __construct($context, array $options = array()) {
$this->context = $context;
if (is_array($options) || $options instanceof ArrayAccess) {
if (is_array($options) || $options instanceof \ArrayAccess) {
foreach ($options as $optionKey => $optionValue) {
$methodName = 'set' . ucfirst($optionKey);
if (method_exists($this, $methodName)) {
......@@ -109,6 +109,7 @@ abstract class t3lib_cache_backend_AbstractBackend implements t3lib_cache_backen
*
* @param integer $defaultLifetime Default lifetime of this cache backend in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited liftime.
* @return void
* @throws \InvalidArgumentException
* @api
*/
public function setDefaultLifetime($defaultLifetime) {
......
......@@ -51,9 +51,8 @@
* @author Christian Jul Jensen <julle@typo3.org>
* @author Dmitry Dulepov <dmitry@typo3.org>
* @api
* @scope prototype
*/
class t3lib_cache_backend_ApcBackend extends t3lib_cache_backend_AbstractBackend {
class t3lib_cache_backend_ApcBackend extends t3lib_cache_backend_AbstractBackend implements t3lib_cache_backend_TaggableBackend {
/**
* A prefix to seperate stored data from other data possible stored in the APC
......@@ -66,10 +65,11 @@ class t3lib_cache_backend_ApcBackend extends t3lib_cache_backend_AbstractBackend
*
* @param string $context FLOW3's application context
* @param array $options Configuration options - unused here
* @throws \t3lib_cache_Exception
*/
public function __construct($context, array $options = array()) {
if (!extension_loaded('apc')) {
throw new t3lib_cache_Exception(
throw new \t3lib_cache_Exception(
'The PHP extension "apc" must be installed and loaded in order to use the APC backend.',
1232985414
);
......@@ -99,21 +99,20 @@ class t3lib_cache_backend_ApcBackend extends t3lib_cache_backend_AbstractBackend
* @param array $tags Tags to associate with this cache entry
* @param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited liftime.
* @return void
* @throws t3lib_cache_Exception if no cache frontend has been set.
* @throws \InvalidArgumentException if the identifier is not valid
* @throws t3lib_cache_exception_InvalidData if $data is not a string
* @throws \t3lib_cache_Exception if no cache frontend has been set.
* @throws \t3lib_cache_exception_InvalidData if $data is not a string
* @api
*/
public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
throw new t3lib_cache_Exception(
throw new \t3lib_cache_Exception(
'No cache frontend has been set yet via setCache().',
1232986818
);
}
if (!is_string($data)) {
throw new t3lib_cache_exception_InvalidData(
throw new \t3lib_cache_exception_InvalidData(
'The specified data is of type "' . gettype($data) . '" but a string is expected.',
1232986825
);
......@@ -127,7 +126,7 @@ class t3lib_cache_backend_ApcBackend extends t3lib_cache_backend_AbstractBackend
$this->removeIdentifierFromAllTags($entryIdentifier);
$this->addIdentifierToTags($entryIdentifier, $tags);
} else {
throw new t3lib_cache_Exception(
throw new \t3lib_cache_Exception(
'Could not set value.',
1232986877
);
......@@ -210,11 +209,12 @@ class t3lib_cache_backend_ApcBackend extends t3lib_cache_backend_AbstractBackend
* Removes all cache entries of this cache.
*
* @return void
* @throws \t3lib_cache_Exception
* @api
*/
public function flush() {
if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
throw new t3lib_cache_Exception(
throw new \t3lib_cache_Exception(
'Yet no cache frontend has been set via setCache().',
1232986971
);
......@@ -242,6 +242,7 @@ class t3lib_cache_backend_ApcBackend extends t3lib_cache_backend_AbstractBackend
*
* @param string $entryIdentifier
* @param array $tags
* @return void
*/
protected function addIdentifierToTags($entryIdentifier, array $tags) {
foreach ($tags as $tag) {
......@@ -265,7 +266,7 @@ class t3lib_cache_backend_ApcBackend extends t3lib_cache_backend_AbstractBackend
* Removes association of the identifier with the given tags
*
* @param string $entryIdentifier
* @param array $tags
* @return void
*/
protected function removeIdentifierFromAllTags($entryIdentifier) {
// Get tags for this identifier
......
......@@ -30,9 +30,8 @@
* @author Christian Kuhn <lolli@schwarzbu.ch>
* @author Ingo Renner <ingo@typo3.org>
* @api
* @scope prototype
*/
class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend {
class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend implements t3lib_cache_backend_TaggableBackend {
/**
* @var integer Timestamp of 2038-01-01)
......@@ -112,7 +111,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Initializes common references used in this backend.
*
* @return void
* @return void
*/
protected function initializeCommonReferences() {
$this->identifierField = $this->cacheTable . '.identifier';
......@@ -127,19 +126,19 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Saves data in a cache file.
*
* @param string An identifier for this specific cache entry
* @param string The data to be stored
* @param array Tags to associate with this cache entry
* @param integer Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited liftime.
* @param string $entryIdentifier An identifier for this specific cache entry
* @param string $data The data to be stored
* @param array $tags Tags to associate with this cache entry
* @param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited liftime.
* @return void
* @throws t3lib_cache_Exception if no cache frontend has been set.
* @throws t3lib_cache_exception_InvalidData if the data to be stored is not a string.
* @throws \t3lib_cache_Exception if no cache frontend has been set.
* @throws \t3lib_cache_exception_InvalidData if the data to be stored is not a string.
*/
public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
$this->throwExceptionIfFrontendDoesNotExist();
if (!is_string($data)) {
throw new t3lib_cache_exception_InvalidData(
throw new \t3lib_cache_exception_InvalidData(
'The specified data is of type "' . gettype($data) . '" but a string is expected.',
1236518298
);
......@@ -274,7 +273,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Finds and returns all cache entries which are tagged by the specified tag.
*
* @param string The tag to search for
* @param string $tag The tag to search for
* @return array An array with identifiers of all matching entries. An empty array if no entries matched
*/
public function findIdentifiersByTag($tag) {
......@@ -313,7 +312,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Removes all cache entries of this cache which are tagged by the specified tag.
*
* @param string The tag the entries must have
* @param string $tag The tag the entries must have
* @return void
*/
public function flushByTag($tag) {
......@@ -371,7 +370,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Returns the table where the cache entries are stored.
*
* @return string The cache table.
* @return string The cache table.
*/
public function getCacheTable() {
$this->throwExceptionIfFrontendDoesNotExist();
......@@ -382,7 +381,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Gets the table where cache tags are stored.
*
* @return string Name of the table storing tags
* @return string Name of the table storing tags
*/
public function getTagsTable() {
$this->throwExceptionIfFrontendDoesNotExist();
......@@ -393,7 +392,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Enable data compression
*
* @param boolean TRUE to enable compression
* @param boolean $compression TRUE to enable compression
*/
public function setCompression($compression) {
$this->compression = $compression;
......@@ -415,12 +414,12 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Check if required frontend instance exists
*
* @throws t3lib_cache_Exception If there is no frontend instance in $this->cache
* @throws \t3lib_cache_Exception If there is no frontend instance in $this->cache
* @return void
*/
protected function throwExceptionIfFrontendDoesNotExist() {
if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
throw new t3lib_cache_Exception(
throw new \t3lib_cache_Exception(
'No cache frontend has been set via setCache() yet.',
1236518288
);
......@@ -445,7 +444,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
/**
* Deletes rows in cache table found by where clause on tags table
*
* @param string The where clause for the tags table
* @param string $tagsTableWhereClause The where clause for the tags table
* @return void
*/
protected function deleteCacheTableRowsByTagsTableWhereClause($tagsTableWhereClause) {
......
......@@ -33,9 +33,8 @@
* @author Christian Kuhn <lolli@schwarzbu.ch>
* @author Karsten Dambekalns <karsten@typo3.org>
* @api
* @scope prototype
*/
class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBackend implements t3lib_cache_backend_PhpCapableBackend {
class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_SimpleFileBackend implements t3lib_cache_backend_PhpCapableBackend, t3lib_cache_backend_FreezableBackend, t3lib_cache_backend_TaggableBackend {
const SEPARATOR = '^';
......@@ -45,183 +44,100 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
const DATASIZE_DIGITS = 10;
/**
* Directory where the files are stored
* A file extension to use for each cache entry.
*
* @var string
*/
protected $cacheDirectory = '';
protected $cacheEntryFileExtension = '';
/**
* TYPO3 v4 note: This variable is only available in v5
* Temporary path to cache directory before setCache() was called. It is
* set by setCacheDirectory() and used in setCache() method which calls
* the directory creation if needed. The variable is not used afterwards,
* the final cache directory path is stored in $this->cacheDirectory then.
*
* @var string Temporary path to cache directory
* @var array
*/
protected $temporaryCacheDirectory = '';
protected $cacheEntryIdentifiers = array();
/**
* A file extension to use for each cache entry.
*
* @var string
* @var boolean
*/
protected $cacheEntryFileExtension = '';
protected $frozen = FALSE;
/**
* Sets a reference to the cache frontend which uses this backend and
* initializes the default cache directory.
* Freezes this cache backend.
*
* TYPO3 v4 note: This method is different between TYPO3 v4 and FLOW3
* because the Environment class to get the path to a temporary directory
* does not exist in v4.
*
* @param t3lib_cache_frontend_Frontend $cache The cache frontend
* @return void
*/
public function setCache(t3lib_cache_frontend_Frontend $cache) {
parent::setCache($cache);
if (empty($this->temporaryCacheDirectory)) {
// If no cache directory was given with cacheDirectory
// configuration option, set it to a path below typo3temp/
$temporaryCacheDirectory = PATH_site . 'typo3temp/';
} else {
$temporaryCacheDirectory = $this->temporaryCacheDirectory;
}
$codeOrData = ($cache instanceof t3lib_cache_frontend_PhpFrontend) ? 'Code' : 'Data';
$finalCacheDirectory = $temporaryCacheDirectory . 'Cache/' . $codeOrData . '/' . $this->cacheIdentifier . '/';
if (!is_dir($finalCacheDirectory)) {
$this->createFinalCacheDirectory($finalCacheDirectory);
}
unset($this->temporaryCacheDirectory);
$this->cacheDirectory = $finalCacheDirectory;
$this->cacheEntryFileExtension = ($cache instanceof t3lib_cache_frontend_PhpFrontend) ? '.php' : '';
}
/**
* Sets the directory where the cache files are stored. By default it is
* assumed that the directory is below the TYPO3_DOCUMENT_ROOT. However, an
* absolute path can be selected, too.
* All data in a frozen backend remains unchanged and methods which try to add
* or modify data result in an exception thrown. Possible expiry times of
* individual cache entries are ignored.
*
* This method does not exist in FLOW3 anymore, but it is needed in
* TYPO3 v4 to enable a cache path outside of document root. The final
* cache path is checked and created in createFinalCachDirectory(),
* called by setCache() method, which is done _after_ the cacheDirectory
* option was handled.
* On the positive side, a frozen cache backend is much faster on read access.
* A frozen backend can only be thawed by calling the flush() method.
*
* @param string $cacheDirectory The cache base directory. If a relative path
* is given, it is assumed it is in TYPO3_DOCUMENT_ROOT. If an absolute
* path is given it is taken as is.
* @return void
* @throws t3lib_cache_Exception if the directory is not within allowed
* open_basedir path.
* @throws \RuntimeException
*/
public function setCacheDirectory($cacheDirectory) {
// Skip handling if directory is a stream ressource
// This is used by unit tests with vfs:// directoryies
if (strpos($cacheDirectory, '://')) {
$this->temporaryCacheDirectory = $cacheDirectory;
return;
public function freeze() {
if ($this->frozen === TRUE) {
throw new \RuntimeException(
sprintf('The cache "%s" is already frozen.', $this->cacheIdentifier),
1323353176
);
}
$documentRoot = PATH_site;
if (($open_basedir = ini_get('open_basedir'))) {
if (TYPO3_OS === 'WIN') {
$delimiter = ';';
$cacheDirectory = str_replace('\\', '/', $cacheDirectory);
if (!(preg_match('/[A-Z]:/', substr($cacheDirectory, 0, 2)))) {
$cacheDirectory = PATH_site . $cacheDirectory;
}
} else {
$delimiter = ':';
if ($cacheDirectory[0] != '/') {
// relative path to cache directory.
$cacheDirectory = PATH_site . $cacheDirectory;
}
}
$cacheEntryFileExtensionLength = strlen($this->cacheEntryFileExtension);
$basedirs = explode($delimiter, $open_basedir);
$cacheDirectoryInBaseDir = FALSE;
foreach ($basedirs as $basedir) {
if (TYPO3_OS === 'WIN') {
$basedir = str_replace('\\', '/', $basedir);
}
if ($basedir[strlen($basedir) - 1] !== '/') {
$basedir .= '/';
}
if (t3lib_div::isFirstPartOfStr($cacheDirectory, $basedir)) {
$documentRoot = $basedir;
$cacheDirectory = str_replace($basedir, '', $cacheDirectory);
$cacheDirectoryInBaseDir = TRUE;
break;
}
}
if (!$cacheDirectoryInBaseDir) {
throw new t3lib_cache_Exception(
'Open_basedir restriction in effect. The directory "' . $cacheDirectory . '" is not in an allowed path.'
);
}
} else {
if ($cacheDirectory[0] == '/') {
// Absolute path to cache directory.
$documentRoot = '/';
for($directoryIterator = new \DirectoryIterator($this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
if ($directoryIterator->isDot()) {
continue;
}
if (TYPO3_OS === 'WIN') {
if (substr($cacheDirectory, 0, strlen($documentRoot)) === $documentRoot) {
$documentRoot = '';
}
if ($cacheEntryFileExtensionLength > 0) {
$entryIdentifier = substr($directoryIterator->getFilename(), 0, - $cacheEntryFileExtensionLength);
} else {
$entryIdentifier = $directoryIterator->getFilename();
}
$this->cacheEntryIdentifiers[$entryIdentifier] = TRUE;
file_put_contents($this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension, $this->get($entryIdentifier));
}
// After this point all paths have '/' as directory seperator
if ($cacheDirectory[strlen($cacheDirectory) - 1] !== '/') {
$cacheDirectory .= '/';
if ($this->useIgBinary === TRUE) {
file_put_contents($this->cacheDirectory . 'FrozenCache.data', igbinary_serialize($this->cacheEntryIdentifiers));
} else {
file_put_contents($this->cacheDirectory . 'FrozenCache.data', serialize($this->cacheEntryIdentifiers));
}
$this->temporaryCacheDirectory = $documentRoot . $cacheDirectory . $this->cacheIdentifier . '/';
$this->frozen = TRUE;
}
/**
* Create the final cache directory if it does not exist. This method
* exists in TYPO3 v4 only.
* Tells if this backend is frozen.
*
* @param string $finalCacheDirectory Absolute path to final cache directory
* @return void
* @throws \t3lib_cache_Exception If directory is not writable after creation
* @return boolean
*/
protected function createFinalCacheDirectory($finalCacheDirectory) {
try {
t3lib_div::mkdir_deep($finalCacheDirectory);
} catch (\RuntimeException $e) {
throw new \t3lib_cache_Exception(
'The directory "' . $finalCacheDirectory . '" can not be created.',
1303669848,
$e
);
}
if (!is_writable($finalCacheDirectory)) {
throw new \t3lib_cache_Exception(
'The directory "' . $finalCacheDirectory . '" is not writable.',
1203965200
);
}
public function isFrozen() {
return $this->frozen;
}
/**
* Returns the directory where the cache files are stored
* Sets a reference to the cache frontend which uses this backend and
* initializes the default cache directory.
*
* @return string Full path of the cache directory
* @api
* This method also detects if this backend is frozen and sets the internal
* flag accordingly.
*
* TYPO3 v4 note: This method is different between TYPO3 v4 and FLOW3
* because the Environment class to get the path to a temporary directory
* does not exist in v4.
*
* @param t3lib_cache_frontend_Frontend $cache The cache frontend
* @return void
*/
public function getCacheDirectory() {
return $this->cacheDirectory;
public function setCache(t3lib_cache_frontend_Frontend $cache) {
parent::setCache($cache);
if (file_exists($this->cacheDirectory . 'FrozenCache.data')) {
$this->frozen = TRUE;
if ($this->useIgBinary === TRUE) {
$this->cacheEntryIdentifiers = igbinary_unserialize(file_get_contents($this->cacheDirectory . 'FrozenCache.data'));
} else {
$this->cacheEntryIdentifiers = unserialize(file_get_contents($this->cacheDirectory . 'FrozenCache.data'));
}
}
}
/**
......@@ -232,13 +148,15 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
* @param array $tags Tags to associate with this cache entry
* @param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited lifetime.
* @return void
* @throws t3lib_cache_Exception if the directory does not exist or is not writable or exceeds the maximum allowed path length, or if no cache frontend has been set.
* @throws t3lib_cache_exception_InvalidData if the data to bes stored is not a string.
* @throws \RuntimeException
* @throws \t3lib_cache_Exception_InvalidData if the directory does not exist or is not writable or exceeds the maximum allowed path length, or if no cache frontend has been set.
* @throws \t3lib_cache_Exception if the directory does not exist or is not writable or exceeds the maximum allowed path length, or if no cache frontend has been set.
* @throws \InvalidArgumentException
* @api
*/
public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
if (!is_string($data)) {
throw new t3lib_cache_Exception_InvalidData(
throw new \t3lib_cache_Exception_InvalidData(
'The specified data is of type "' . gettype($data) . '" but a string is expected.',
1204481674
);
......@@ -250,33 +168,30 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
1282073032
);
}
if ($entryIdentifier === '') {
throw new \InvalidArgumentException(
'The specified entry identifier must not be empty.',
1298114280
);
}
if ($this->frozen === TRUE) {
throw new \RuntimeException(
sprintf('Cannot add or modify cache entry because the backend of cache "%s" is frozen.', $this->cacheIdentifier),
1323344192
);
}
$this->remove($entryIdentifier);
$temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid() . '.temp';
if (strlen($temporaryCacheEntryPathAndFilename) > t3lib_div::getMaximumPathLength()) {
throw new t3lib_cache_Exception(
'The length of the temporary cache file path "' . $temporaryCacheEntryPathAndFilename .
'" is ' . strlen($temporaryCacheEntryPathAndFilename) . ' characters long and exceeds the maximum path length of ' .
t3lib_div::getMaximumPathLength() . '. Please consider setting the temporaryDirectoryBase option to a shorter path. ',
1248710426
);
}
$expiryTime = ($lifetime === NULL) ? 0 : ($GLOBALS['EXEC_TIME'] + $lifetime);
$lifetime = $lifetime === NULL ? $this->defaultLifetime : $lifetime;
$expiryTime = ($lifetime === 0) ? 0 : ($GLOBALS['EXEC_TIME'] + $lifetime);
$metaData = str_pad($expiryTime, self::EXPIRYTIME_LENGTH) . implode(' ', $tags) . str_pad(strlen($data), self::DATASIZE_DIGITS);
$result = file_put_contents($temporaryCacheEntryPathAndFilename, $data . $metaData);
t3lib_div::fixPermissions($temporaryCacheEntryPathAndFilename);
if ($result === FALSE) {
throw new t3lib_cache_exception(
throw new \t3lib_cache_exception(
'The temporary cache file "' . $temporaryCacheEntryPathAndFilename . '" could not be written.',
1204026251
);
......@@ -284,14 +199,12 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
$i = 0;
$cacheEntryPathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
// @TODO: Figure out why the heck this is done and maybe find a smarter solution, report to FLOW3
while (!rename($temporaryCacheEntryPathAndFilename, $cacheEntryPathAndFilename) && $i < 5) {
while (($result = rename($temporaryCacheEntryPathAndFilename, $cacheEntryPathAndFilename)) === FALSE && $i < 5) {
$i++;
}
// @FIXME: At least the result of rename() should be handled here, report to FLOW3
if ($result === FALSE) {
throw new t3lib_cache_exception(
throw new \t3lib_cache_exception(
'The cache file "' . $cacheEntryPathAndFilename . '" could not be written.',
1222361632
);
......@@ -307,6 +220,10 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
* @api
*/
public function get($entryIdentifier) {
if ($this->frozen === TRUE) {
return (isset($this->cacheEntryIdentifiers[$entryIdentifier]) ? file_get_contents($this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension) : FALSE);
}
if ($entryIdentifier !== basename($entryIdentifier)) {
throw new \InvalidArgumentException(
'The specified entry identifier must not contain a path segment.',
......@@ -327,9 +244,13 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
*
* @param string $entryIdentifier
* @return boolean TRUE if such an entry exists, FALSE if not
* @throws \InvalidArgumentException
* @api
*/
public function has($entryIdentifier) {
if ($this->frozen === TRUE) {
return isset($this->cacheEntryIdentifiers[$entryIdentifier]);
}
if ($entryIdentifier !== basename($entryIdentifier)) {
throw new \InvalidArgumentException(
'The specified entry identifier must not contain a path segment.',
......@@ -346,6 +267,8 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
*
* @param string $entryIdentifier Specifies the cache entry to remove
* @return boolean TRUE if (at least) an entry could be removed or FALSE if no entry was found
* @throws \RuntimeException
* @throws \InvalidArgumentException
* @api
*/
public function remove($entryIdentifier) {
......@@ -361,6 +284,12 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
1298114279
);
}
if ($this->frozen === TRUE) {
throw new \RuntimeException(
sprintf('Cannot remove cache entry because the backend of cache "%s" is frozen.', $this->cacheIdentifier),
1323344193
);