TYPO3 CMS  TYPO3_6-2
FileBackend.php
Go to the documentation of this file.
1 <?php
3 
27 
28  const SEPARATOR = '^';
29  const EXPIRYTIME_FORMAT = 'YmdHis';
30  const EXPIRYTIME_LENGTH = 14;
31  const DATASIZE_DIGITS = 10;
37  protected $cacheEntryFileExtension = '';
38 
42  protected $cacheEntryIdentifiers = array();
43 
47  protected $frozen = FALSE;
48 
62  public function freeze() {
63  if ($this->frozen === TRUE) {
64  throw new \RuntimeException(sprintf('The cache "%s" is already frozen.', $this->cacheIdentifier), 1323353176);
65  }
66  $cacheEntryFileExtensionLength = strlen($this->cacheEntryFileExtension);
67  for ($directoryIterator = new \DirectoryIterator($this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
68  if ($directoryIterator->isDot()) {
69  continue;
70  }
71  if ($cacheEntryFileExtensionLength > 0) {
72  $entryIdentifier = substr($directoryIterator->getFilename(), 0, -$cacheEntryFileExtensionLength);
73  } else {
74  $entryIdentifier = $directoryIterator->getFilename();
75  }
76  $this->cacheEntryIdentifiers[$entryIdentifier] = TRUE;
77  file_put_contents($this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension, $this->get($entryIdentifier));
78  }
79  if ($this->useIgBinary === TRUE) {
80  file_put_contents($this->cacheDirectory . 'FrozenCache.data', igbinary_serialize($this->cacheEntryIdentifiers));
81  } else {
82  file_put_contents($this->cacheDirectory . 'FrozenCache.data', serialize($this->cacheEntryIdentifiers));
83  }
84  $this->frozen = TRUE;
85  }
86 
92  public function isFrozen() {
93  return $this->frozen;
94  }
95 
110  public function setCache(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache) {
111  parent::setCache($cache);
112  if (file_exists($this->cacheDirectory . 'FrozenCache.data')) {
113  $this->frozen = TRUE;
114  if ($this->useIgBinary === TRUE) {
115  $this->cacheEntryIdentifiers = igbinary_unserialize(file_get_contents($this->cacheDirectory . 'FrozenCache.data'));
116  } else {
117  $this->cacheEntryIdentifiers = unserialize(file_get_contents($this->cacheDirectory . 'FrozenCache.data'));
118  }
119  }
120  }
121 
136  public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
137  if (!is_string($data)) {
138  throw new \TYPO3\CMS\Core\Cache\Exception\InvalidDataException('The specified data is of type "' . gettype($data) . '" but a string is expected.', 1204481674);
139  }
140  if ($entryIdentifier !== basename($entryIdentifier)) {
141  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1282073032);
142  }
143  if ($entryIdentifier === '') {
144  throw new \InvalidArgumentException('The specified entry identifier must not be empty.', 1298114280);
145  }
146  if ($this->frozen === TRUE) {
147  throw new \RuntimeException(sprintf('Cannot add or modify cache entry because the backend of cache "%s" is frozen.', $this->cacheIdentifier), 1323344192);
148  }
149  $this->remove($entryIdentifier);
150  $temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid('', TRUE) . '.temp';
151  $lifetime = $lifetime === NULL ? $this->defaultLifetime : $lifetime;
152  $expiryTime = $lifetime === 0 ? 0 : $GLOBALS['EXEC_TIME'] + $lifetime;
153  $metaData = str_pad($expiryTime, self::EXPIRYTIME_LENGTH) . implode(' ', $tags) . str_pad(strlen($data), self::DATASIZE_DIGITS);
154  $result = file_put_contents($temporaryCacheEntryPathAndFilename, $data . $metaData);
155  \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($temporaryCacheEntryPathAndFilename);
156  if ($result === FALSE) {
157  throw new \TYPO3\CMS\Core\Cache\Exception('The temporary cache file "' . $temporaryCacheEntryPathAndFilename . '" could not be written.', 1204026251);
158  }
159  $i = 0;
160  $cacheEntryPathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
161  while (($result = rename($temporaryCacheEntryPathAndFilename, $cacheEntryPathAndFilename)) === FALSE && $i < 5) {
162  $i++;
163  }
164  if ($result === FALSE) {
165  throw new \TYPO3\CMS\Core\Cache\Exception('The cache file "' . $cacheEntryPathAndFilename . '" could not be written.', 1222361632);
166  }
167  if ($this->cacheEntryFileExtension === '.php') {
169  }
170  }
171 
180  public function get($entryIdentifier) {
181  if ($this->frozen === TRUE) {
182  return isset($this->cacheEntryIdentifiers[$entryIdentifier]) ? file_get_contents($this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension) : FALSE;
183  }
184  if ($entryIdentifier !== basename($entryIdentifier)) {
185  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1282073033);
186  }
187  $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
188  if ($this->isCacheFileExpired($pathAndFilename)) {
189  return FALSE;
190  }
191  $dataSize = (int)file_get_contents($pathAndFilename, NULL, NULL, (filesize($pathAndFilename) - self::DATASIZE_DIGITS), self::DATASIZE_DIGITS);
192  return file_get_contents($pathAndFilename, NULL, NULL, 0, $dataSize);
193  }
194 
203  public function has($entryIdentifier) {
204  if ($this->frozen === TRUE) {
205  return isset($this->cacheEntryIdentifiers[$entryIdentifier]);
206  }
207  if ($entryIdentifier !== basename($entryIdentifier)) {
208  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1282073034);
209  }
210  return !$this->isCacheFileExpired(($this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension));
211  }
212 
223  public function remove($entryIdentifier) {
224  if ($entryIdentifier !== basename($entryIdentifier)) {
225  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1282073035);
226  }
227  if ($entryIdentifier === '') {
228  throw new \InvalidArgumentException('The specified entry identifier must not be empty.', 1298114279);
229  }
230  if ($this->frozen === TRUE) {
231  throw new \RuntimeException(sprintf('Cannot remove cache entry because the backend of cache "%s" is frozen.', $this->cacheIdentifier), 1323344193);
232  }
233  $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
234  if (file_exists($pathAndFilename) === FALSE) {
235  return FALSE;
236  }
237  if (unlink($pathAndFilename) === FALSE) {
238  return FALSE;
239  }
240  return TRUE;
241  }
242 
251  public function findIdentifiersByTag($searchedTag) {
252  $entryIdentifiers = array();
253  $now = $GLOBALS['EXEC_TIME'];
254  $cacheEntryFileExtensionLength = strlen($this->cacheEntryFileExtension);
255  for ($directoryIterator = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('DirectoryIterator', $this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
256  if ($directoryIterator->isDot()) {
257  continue;
258  }
259  $cacheEntryPathAndFilename = $directoryIterator->getPathname();
260  $index = (int)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, (filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS), self::DATASIZE_DIGITS);
261  $metaData = file_get_contents($cacheEntryPathAndFilename, NULL, NULL, $index);
262  $expiryTime = (int)substr($metaData, 0, self::EXPIRYTIME_LENGTH);
263  if ($expiryTime !== 0 && $expiryTime < $now) {
264  continue;
265  }
266  if (in_array($searchedTag, explode(' ', substr($metaData, self::EXPIRYTIME_LENGTH, -self::DATASIZE_DIGITS)))) {
267  if ($cacheEntryFileExtensionLength > 0) {
268  $entryIdentifiers[] = substr($directoryIterator->getFilename(), 0, -$cacheEntryFileExtensionLength);
269  } else {
270  $entryIdentifiers[] = $directoryIterator->getFilename();
271  }
272  }
273  }
274  return $entryIdentifiers;
275  }
276 
283  public function flush() {
284  parent::flush();
285  if ($this->frozen === TRUE) {
286  $this->frozen = FALSE;
287  }
288  }
289 
297  public function flushByTag($tag) {
298  $identifiers = $this->findIdentifiersByTag($tag);
299  if (count($identifiers) === 0) {
300  return;
301  }
302  foreach ($identifiers as $entryIdentifier) {
303  $this->remove($entryIdentifier);
304  }
305  }
306 
315  protected function isCacheFileExpired($cacheEntryPathAndFilename) {
316  if (file_exists($cacheEntryPathAndFilename) === FALSE) {
317  return TRUE;
318  }
319  $index = (int)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, (filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS), self::DATASIZE_DIGITS);
320  $expiryTime = (int)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, $index, self::EXPIRYTIME_LENGTH);
321  return $expiryTime !== 0 && $expiryTime < $GLOBALS['EXEC_TIME'];
322  }
323 
330  public function collectGarbage() {
331  if ($this->frozen === TRUE) {
332  return;
333  }
334  for ($directoryIterator = new \DirectoryIterator($this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
335  if ($directoryIterator->isDot()) {
336  continue;
337  }
338  if ($this->isCacheFileExpired($directoryIterator->getPathname())) {
339  $cacheEntryFileExtensionLength = strlen($this->cacheEntryFileExtension);
340  if ($cacheEntryFileExtensionLength > 0) {
341  $this->remove(substr($directoryIterator->getFilename(), 0, -$cacheEntryFileExtensionLength));
342  } else {
343  $this->remove($directoryIterator->getFilename());
344  }
345  }
346  }
347  }
348 
357  protected function findCacheFilesByIdentifier($entryIdentifier) {
358  $pattern = $this->cacheDirectory . $entryIdentifier;
359  $filesFound = glob($pattern);
360  if ($filesFound === FALSE || count($filesFound) === 0) {
361  return FALSE;
362  }
363  return $filesFound;
364  }
365 
374  public function requireOnce($entryIdentifier) {
375  if ($this->frozen === TRUE) {
376  if (isset($this->cacheEntryIdentifiers[$entryIdentifier])) {
377  return require_once $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
378  } else {
379  return FALSE;
380  }
381  } else {
382  $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
383  if ($entryIdentifier !== basename($entryIdentifier)) {
384  throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1282073036);
385  }
386  $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension;
387  return $this->isCacheFileExpired($pathAndFilename) ? FALSE : require_once $pathAndFilename;
388  }
389  }
390 
391 }
isCacheFileExpired($cacheEntryPathAndFilename)
static fixPermissions($path, $recursive=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.
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]