[BUGFIX] Cache FileBackend does not respect fileCreateMask
[Packages/TYPO3.CMS.git] / t3lib / cache / backend / class.t3lib_cache_backend_filebackend.php
index cf95d0a..578136e 100644 (file)
@@ -1,27 +1,26 @@
 <?php
 /***************************************************************
-*  Copyright notice
-*
-*  (c) 2009-2010 Ingo Renner <ingo@typo3.org>
-*  All rights reserved
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
+ *  Copyright notice
+ *
+ *  (c) 2009-2011 Ingo Renner <ingo@typo3.org>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
 
 /**
  * A caching backend which stores cache entries in files
@@ -31,7 +30,7 @@
  * @package TYPO3
  * @subpackage t3lib_cache
  * @api
- * @version $Id$
+ * @scope prototype
  */
 class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBackend implements t3lib_cache_backend_PhpCapableBackend {
 
@@ -43,52 +42,64 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
        const DATASIZE_DIGITS = 10;
 
        /**
-        * @var string Directory where the files are stored
+        * Directory where the files are stored
+        *
+        * @var string
         */
        protected $cacheDirectory = '';
 
        /**
-        * @var string Absolute path to root, usually document root of website
-        */
-       protected $root = '/';
-
-       /**
-        * Maximum allowed file path length in the current environment.
+        * 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 integer
+        * @var string Temporary path to cache directory
         */
-       protected $maximumPathLength = null;
+       protected $temporaryCacheDirectory = '';
 
        /**
-        * Constructs this backend
+        * A file extension to use for each cache entry.
         *
-        * @param mixed Configuration options - depends on the actual backend
+        * @var string
         */
-       public function __construct(array $options = array()) {
-               parent::__construct($options);
+       protected $cacheEntryFileExtension = '';
 
-               if (is_null($this->maximumPathLength)) {
-                       $this->maximumPathLength = t3lib_div::getMaximumPathLength();
-               }
-       }
 
        /**
         * Sets a reference to the cache frontend which uses this backend and
-        * initializes the default cache directory
+        * initializes the default cache directory.
+        *
+        * 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.
         *
-        * @void
+        * @param t3lib_cache_frontend_Frontend $cache The cache frontend
+        * @return void
         * @author Robert Lemke <robert@typo3.org>
         */
        public function setCache(t3lib_cache_frontend_Frontend $cache) {
                parent::setCache($cache);
 
-               if (empty($this->cacheDirectory)) {
-                       $cacheDirectory = 'typo3temp/cache/';
-                       try {
-                               $this->setCacheDirectory($cacheDirectory);
-                       } catch(t3lib_cache_Exception $exception) {
-                       }
+               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' : '';
        }
 
        /**
@@ -96,20 +107,35 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         * assumed that the directory is below the TYPO3_DOCUMENT_ROOT. However, an
         * absolute path can be selected, too.
         *
-        * @param string The directory. If a relative path is given, it's assumed it's in TYPO3_DOCUMENT_ROOT. If an absolute path is given it is taken as is.
+        * 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.
+        *
+        * @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 does not exist, is not writable or could not be created.
-        * @author Robert Lemke <robert@typo3.org>
-        * @author Ingo Renner <ingo@typo3.org>
+        * @throws t3lib_cache_Exception if the directory is not within allowed
+        *              open_basedir path.
+        * @author Christian Kuhn <lolli@schwarzbu.ch>
         */
        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;
+               }
+
                $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)))) {
+                               if (!(preg_match('/[A-Z]:/', substr($cacheDirectory, 0, 2)))) {
                                        $cacheDirectory = PATH_site . $cacheDirectory;
                                }
                        } else {
@@ -147,7 +173,9 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
                                $documentRoot = '/';
                        }
                        if (TYPO3_OS === 'WIN') {
-                               $documentRoot = '';
+                               if (substr($cacheDirectory, 0,  strlen($documentRoot)) === $documentRoot) {
+                                       $documentRoot = '';
+                               }
                        }
                }
 
@@ -155,32 +183,34 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
                if ($cacheDirectory[strlen($cacheDirectory) - 1] !== '/') {
                        $cacheDirectory .= '/';
                }
-               $cacheDirectory .= $this->cacheIdentifier;
-               if ($cacheDirectory[strlen($cacheDirectory) - 1] !== '/') {
-                       $cacheDirectory .= '/';
-               }
 
