TYPO3 CMS  TYPO3_8-7
CacheManager.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Cache;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
27 
36 {
40  protected $caches = [];
41 
45  protected $cacheConfigurations = [];
46 
55  protected $cacheGroups = [];
56 
61  'frontend' => VariableFrontend::class,
62  'backend' => Typo3DatabaseBackend::class,
63  'options' => [],
64  'groups' => ['all']
65  ];
66 
83  {
84  foreach ($cacheConfigurations as $identifier => $configuration) {
85  if (!is_array($configuration)) {
86  throw new \InvalidArgumentException('The cache configuration for cache "' . $identifier . '" was not an array as expected.', 1231259656);
87  }
88  $this->cacheConfigurations[$identifier] = $configuration;
89  }
90  }
91 
99  public function registerCache(FrontendInterface $cache)
100  {
101  $identifier = $cache->getIdentifier();
102  if (isset($this->caches[$identifier])) {
103  throw new DuplicateIdentifierException('A cache with identifier "' . $identifier . '" has already been registered.', 1203698223);
104  }
105  $this->caches[$identifier] = $cache;
106  }
107 
116  public function getCache($identifier)
117  {
118  if ($this->hasCache($identifier) === false) {
119  throw new NoSuchCacheException('A cache with identifier "' . $identifier . '" does not exist.', 1203699034);
120  }
121  if (!isset($this->caches[$identifier])) {
122  $this->createCache($identifier);
123  }
124  return $this->caches[$identifier];
125  }
126 
134  public function hasCache($identifier)
135  {
136  return isset($this->caches[$identifier]) || isset($this->cacheConfigurations[$identifier]);
137  }
138 
144  public function flushCaches()
145  {
146  $this->createAllCaches();
147  foreach ($this->caches as $cache) {
148  $cache->flush();
149  }
150  }
151 
159  public function flushCachesInGroup($groupIdentifier)
160  {
161  $this->createAllCaches();
162  if (!isset($this->cacheGroups[$groupIdentifier])) {
163  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390334120);
164  }
165  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
166  if (isset($this->caches[$cacheIdentifier])) {
167  $this->caches[$cacheIdentifier]->flush();
168  }
169  }
170  }
171 
181  public function flushCachesInGroupByTag($groupIdentifier, $tag)
182  {
183  if (empty($tag)) {
184  return;
185  }
186  $this->createAllCaches();
187  if (!isset($this->cacheGroups[$groupIdentifier])) {
188  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390337129);
189  }
190  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
191  if (isset($this->caches[$cacheIdentifier])) {
192  $this->caches[$cacheIdentifier]->flushByTag($tag);
193  }
194  }
195  }
196 
206  public function flushCachesInGroupByTags($groupIdentifier, array $tags)
207  {
208  if (empty($tags)) {
209  return;
210  }
211  $this->createAllCaches();
212  if (!isset($this->cacheGroups[$groupIdentifier])) {
213  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390337130);
214  }
215  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
216  if (isset($this->caches[$cacheIdentifier])) {
217  $this->caches[$cacheIdentifier]->flushByTags($tags);
218  }
219  }
220  }
221 
229  public function flushCachesByTag($tag)
230  {
231  $this->createAllCaches();
232  foreach ($this->caches as $cache) {
233  $cache->flushByTag($tag);
234  }
235  }
236 
243  public function flushCachesByTags(array $tags)
244  {
245  $this->createAllCaches();
246  foreach ($this->caches as $cache) {
247  $cache->flushByTags($tags);
248  }
249  }
250 
254  protected function createAllCaches()
255  {
256  foreach ($this->cacheConfigurations as $identifier => $_) {
257  if (!isset($this->caches[$identifier])) {
258  $this->createCache($identifier);
259  }
260  }
261  }
262 
271  protected function createCache($identifier)
272  {
273  if (isset($this->cacheConfigurations[$identifier]['frontend'])) {
274  $frontend = $this->cacheConfigurations[$identifier]['frontend'];
275  } else {
276  $frontend = $this->defaultCacheConfiguration['frontend'];
277  }
278  if (isset($this->cacheConfigurations[$identifier]['backend'])) {
279  $backend = $this->cacheConfigurations[$identifier]['backend'];
280  } else {
281  $backend = $this->defaultCacheConfiguration['backend'];
282  }
283  if (isset($this->cacheConfigurations[$identifier]['options'])) {
284  $backendOptions = $this->cacheConfigurations[$identifier]['options'];
285  } else {
286  $backendOptions = $this->defaultCacheConfiguration['options'];
287  }
288 
289  // Add the cache identifier to the groups that it should be attached to, or use the default ones.
290  if (isset($this->cacheConfigurations[$identifier]['groups']) && is_array($this->cacheConfigurations[$identifier]['groups'])) {
291  $assignedGroups = $this->cacheConfigurations[$identifier]['groups'];
292  } else {
293  $assignedGroups = $this->defaultCacheConfiguration['groups'];
294  }
295  foreach ($assignedGroups as $groupIdentifier) {
296  if (!isset($this->cacheGroups[$groupIdentifier])) {
297  $this->cacheGroups[$groupIdentifier] = [];
298  }
299  $this->cacheGroups[$groupIdentifier][] = $identifier;
300  }
301 
302  // New operator used on purpose: This class is required early during
303  // bootstrap before makeInstance() is properly set up
304  $backend = '\\' . ltrim($backend, '\\');
305  $backendInstance = new $backend('production', $backendOptions);
306  if (!$backendInstance instanceof BackendInterface) {
307  throw new InvalidBackendException('"' . $backend . '" is not a valid cache backend object.', 1464550977);
308  }
309  if (is_callable([$backendInstance, 'initializeObject'])) {
310  $backendInstance->initializeObject();
311  }
312 
313  // New used on purpose, see comment above
314  $frontendInstance = new $frontend($identifier, $backendInstance);
315  if (!$frontendInstance instanceof FrontendInterface) {
316  throw new InvalidCacheException('"' . $frontend . '" is not a valid cache frontend object.', 1464550984);
317  }
318  if (is_callable([$frontendInstance, 'initializeObject'])) {
319  $frontendInstance->initializeObject();
320  }
321 
322  $this->registerCache($frontendInstance);
323  }
324 }
setCacheConfigurations(array $cacheConfigurations)
flushCachesInGroup($groupIdentifier)
flushCachesInGroupByTags($groupIdentifier, array $tags)
flushCachesInGroupByTag($groupIdentifier, $tag)
registerCache(FrontendInterface $cache)