‪TYPO3CMS  11.5
CacheManager.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
16 namespace ‪TYPO3\CMS\Core\Cache;
17 
31 
36 {
40  protected ‪$caches = [];
41 
45  protected ‪$cacheConfigurations = [];
46 
55  protected ‪$cacheGroups = [];
56 
60  protected ‪$defaultCacheConfiguration = [
61  'frontend' => VariableFrontend::class,
62  'backend' => Typo3DatabaseBackend::class,
63  'options' => [],
64  'groups' => ['all'],
65  ];
66 
70  protected ‪$disableCaching = false;
71 
75  public function ‪__construct(bool ‪$disableCaching = false)
76  {
77  $this->disableCaching = ‪$disableCaching;
78  }
79 
96  {
97  $newConfiguration = [];
98  $migratedConfiguration = [];
99  foreach (‪$cacheConfigurations as $identifier => $configuration) {
100  if (empty($identifier)) {
101  throw new \InvalidArgumentException('A cache identifier was not set.', 1596980032);
102  }
103  if (!is_array($configuration)) {
104  throw new \InvalidArgumentException('The cache configuration for cache "' . $identifier . '" was not an array as expected.', 1231259656);
105  }
106  // Fallback layer, will be removed in TYPO3 v12.0.
107  if (strpos($identifier, 'cache_') === 0) {
108  $identifier = substr($identifier, 6);
109  if (empty($identifier)) {
110  throw new \InvalidArgumentException('A cache identifier was not set.', 1596980033);
111  }
112  trigger_error('Accessing a cache with the "cache_" prefix as in "' . $identifier . '" is not necessary anymore, and should be called without the cache prefix.', E_USER_DEPRECATED);
113  $migratedConfiguration[$identifier] = $configuration;
114  } else {
115  $newConfiguration[$identifier] = $configuration;
116  }
117  }
118  $this->cacheConfigurations = array_replace_recursive($newConfiguration, $migratedConfiguration);
119  }
120 
128  public function ‪registerCache(FrontendInterface $cache, array $groups = [])
129  {
130  $identifier = $cache->getIdentifier();
131  if (isset($this->caches[$identifier])) {
132  throw new DuplicateIdentifierException('A cache with identifier "' . $identifier . '" has already been registered.', 1203698223);
133  }
134  $this->caches[$identifier] = $cache;
135  foreach ($groups as $groupIdentifier) {
136  $this->cacheGroups[$groupIdentifier][] = $identifier;
137  }
138  }
139 
147  public function ‪getCache($identifier)
148  {
149  // Fallback layer, will be removed in TYPO3 v12.0.
150  if (strpos($identifier, 'cache_') === 0) {
151  trigger_error('Accessing a cache with the "cache_" prefix as in "' . $identifier . '" is not necessary anymore, and should be called without the cache prefix.', E_USER_DEPRECATED);
152  $identifier = substr($identifier, 6);
153  }
154  if ($this->‪hasCache($identifier) === false) {
155  throw new NoSuchCacheException('A cache with identifier "' . $identifier . '" does not exist.', 1203699034);
156  }
157  if (!isset($this->caches[$identifier])) {
158  $this->‪createCache($identifier);
159  }
160  return $this->caches[$identifier];
161  }
162 
169  public function ‪hasCache($identifier)
170  {
171  // Fallback layer, will be removed in TYPO3 v12.0.
172  if (strpos($identifier, 'cache_') === 0) {
173  trigger_error('Accessing a cache with the "cache_" prefix as in "' . $identifier . '" is not necessary anymore, and should be called without the cache prefix.', E_USER_DEPRECATED);
174  $identifier = substr($identifier, 6);
175  }
176  return isset($this->caches[$identifier]) || isset($this->cacheConfigurations[$identifier]);
177  }
178 
182  public function ‪flushCaches()
183  {
184  $this->‪createAllCaches();
185  foreach ($this->caches as $cache) {
186  $cache->flush();
187  }
188  }
189 
196  public function ‪flushCachesInGroup($groupIdentifier)
197  {
198  $this->‪createAllCaches();
199  if (!isset($this->cacheGroups[$groupIdentifier])) {
200  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390334120);
201  }
202  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
203  if (isset($this->caches[$cacheIdentifier])) {
204  $this->caches[$cacheIdentifier]->flush();
205  }
206  }
207  }
208 
217  public function ‪flushCachesInGroupByTag($groupIdentifier, $tag)
218  {
219  if (empty($tag)) {
220  return;
221  }
222  $this->‪createAllCaches();
223  if (!isset($this->cacheGroups[$groupIdentifier])) {
224  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390337129);
225  }
226  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
227  if (isset($this->caches[$cacheIdentifier])) {
228  $this->caches[$cacheIdentifier]->flushByTag($tag);
229  }
230  }
231  }
232 
241  public function ‪flushCachesInGroupByTags($groupIdentifier, array $tags)
242  {
243  if (empty($tags)) {
244  return;
245  }
246  $this->‪createAllCaches();
247  if (!isset($this->cacheGroups[$groupIdentifier])) {
248  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390337130);
249  }
250  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
251  if (isset($this->caches[$cacheIdentifier])) {
252  $this->caches[$cacheIdentifier]->flushByTags($tags);
253  }
254  }
255  }
256 
263  public function ‪flushCachesByTag($tag)
264  {
265  $this->‪createAllCaches();
266  foreach ($this->caches as $cache) {
267  $cache->flushByTag($tag);
268  }
269  }
270 
276  public function ‪flushCachesByTags(array $tags)
277  {
278  $this->‪createAllCaches();
279  foreach ($this->caches as $cache) {
280  $cache->flushByTags($tags);
281  }
282  }
283 
288  public function ‪getCacheGroups(): array
289  {
290  $groups = array_keys($this->cacheGroups);
291 
292  foreach ($this->cacheConfigurations as $config) {
293  foreach ($config['groups'] ?? [] as $group) {
294  if (!in_array($group, $groups, true)) {
295  $groups[] = $group;
296  }
297  }
298  }
299 
300  return $groups;
301  }
302 
303  public function ‪handleCacheFlushEvent(CacheFlushEvent $event): void
304  {
305  foreach ($event->getGroups() as $group) {
306  $this->‪flushCachesInGroup($group);
307  }
308  }
309 
313  protected function ‪createAllCaches()
314  {
315  foreach ($this->cacheConfigurations as $identifier => $_) {
316  if (!isset($this->caches[$identifier])) {
317  $this->‪createCache($identifier);
318  }
319  }
320  }
321 
330  protected function ‪createCache($identifier)
331  {
332  if (isset($this->cacheConfigurations[$identifier]['frontend'])) {
333  $frontend = $this->cacheConfigurations[$identifier]['frontend'];
334  } else {
335  $frontend = $this->defaultCacheConfiguration['frontend'];
336  }
337  if (isset($this->cacheConfigurations[$identifier]['backend'])) {
338  $backend = $this->cacheConfigurations[$identifier]['backend'];
339  } else {
340  $backend = $this->defaultCacheConfiguration['backend'];
341  }
342  if (isset($this->cacheConfigurations[$identifier]['options'])) {
343  $backendOptions = $this->cacheConfigurations[$identifier]['options'];
344  } else {
345  $backendOptions = $this->defaultCacheConfiguration['options'];
346  }
347 
348  if ($this->disableCaching && $backend !== TransientMemoryBackend::class) {
349  $backend = NullBackend::class;
350  $backendOptions = [];
351  }
352 
353  // Add the cache identifier to the groups that it should be attached to, or use the default ones.
354  if (isset($this->cacheConfigurations[$identifier]['groups']) && is_array($this->cacheConfigurations[$identifier]['groups'])) {
355  $assignedGroups = $this->cacheConfigurations[$identifier]['groups'];
356  } else {
357  $assignedGroups = $this->defaultCacheConfiguration['groups'];
358  }
359  foreach ($assignedGroups as $groupIdentifier) {
360  if (!isset($this->cacheGroups[$groupIdentifier])) {
361  $this->cacheGroups[$groupIdentifier] = [];
362  }
363  $this->cacheGroups[$groupIdentifier][] = $identifier;
364  }
365 
366  // New operator used on purpose: This class is required early during
367  // bootstrap before makeInstance() is properly set up
368  $backend = '\\' . ltrim($backend, '\\');
369  $backendInstance = new $backend('production', $backendOptions);
370  if (!$backendInstance instanceof BackendInterface) {
371  throw new InvalidBackendException('"' . $backend . '" is not a valid cache backend object.', 1464550977);
372  }
373  if (is_callable([$backendInstance, 'initializeObject'])) {
374  $backendInstance->initializeObject();
375  }
376 
377  // New used on purpose, see comment above
378  $frontendInstance = new $frontend($identifier, $backendInstance);
379  if (!$frontendInstance instanceof FrontendInterface) {
380  throw new InvalidCacheException('"' . $frontend . '" is not a valid cache frontend object.', 1464550984);
381  }
382  if (is_callable([$frontendInstance, 'initializeObject'])) {
383  $frontendInstance->initializeObject();
384  }
385 
386  $this->‪registerCache($frontendInstance);
387  }
388 }
‪TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend
Definition: TransientMemoryBackend.php:25
‪TYPO3\CMS\Core\Cache
‪TYPO3\CMS\Core\Cache\CacheManager\$cacheGroups
‪array $cacheGroups
Definition: CacheManager.php:52
‪TYPO3\CMS\Core\Cache\CacheManager\getCache
‪FrontendInterface getCache($identifier)
Definition: CacheManager.php:142
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface\getIdentifier
‪string getIdentifier()
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesInGroupByTags
‪flushCachesInGroupByTags($groupIdentifier, array $tags)
Definition: CacheManager.php:236
‪TYPO3\CMS\Core\Cache\CacheManager\createCache
‪createCache($identifier)
Definition: CacheManager.php:325
‪TYPO3\CMS\Core\Cache\CacheManager\createAllCaches
‪createAllCaches()
Definition: CacheManager.php:308
‪TYPO3\CMS\Core\Cache\Exception\InvalidBackendException
Definition: InvalidBackendException.php:23
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesByTags
‪flushCachesByTags(array $tags)
Definition: CacheManager.php:271
‪TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
Definition: Typo3DatabaseBackend.php:30
‪TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
Definition: NoSuchCacheException.php:23
‪TYPO3\CMS\Core\Cache\CacheManager\$cacheConfigurations
‪array $cacheConfigurations
Definition: CacheManager.php:43
‪TYPO3\CMS\Core\Cache\CacheManager\hasCache
‪bool hasCache($identifier)
Definition: CacheManager.php:164
‪TYPO3\CMS\Core\Cache\CacheManager\handleCacheFlushEvent
‪handleCacheFlushEvent(CacheFlushEvent $event)
Definition: CacheManager.php:298
‪TYPO3\CMS\Core\Cache\Event\CacheFlushEvent\getGroups
‪getGroups()
Definition: CacheFlushEvent.php:33
‪TYPO3\CMS\Core\Cache\Backend\BackendInterface
Definition: BackendInterface.php:25
‪TYPO3\CMS\Core\Cache\CacheManager\$disableCaching
‪bool $disableCaching
Definition: CacheManager.php:65
‪TYPO3\CMS\Core\Cache\CacheManager\flushCaches
‪flushCaches()
Definition: CacheManager.php:177
‪TYPO3\CMS\Core\Cache\Frontend\VariableFrontend
Definition: VariableFrontend.php:25
‪TYPO3\CMS\Core\Cache\Backend\NullBackend
Definition: NullBackend.php:22
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesInGroupByTag
‪flushCachesInGroupByTag($groupIdentifier, $tag)
Definition: CacheManager.php:212
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesInGroup
‪flushCachesInGroup($groupIdentifier)
Definition: CacheManager.php:191
‪TYPO3\CMS\Core\Cache\Exception\DuplicateIdentifierException
Definition: DuplicateIdentifierException.php:23
‪TYPO3\CMS\Core\Cache\Exception\InvalidCacheException
Definition: InvalidCacheException.php:23
‪TYPO3\CMS\Core\Cache\CacheManager\$caches
‪FrontendInterface[] $caches
Definition: CacheManager.php:39
‪TYPO3\CMS\Core\Cache\CacheManager\$defaultCacheConfiguration
‪array $defaultCacheConfiguration
Definition: CacheManager.php:56
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Cache\CacheManager\registerCache
‪registerCache(FrontendInterface $cache, array $groups=[])
Definition: CacheManager.php:123
‪TYPO3\CMS\Core\Cache\Event\CacheFlushEvent
Definition: CacheFlushEvent.php:24
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪TYPO3\CMS\Core\Cache\Exception\NoSuchCacheGroupException
Definition: NoSuchCacheGroupException.php:23
‪TYPO3\CMS\Core\Cache\CacheManager\setCacheConfigurations
‪setCacheConfigurations(array $cacheConfigurations)
Definition: CacheManager.php:90
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesByTag
‪flushCachesByTag($tag)
Definition: CacheManager.php:258
‪TYPO3\CMS\Core\Cache\CacheManager\__construct
‪__construct(bool $disableCaching=false)
Definition: CacheManager.php:70
‪TYPO3\CMS\Core\Cache\CacheManager\getCacheGroups
‪string[] getCacheGroups()
Definition: CacheManager.php:283