-               if (!is_writable($documentRoot . $cacheDirectory)) {
-                       t3lib_div::mkdir_deep(
-                               $documentRoot,
-                               $cacheDirectory
-                       );
-               }
-               if (!is_dir($documentRoot . $cacheDirectory)) {
-                       throw new t3lib_cache_Exception(
-                               'The directory "' . $documentRoot . $cacheDirectory . '" does not exist.',
-                               1203965199
+               $this->temporaryCacheDirectory = $documentRoot . $cacheDirectory . $this->cacheIdentifier . '/';
+       }
+
+       /**
+        * Create the final cache directory if it does not exist. This method
+        * exists in TYPO3 v4 only.
+        *
+        * @param string $finalCacheDirectory Absolute path to final cache directory
+        * @return void
+        * @throws \t3lib_cache_Exception If directory is not writable after creation
+        */
+       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($documentRoot . $cacheDirectory)) {
-                       throw new t3lib_cache_Exception(
-                               'The directory "' . $documentRoot . $cacheDirectory . '" is not writable.',
+               if (!is_writable($finalCacheDirectory)) {
+                       throw new \t3lib_cache_Exception(
+                               'The directory "' . $finalCacheDirectory . '" is not writable.',
                                1203965200
                        );
                }
-
-               $this->root = $documentRoot;
-               $this->cacheDirectory =  $cacheDirectory;
        }
 
        /**
@@ -191,7 +221,7 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         * @api
         */
        public function getCacheDirectory() {
-               return $this->root . $this->cacheDirectory;
+               return $this->cacheDirectory;
        }
 
        /**
@@ -208,13 +238,6 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         * @api
         */
        public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
-               if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
-                       throw new t3lib_cache_Exception(
-                               'No cache frontend has been set yet via setCache().',
-                               1204111375
-                       );
-               }
-
                if (!is_string($data)) {
                        throw new t3lib_cache_Exception_InvalidData(
                                'The specified data is of type "' . gettype($data) . '" but a string is expected.',
@@ -223,20 +246,27 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
                }
 
                if ($entryIdentifier !== basename($entryIdentifier)) {
-                       throw new InvalidArgumentException(
+                       throw new \InvalidArgumentException(
                                'The specified entry identifier must not contain a path segment.',
                                1282073032
                        );
                }
 
+               if ($entryIdentifier === '') {
+                       throw new \InvalidArgumentException(
+                               'The specified entry identifier must not be empty.',
+                               1298114280
+                       );
+               }
+
                $this->remove($entryIdentifier);
 
-               $temporaryCacheEntryPathAndFilename = $this->root . $this->cacheDirectory . uniqid() . '.temp';
-               if (strlen($temporaryCacheEntryPathAndFilename) > $this->maximumPathLength) {
+               $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 ' .
-                                       $this->maximumPathLength . '. Please consider setting the temporaryDirectoryBase option to a shorter path. ',
+                               '" 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
                        );
                }
@@ -244,6 +274,7 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
                $expiryTime = ($lifetime === NULL) ? 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(
@@ -253,7 +284,7 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
                }
 
                $i = 0;
-               $cacheEntryPathAndFilename = $this->root . $this->cacheDirectory . $entryIdentifier;
+               $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) {
                        $i++;
@@ -273,43 +304,44 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         *
         * @param string $entryIdentifier An identifier which describes the cache entry to load
         * @return mixed The cache entry's content as a string or FALSE if the cache entry could not be loaded
+        * @throws \InvalidArgumentException If identifier is invalid
         * @author Robert Lemke <robert@typo3.org>
         * @author Karsten Dambekalns <karsten@typo3.org>
         * @api
         */
        public function get($entryIdentifier) {
                if ($entryIdentifier !== basename($entryIdentifier)) {
-                       throw new InvalidArgumentException(
+                       throw new \InvalidArgumentException(
                                'The specified entry identifier must not contain a path segment.',
                                1282073033
                        );
                }
 
-               $pathAndFilename = $this->root . $this->cacheDirectory . $entryIdentifier;
+               $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
                if ($this->isCacheFileExpired($pathAndFilename)) {
                        return FALSE;
                }
-               $dataSize = (integer)file_get_contents($pathAndFilename, NULL, NULL, filesize($pathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
+               $dataSize = (integer) file_get_contents($pathAndFilename, NULL, NULL, filesize($pathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
                return file_get_contents($pathAndFilename, NULL, NULL, 0, $dataSize);
        }
 
        /**
         * Checks if a cache entry with the specified identifier exists.
         *
-        * @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
+        * @param string $entryIdentifier
+        * @return boolean TRUE if such an entry exists, FALSE if not
         * @author Robert Lemke <robert@typo3.org>
         * @api
         */
        public function has($entryIdentifier) {
                if ($entryIdentifier !== basename($entryIdentifier)) {
-                       throw new InvalidArgumentException(
+                       throw new \InvalidArgumentException(
                                'The specified entry identifier must not contain a path segment.',
                                1282073034
                        );
                }
 
-               return !$this->isCacheFileExpired($this->root . $this->cacheDirectory . $entryIdentifier);
+               return !$this->isCacheFileExpired($this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension);
        }
 
        /**
@@ -323,14 +355,20 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         */
        public function remove($entryIdentifier) {
                if ($entryIdentifier !== basename($entryIdentifier)) {
-                       throw new InvalidArgumentException(
+                       throw new \InvalidArgumentException(
                                'The specified entry identifier must not contain a path segment.',
                                1282073035
                        );
                }
+               if ($entryIdentifier === '') {
+                       throw new \InvalidArgumentException(
+                               'The specified entry identifier must not be empty.',
+                               1298114279
+                       );
+               }
 
-               $pathAndFilename = $this->root . $this->cacheDirectory . $entryIdentifier;
-               if (!file_exists($pathAndFilename)) {
+               $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
+               if (file_exists($pathAndFilename) === FALSE) {
                        return FALSE;
                }
                if (unlink($pathAndFilename) === FALSE) {
@@ -346,57 +384,30 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         * @param string $searchedTag The tag to search for
         * @return array An array with identifiers of all matching entries. An empty array if no entries matched
         * @author Robert Lemke <robert@typo3.org>
-        * @author Karsten Dambekalns <karsten@typo3.org>
         * @api
         */
        public function findIdentifiersByTag($searchedTag) {
                $entryIdentifiers = array();
                $now = $GLOBALS['EXEC_TIME'];
-               for ($directoryIterator = t3lib_div::makeInstance('DirectoryIterator', $this->root . $this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
+               $cacheEntryFileExtensionLength = strlen($this->cacheEntryFileExtension);
+               for ($directoryIterator = t3lib_div::makeInstance('DirectoryIterator', $this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
                        if ($directoryIterator->isDot()) {
                                continue;
                        }
                        $cacheEntryPathAndFilename = $directoryIterator->getPathname();
-                       $index = (integer)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
+                       $index = (integer) file_get_contents($cacheEntryPathAndFilename, NULL, NULL, filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
                        $metaData = file_get_contents($cacheEntryPathAndFilename, NULL, NULL, $index);
 
-                       $expiryTime = (integer)substr($metaData, 0, self::EXPIRYTIME_LENGTH);
+                       $expiryTime = (integer) substr($metaData, 0, self::EXPIRYTIME_LENGTH);
                        if ($expiryTime !== 0 && $expiryTime < $now) {
                                continue;
                        }
                        if (in_array($searchedTag, explode(' ', substr($metaData, self::EXPIRYTIME_LENGTH, -self::DATASIZE_DIGITS)))) {
-                               $entryIdentifiers[] = $directoryIterator->getFilename();
-                       }
-               }
-               return $entryIdentifiers;
-       }
-
-       /**
-        * Finds and returns all cache entry identifiers which are tagged by the
-        * specified tags.
-        *
-        * @param array $searchedTags Array of tags to search for
-        * @return array An array with identifiers of all matching entries. An empty array if no entries matched
-        * @author Ingo Renner <ingo@typo3.org>
-        * @author Christian Kuhn <lolli@schwarzbu.ch>
-        * @api
-        */
-       public function findIdentifiersByTags(array $searchedTags) {
-               $entryIdentifiers = array();
-               for ($directoryIterator = t3lib_div::makeInstance('DirectoryIterator', $this->root . $this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
-                       if ($directoryIterator->isDot()) {
-                               continue;
-                       }
-                       $cacheEntryPathAndFilename = $directoryIterator->getPathname();
-                       $index = (integer)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
-                       $metaData = file_get_contents($cacheEntryPathAndFilename, NULL, NULL, $index);
-
-                       $expiryTime = (integer)substr($metaData, 0, self::EXPIRYTIME_LENGTH);
-                       if ($expiryTime !== 0 && $expiryTime < $GLOBALS['EXEC_TIME']) {
-                               continue;
-                       }
-                       if (in_array($searchedTags, explode(' ', substr($metaData, self::EXPIRYTIME_LENGTH, -self::DATASIZE_DIGITS)))) {
-                               $entryIdentifiers[] = $directoryIterator->getFilename();
+                               if ($cacheEntryFileExtensionLength > 0) {
+                                       $entryIdentifiers[] = substr($directoryIterator->getFilename(), 0, - $cacheEntryFileExtensionLength);
+                               } else {
+                                       $entryIdentifiers[] = $directoryIterator->getFilename();
+                               }
                        }
                }
                return $entryIdentifiers;
@@ -411,7 +422,8 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         * @api
         */
        public function flush() {
-               t3lib_div::rmdir($this->root . $this->cacheDirectory, TRUE);
+               t3lib_div::rmdir($this->cacheDirectory, TRUE);
+               $this->createFinalCacheDirectory($this->cacheDirectory);
        }
 
        /**
@@ -419,6 +431,7 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         *
         * @param string $tag The tag the entries must have
         * @return void
+        * @author Robert Lemke <robert@typo3.org>
         * @author Ingo Renner <ingo@typo3.org>
         * @api
         */
@@ -433,20 +446,6 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
                }
        }
 
-       /**
-        * Removes all cache entries of this cache which are tagged by the specified tag.
-        *
-        * @param array $tags The tags the entries must have
-        * @return void
-        * @author Ingo Renner <ingo@typo3.org>
-        * @api
-        */
-       public function flushByTags(array $tags) {
-               foreach ($tags as $tag) {
-                       $this->flushByTag($tag);
-               }
-       }
-
        /**
         * Checks if the given cache entry files are still valid or if their
         * lifetime has exceeded.
@@ -454,12 +453,13 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         * @param string $cacheEntryPathAndFilename
         * @return boolean
         * @author Robert Lemke <robert@typo3.org>
+        * @api
         */
        protected function isCacheFileExpired($cacheEntryPathAndFilename) {
-               if (!file_exists($cacheEntryPathAndFilename)) {
+               if (file_exists($cacheEntryPathAndFilename) === FALSE) {
                        return TRUE;
                }
-               $index = (integer)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
+               $index = (integer) file_get_contents($cacheEntryPathAndFilename, NULL, NULL, filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
                $expiryTime = file_get_contents($cacheEntryPathAndFilename, NULL, NULL, $index, self::EXPIRYTIME_LENGTH);
                return ($expiryTime != 0 && $expiryTime < $GLOBALS['EXEC_TIME']);
        }
@@ -472,22 +472,19 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         * @api
         */
        public function collectGarbage() {
-               if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
-                       throw new t3lib_cache_Exception(
-                               'Yet no cache frontend has been set via setCache().',
-                               1222686150
-                       );
-               }
-
-               $pattern = $this->root . $this->cacheDirectory . '*';
-               $filesFound = glob($pattern);
+               for ($directoryIterator = new \DirectoryIterator($this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
+                       if ($directoryIterator->isDot()) {
+                               continue;
+                       }
 
-               if (is_array($filesFound)) {
-                       foreach ($filesFound as $cacheFilename) {
-                               if ($this->isCacheFileExpired($cacheFilename)) {
-                                       $this->remove(basename($cacheFilename));
-                               }
-                       }
+                       if ($this->isCacheFileExpired($directoryIterator->getPathname())) {
+                               $cacheEntryFileExtensionLength = strlen($this->cacheEntryFileExtension);
+                               if ($cacheEntryFileExtensionLength > 0) {
+                                       $this->remove(substr($directoryIterator->getFilename(), 0, - $cacheEntryFileExtensionLength));
+                               } else {
+                                       $this->remove($directoryIterator->getFilename());
+                               }
+                       }
                }
        }
 
@@ -499,18 +496,10 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         * @param string $entryIdentifier The cache entry identifier
         * @return mixed The file names (including path) as an array if one or more entries could be found, otherwise FALSE
         * @author Robert Lemke <robert@typo3.org>
-        * @throws t3lib_cache_Exception if no frontend has been set
         * @internal
         */
        protected function findCacheFilesByIdentifier($entryIdentifier) {
-               if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
-                       throw new t3lib_cache_Exception(
-                               'Yet no cache frontend has been set via setCache().',
-                               1204111376
-                       );
-               }
-
-               $pattern = $this->root . $this->cacheDirectory . $entryIdentifier;
+               $pattern = $this->cacheDirectory . $entryIdentifier;
                $filesFound = glob($pattern);
                if ($filesFound === FALSE || count($filesFound) === 0) {
                        return FALSE;
@@ -528,20 +517,14 @@ class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBacken
         */
        public function requireOnce($entryIdentifier) {
                if ($entryIdentifier !== basename($entryIdentifier)) {
-                       throw new InvalidArgumentException(
+                       throw new \InvalidArgumentException(
                                'The specified entry identifier must not contain a path segment.',
                                1282073036
                        );
                }
 
-               $pathAndFilename = $this->root . $this->cacheDirectory . $entryIdentifier;
+               $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
                return ($this->isCacheFileExpired($pathAndFilename)) ? FALSE : require_once($pathAndFilename);
        }
 }
-
-
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/cache/backend/class.t3lib_cache_backend_filebackend.php'])  {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/cache/backend/class.t3lib_cache_backend_filebackend.php']);
-}
-
 ?>
\ No newline at end of file