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