TYPO3 CMS  TYPO3_6-2
SimpleFileBackend.php
Go to the documentation of this file.
1 <?php
3 
4 /* *
5  * This script belongs to the FLOW3 framework. *
6  * *
7  * It is free software; you can redistribute it and/or modify it under *
8  * the terms of the GNU Lesser General Public License, either version 3 *
9  * of the License, or (at your option) any later version. *
10  * *
11  * The TYPO3 project - inspiring people to share! *
12  * */
20 
21  const SEPARATOR = '^';
22  const EXPIRYTIME_FORMAT = 'YmdHis';
23  const EXPIRYTIME_LENGTH = 14;
24  const DATASIZE_DIGITS = 10;
30  protected $cacheDirectory = '';
31 
41  protected $temporaryCacheDirectory = '';
42 
48  protected $cacheEntryFileExtension = '';
49 
53  protected $cacheEntryIdentifiers = array();
54 
58  protected $frozen = FALSE;
59 
66  protected $useIgBinary = FALSE;
67 
73  public function initializeObject() {
74  $this->useIgBinary = extension_loaded('igbinary');
75  }
76 
89  public function setCache(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache) {
90  parent::setCache($cache);
91  if (empty($this->temporaryCacheDirectory)) {
92  // If no cache directory was given with cacheDirectory
93  // configuration option, set it to a path below typo3temp/
94  $temporaryCacheDirectory = PATH_site . 'typo3temp/';
95  } else {
97  }
98  $codeOrData = $cache instanceof \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend ? 'Code' : 'Data';
99  $finalCacheDirectory = $temporaryCacheDirectory . 'Cache/' . $codeOrData . '/' . $this->cacheIdentifier . '/';
100  if (!is_dir($finalCacheDirectory)) {
101  $this->createFinalCacheDirectory($finalCacheDirectory);
102  }
103  unset($this->temporaryCacheDirectory);
104  $this->cacheDirectory = $finalCacheDirectory;
105  $this->cacheEntryFileExtension = $cache instanceof \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend ? '.php' : '';
106  if (strlen($this->cacheDirectory) + 23 > \TYPO3\CMS\Core\Utility\GeneralUtility::getMaximumPathLength()) {
107  throw new \TYPO3\CMS\Core\Cache\Exception('The length of the temporary cache file path "' . $this->cacheDirectory . '" exceeds the ' . 'maximum path length of ' . (\TYPO3\CMS\Core\Utility\GeneralUtility::getMaximumPathLength() - 23) . '. Please consider ' . 'setting the temporaryDirectoryBase option to a shorter path.', 1248710426);
108  }
109  }
110 
127  // Skip handling if directory is a stream ressource
128  // This is used by unit tests with vfs:// directoryies
129  if (strpos($cacheDirectory, '://')) {
130  $this->temporaryCacheDirectory = $cacheDirectory;
131  return;
132  }
133  $documentRoot = PATH_site;
134  if ($open_basedir = ini_get('open_basedir')) {
135  if (TYPO3_OS === 'WIN') {
136  $delimiter = ';';
137  $cacheDirectory = str_replace('\\', '/', $cacheDirectory);
138  if (!preg_match('/[A-Z]:/', substr($cacheDirectory, 0, 2))) {
139  $cacheDirectory = PATH_site . $cacheDirectory;
140  }
141  } else {
142  $delimiter = ':';
143  if ($cacheDirectory[0] != '/') {
144  // relative path to cache directory.
145  $cacheDirectory = PATH_site . $cacheDirectory;
146  }
147  }
148  $basedirs = explode($delimiter, $open_basedir);
149  $cacheDirectoryInBaseDir = FALSE;
150  foreach ($basedirs as $basedir) {
151  if (TYPO3_OS === 'WIN') {
152  $basedir = str_replace('\\', '/', $basedir);
153  }
154  if ($basedir[strlen($basedir) - 1] !== '/') {
155  $basedir .= '/';
156  }
157  if (\TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($cacheDirectory, $basedir)) {
158  $documentRoot = $basedir;
159  $cacheDirectory = str_replace($basedir, '', $cacheDirectory);
160  $cacheDirectoryInBaseDir = TRUE;
161  break;
162  }
163  }
164  if (!$cacheDirectoryInBaseDir) {
165  throw new \TYPO3\CMS\Core\Cache\Exception('Open_basedir restriction in effect. The directory "' . $cacheDirectory . '" is not in an allowed path.');
166  }
167  } else {
168  if ($cacheDirectory[0] == '/') {
169  // Absolute path to cache directory.
170  $documentRoot = '';
171  }
172  if (TYPO3_OS === 'WIN') {
173  if (substr($cacheDirectory, 0, strlen($documentRoot)) === $documentRoot) {
174  $documentRoot = '';
175  }
176  }
177  }
178  // After this point all paths have '/' as directory seperator
179  if ($cacheDirectory[strlen($cacheDirectory) - 1] !== '/') {
180  $cacheDirectory .= '/';
181  }
182  $this->temporaryCacheDirectory = $documentRoot . $cacheDirectory . $this->cacheIdentifier . '/';
183  }
184 
193  protected function createFinalCacheDirectory($finalCacheDirectory) {
194  try {
196  } catch (\RuntimeException $e) {
197  throw new \TYPO3\CMS\Core\Cache\Exception('The directory "' . $finalCacheDirectory . '" can not be created.', 1303669848, $e);
198  }
199  if (!is_writable($finalCacheDirectory)) {
200  throw new \TYPO3\CMS\Core\Cache\Exception('The directory "' . $finalCacheDirectory . '" is not writable.', 1203965200);
201  }
202  }
203 
210  public function getCacheDirectory() {
211  return $this->cacheDirectory;
212  }
213 
227  public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
228  if (!is_string($data)) {
229  throw new \TYPO3\CMS\Core\Cache\Exception\InvalidDataException('The specified data is of type "' . gettype($data) . '" but a string is expected.', 1334756734);
230  }
231  if ($entryIdentifier !== basename($entryIdentifier)) {
232  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1334756735);
233  }
234  if ($entryIdentifier === '') {
235  throw new \InvalidArgumentException('The specified entry identifier must not be empty.', 1334756736);
236  }
237  $temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid('', TRUE) . '.temp';
238  $result = file_put_contents($temporaryCacheEntryPathAndFilename, $data);
239  \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($temporaryCacheEntryPathAndFilename);
240  if ($result === FALSE) {
241  throw new \TYPO3\CMS\Core\Cache\Exception('The temporary cache file "' . $temporaryCacheEntryPathAndFilename . '" could not be written.', 1334756737);
242  }
243  $cacheEntryPathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
244  rename($temporaryCacheEntryPathAndFilename, $cacheEntryPathAndFilename);
245  if ($this->cacheEntryFileExtension === '.php') {
247  }
248  }
249 
258  public function get($entryIdentifier) {
259  if ($entryIdentifier !== basename($entryIdentifier)) {
260  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1334756877);
261  }
262  $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
263  if (!file_exists($pathAndFilename)) {
264  return FALSE;
265  }
266  return file_get_contents($pathAndFilename);
267  }
268 
277  public function has($entryIdentifier) {
278  if ($entryIdentifier !== basename($entryIdentifier)) {
279  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1334756878);
280  }
281  return file_exists($this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension);
282  }
283 
293  public function remove($entryIdentifier) {
294  if ($entryIdentifier !== basename($entryIdentifier)) {
295  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1334756960);
296  }
297  if ($entryIdentifier === '') {
298  throw new \InvalidArgumentException('The specified entry identifier must not be empty.', 1334756961);
299  }
300  try {
301  unlink($this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension);
302  } catch (\Exception $e) {
303  return FALSE;
304  }
305  return TRUE;
306  }
307 
314  public function flush() {
315  \TYPO3\CMS\Core\Utility\GeneralUtility::flushDirectory($this->cacheDirectory, TRUE);
316  }
317 
326  protected function isCacheFileExpired($cacheEntryPathAndFilename) {
327  return file_exists($cacheEntryPathAndFilename) === FALSE;
328  }
329 
336  public function collectGarbage() {
337 
338  }
339 
346  protected function findCacheFilesByIdentifier($entryIdentifier) {
347  $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
348  return file_exists($pathAndFilename) ? array($pathAndFilename) : FALSE;
349  }
350 
359  public function requireOnce($entryIdentifier) {
360  $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
361  if ($entryIdentifier !== basename($entryIdentifier)) {
362  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1282073037);
363  }
364  return file_exists($pathAndFilename) ? require_once $pathAndFilename : FALSE;
365  }
366 
367 }
static mkdir_deep($directory, $deepDirectory='')
static isFirstPartOfStr($str, $partStr)
static fixPermissions($path, $recursive=FALSE)
static flushDirectory($directory, $keepOriginalDirectory=FALSE, $flushOpcodeCache=FALSE)
setCache(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache)
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren&#39;t numeric.