Upgraded drupal core with security updates
[yaffs-website] / web / core / lib / Drupal / Core / Template / TwigPhpStorageCache.php
1 <?php
2
3 namespace Drupal\Core\Template;
4
5 use Drupal\Component\Utility\Crypt;
6 use Drupal\Core\Cache\CacheBackendInterface;
7 use Drupal\Core\PhpStorage\PhpStorageFactory;
8
9 /**
10  * Provides an alternate cache storage for Twig using PhpStorage.
11  *
12  * This class is designed to work on setups with multiple webheads using a local
13  * filesystem for the twig cache. When generating the cache key, a hash value
14  * depending on the enabled extensions is included. This prevents stale
15  * templates from being reused when twig extensions are enabled or disabled.
16  *
17  * @see \Drupal\Core\DependencyInjection\Compiler\TwigExtensionPass
18  */
19 class TwigPhpStorageCache implements \Twig_CacheInterface {
20
21   /**
22    * The maximum length for each part of the cache key suffix.
23    */
24   const SUFFIX_SUBSTRING_LENGTH = 25;
25
26   /**
27    * The cache object used for auto-refresh via mtime.
28    *
29    * @var \Drupal\Core\Cache\CacheBackendInterface
30    */
31   protected $cache;
32
33   /**
34    * The PhpStorage object used for storing the templates.
35    *
36    * @var \Drupal\Component\PhpStorage\PhpStorageInterface
37    */
38   protected $storage;
39
40   /**
41    * The template cache filename prefix.
42    *
43    * @var string
44    */
45   protected $templateCacheFilenamePrefix;
46
47   /**
48    * Store cache backend and other information internally.
49    *
50    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
51    *   The cache bin.
52    * @param string $twig_cache_prefix
53    *   A Twig cache file prefix that changes when Twig extensions change.
54    */
55   public function __construct(CacheBackendInterface $cache, $twig_cache_prefix) {
56     $this->cache = $cache;
57     $this->templateCacheFilenamePrefix = $twig_cache_prefix;
58   }
59
60   /**
61    * Gets the PHP code storage object to use for the compiled Twig files.
62    *
63    * @return \Drupal\Component\PhpStorage\PhpStorageInterface
64    */
65   protected function storage() {
66     if (!isset($this->storage)) {
67       $this->storage = PhpStorageFactory::get('twig');
68     }
69     return $this->storage;
70   }
71
72   /**
73    * {@inheritdoc}
74    */
75   public function generateKey($name, $className) {
76     if (strpos($name, '{# inline_template_start #}') === 0) {
77       // $name is an inline template, and can have characters that are not valid
78       // for a filename. $suffix is unique for each inline template so we just
79       // use the generic name 'inline-template' here.
80       $name = 'inline-template';
81     }
82     else {
83       $name = basename($name);
84     }
85
86     // Windows (and some encrypted Linux systems) only support 255 characters in
87     // a path. On Windows a requirements error is displayed and installation is
88     // blocked if Drupal's public files path is longer than 120 characters.
89     // Thus, to always be less than 255, file paths may not be more than 135
90     // characters long. Using the default PHP file storage class, the Twig cache
91     // file path will be 124 characters long at most, which provides a margin of
92     // safety.
93     $suffix = substr($name, 0, self::SUFFIX_SUBSTRING_LENGTH) . '_';
94     $suffix .= substr(Crypt::hashBase64($className), 0, self::SUFFIX_SUBSTRING_LENGTH);
95
96     // The cache prefix is what gets invalidated.
97     return $this->templateCacheFilenamePrefix . '_' . $suffix;
98   }
99
100   /**
101    * {@inheritdoc}
102    */
103   public function load($key) {
104     $this->storage()->load($key);
105   }
106
107   /**
108    * {@inheritdoc}
109    */
110   public function write($key, $content) {
111     $this->storage()->save($key, $content);
112     // Save the last mtime.
113     $cid = 'twig:' . $key;
114     $this->cache->set($cid, REQUEST_TIME);
115   }
116
117   /**
118    * {@inheritdoc}
119    */
120   public function getTimestamp($key) {
121     $cid = 'twig:' . $key;
122     if ($cache = $this->cache->get($cid)) {
123       return $cache->data;
124     }
125     else {
126       return 0;
127     }
128   }
129
130 }