vendor/twig/twig/src/Cache/FilesystemCache.php line 42

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) Fabien Potencier
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Twig\Cache;
  11. /**
  12. * Implements a cache on the filesystem.
  13. *
  14. * @author Andrew Tch <andrew@noop.lv>
  15. */
  16. class FilesystemCache implements CacheInterface, RemovableCacheInterface
  17. {
  18. public const FORCE_BYTECODE_INVALIDATION = 1;
  19. private $directory;
  20. private $options;
  21. public function __construct(string $directory, int $options = 0)
  22. {
  23. $this->directory = rtrim($directory, '\/').'/';
  24. $this->options = $options;
  25. }
  26. public function generateKey(string $name, string $className): string
  27. {
  28. $hash = hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $className);
  29. return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php';
  30. }
  31. public function load(string $key): void
  32. {
  33. if (is_file($key)) {
  34. @include_once $key;
  35. }
  36. }
  37. public function write(string $key, string $content): void
  38. {
  39. $dir = \dirname($key);
  40. if (!is_dir($dir)) {
  41. if (false === @mkdir($dir, 0777, true)) {
  42. clearstatcache(true, $dir);
  43. if (!is_dir($dir)) {
  44. throw new \RuntimeException(\sprintf('Unable to create the cache directory (%s).', $dir));
  45. }
  46. }
  47. } elseif (!is_writable($dir)) {
  48. throw new \RuntimeException(\sprintf('Unable to write in the cache directory (%s).', $dir));
  49. }
  50. $tmpFile = tempnam($dir, basename($key));
  51. if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $key)) {
  52. @chmod($key, 0666 & ~umask());
  53. if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
  54. // Compile cached file into bytecode cache
  55. if (\function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
  56. @opcache_invalidate($key, true);
  57. } elseif (\function_exists('apc_compile_file')) {
  58. apc_compile_file($key);
  59. }
  60. }
  61. return;
  62. }
  63. throw new \RuntimeException(\sprintf('Failed to write cache file "%s".', $key));
  64. }
  65. public function remove(string $name, string $cls): void
  66. {
  67. $key = $this->generateKey($name, $cls);
  68. if (!@unlink($key) && file_exists($key)) {
  69. throw new \RuntimeException(\sprintf('Failed to delete cache file "%s".', $key));
  70. }
  71. }
  72. public function getTimestamp(string $key): int
  73. {
  74. if (!is_file($key)) {
  75. return 0;
  76. }
  77. return (int) @filemtime($key);
  78. }
  79. }