‪TYPO3CMS  10.4
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 
30 
35 {
39  protected ‪$caches = [];
40 
44  protected ‪$cacheConfigurations = [];
45 
54  protected ‪$cacheGroups = [];
55 
59  protected ‪$defaultCacheConfiguration = [
60  'frontend' => VariableFrontend::class,
61  'backend' => Typo3DatabaseBackend::class,
62  'options' => [],
63  'groups' => ['all']
64  ];
65 
69  protected ‪$disableCaching = false;
70 
74  public function ‪__construct(bool ‪$disableCaching = false)
75  {
76  $this->disableCaching = ‪$disableCaching;
77  }
78 
95  {
96  $newConfiguration = [];
97  $migratedConfiguration = [];
98  foreach (‪$cacheConfigurations as $identifier => $configuration) {
99  if (empty($identifier)) {
100  throw new \InvalidArgumentException('A cache identifier was not set.', 1596980032);
101  }
102  if (!is_array($configuration)) {
103  throw new \InvalidArgumentException('The cache configuration for cache "' . $identifier . '" was not an array as expected.', 1231259656);
104  }
105  // Fallback layer, will be removed in TYPO3 v12.0.
106  if (strpos($identifier, 'cache_') === 0) {
107  $identifier = substr($identifier, 6);
108  if (empty($identifier)) {
109  throw new \InvalidArgumentException('A cache identifier was not set.', 1596980033);
110  }
111  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);
112  $migratedConfiguration[$identifier] = $configuration;
113  } else {
114  $newConfiguration[$identifier] = $configuration;
115  }
116  }
117  $this->cacheConfigurations = array_replace_recursive($newConfiguration, $migratedConfiguration);
118  }
119 
127  public function ‪registerCache(FrontendInterface $cache, array $groups = [])
128  {
129  $identifier = $cache->getIdentifier();
130  if (isset($this->caches[$identifier])) {
131  throw new DuplicateIdentifierException('A cache with identifier "' . $identifier . '" has already been registered.', 1203698223);
132  }
133  $this->caches[$identifier] = $cache;
134  foreach ($groups as $groupIdentifier) {
135  $this->cacheGroups[$groupIdentifier][] = $identifier;
136  }
137  }
138 
146  public function ‪getCache($identifier)
147  {
148  // Fallback layer, will be removed in TYPO3 v12.0.
149  if (strpos($identifier, 'cache_') === 0) {
150  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);
151  $identifier = substr($identifier, 6);
152  }
153  if ($this->‪hasCache($identifier) === false) {
154  throw new NoSuchCacheException('A cache with identifier "' . $identifier . '" does not exist.', 1203699034);
155  }
156  if (!isset($this->caches[$identifier])) {
157  $this->‪createCache($identifier);
158  }
159  return $this->caches[$identifier];
160  }
161 
168  public function ‪hasCache($identifier)
169  {
170  // Fallback layer, will be removed in TYPO3 v12.0.
171  if (strpos($identifier, 'cache_') === 0) {
172  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);
173  $identifier = substr($identifier, 6);
174  }
175  return isset($this->caches[$identifier]) || isset($this->cacheConfigurations[$identifier]);
176  }
177 
181  public function ‪flushCaches()
182  {
183  $this->‪createAllCaches();
184  foreach ($this->caches as $cache) {
185  $cache->flush();
186  }
187  }
188 
195  public function ‪flushCachesInGroup($groupIdentifier)
196  {
197  $this->‪createAllCaches();
198  if (!isset($this->cacheGroups[$groupIdentifier])) {
199  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390334120);
200  }
201  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
202  if (isset($this->caches[$cacheIdentifier])) {
203  $this->caches[$cacheIdentifier]->flush();
204  }
205  }
206  }
207 
216  public function ‪flushCachesInGroupByTag($groupIdentifier, $tag)
217  {
218  if (empty($tag)) {
219  return;
220  }
221  $this->‪createAllCaches();
222  if (!isset($this->cacheGroups[$groupIdentifier])) {
223  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390337129);
224  }
225  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
226  if (isset($this->caches[$cacheIdentifier])) {
227  $this->caches[$cacheIdentifier]->flushByTag($tag);
228  }
229  }
230  }
231 
240  public function ‪flushCachesInGroupByTags($groupIdentifier, array $tags)
241  {
242  if (empty($tags)) {
243  return;
244  }
245  $this->‪createAllCaches();
246  if (!isset($this->cacheGroups[$groupIdentifier])) {
247  throw new NoSuchCacheGroupException('No cache in the specified group \'' . $groupIdentifier . '\'', 1390337130);
248  }
249  foreach ($this->cacheGroups[$groupIdentifier] as $cacheIdentifier) {
250  if (isset($this->caches[$cacheIdentifier])) {
251  $this->caches[$cacheIdentifier]->flushByTags($tags);
252  }
253  }
254  }
255 
262  public function ‪flushCachesByTag($tag)
263  {
264  $this->‪createAllCaches();
265  foreach ($this->caches as $cache) {
266  $cache->flushByTag($tag);
267  }
268  }
269 
275  public function ‪flushCachesByTags(array $tags)
276  {
277  $this->‪createAllCaches();
278  foreach ($this->caches as $cache) {
279  $cache->flushByTags($tags);
280  }
281  }
282 
286  protected function ‪createAllCaches()
287  {
288  foreach ($this->cacheConfigurations as $identifier => $_) {
289  if (!isset($this->caches[$identifier])) {
290  $this->‪createCache($identifier);
291  }
292  }
293  }
294 
303  protected function ‪createCache($identifier)
304  {
305  if (isset($this->cacheConfigurations[$identifier]['frontend'])) {
306  $frontend = $this->cacheConfigurations[$identifier]['frontend'];
307  } else {
308  $frontend = $this->defaultCacheConfiguration['frontend'];
309  }
310  if (isset($this->cacheConfigurations[$identifier]['backend'])) {
311  $backend = $this->cacheConfigurations[$identifier]['backend'];
312  } else {
313  $backend = $this->defaultCacheConfiguration['backend'];
314  }
315  if (isset($this->cacheConfigurations[$identifier]['options'])) {
316  $backendOptions = $this->cacheConfigurations[$identifier]['options'];
317  } else {
318  $backendOptions = $this->defaultCacheConfiguration['options'];
319  }
320 
321  if ($this->disableCaching && $backend !== TransientMemoryBackend::class) {
322  $backend = NullBackend::class;
323  $backendOptions = [];
324  }
325 
326  // Add the cache identifier to the groups that it should be attached to, or use the default ones.
327  if (isset($this->cacheConfigurations[$identifier]['groups']) && is_array($this->cacheConfigurations[$identifier]['groups'])) {
328  $assignedGroups = $this->cacheConfigurations[$identifier]['groups'];
329  } else {
330  $assignedGroups = $this->defaultCacheConfiguration['groups'];
331  }
332  foreach ($assignedGroups as $groupIdentifier) {
333  if (!isset($this->cacheGroups[$groupIdentifier])) {
334  $this->cacheGroups[$groupIdentifier] = [];
335  }
336  $this->cacheGroups[$groupIdentifier][] = $identifier;
337  }
338 
339  // New operator used on purpose: This class is required early during
340  // bootstrap before makeInstance() is properly set up
341  $backend = '\\' . ltrim($backend, '\\');
342  $backendInstance = new $backend('production', $backendOptions);
343  if (!$backendInstance instanceof BackendInterface) {
344  throw new InvalidBackendException('"' . $backend . '" is not a valid cache backend object.', 1464550977);
345  }
346  if (is_callable([$backendInstance, 'initializeObject'])) {
347  $backendInstance->initializeObject();
348  }
349 
350  // New used on purpose, see comment above
351  $frontendInstance = new $frontend($identifier, $backendInstance);
352  if (!$frontendInstance instanceof FrontendInterface) {
353  throw new InvalidCacheException('"' . $frontend . '" is not a valid cache frontend object.', 1464550984);
354  }
355  if (is_callable([$frontendInstance, 'initializeObject'])) {
356  $frontendInstance->initializeObject();
357  }
358 
359  $this->‪registerCache($frontendInstance);
360  }
361 }
‪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:51
‪TYPO3\CMS\Core\Cache\CacheManager\getCache
‪FrontendInterface getCache($identifier)
Definition: CacheManager.php:141
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface\getIdentifier
‪string getIdentifier()
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesInGroupByTags
‪flushCachesInGroupByTags($groupIdentifier, array $tags)
Definition: CacheManager.php:235
‪TYPO3\CMS\Core\Cache\CacheManager\createCache
‪createCache($identifier)
Definition: CacheManager.php:298
‪TYPO3\CMS\Core\Cache\CacheManager\createAllCaches
‪createAllCaches()
Definition: CacheManager.php:281
‪TYPO3\CMS\Core\Cache\Exception\InvalidBackendException
Definition: InvalidBackendException.php:24
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesByTags
‪flushCachesByTags(array $tags)
Definition: CacheManager.php:270
‪TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
Definition: Typo3DatabaseBackend.php:31
‪TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
Definition: NoSuchCacheException.php:24
‪TYPO3\CMS\Core\Cache\CacheManager\$cacheConfigurations
‪array $cacheConfigurations
Definition: CacheManager.php:42
‪TYPO3\CMS\Core\Cache\CacheManager\hasCache
‪bool hasCache($identifier)
Definition: CacheManager.php:163
‪TYPO3\CMS\Core\Cache\Backend\BackendInterface
Definition: BackendInterface.php:25
‪TYPO3\CMS\Core\Cache\CacheManager\$disableCaching
‪bool $disableCaching
Definition: CacheManager.php:64
‪TYPO3\CMS\Core\Cache\CacheManager\flushCaches
‪flushCaches()
Definition: CacheManager.php:176
‪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:35
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesInGroupByTag
‪flushCachesInGroupByTag($groupIdentifier, $tag)
Definition: CacheManager.php:211
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesInGroup
‪flushCachesInGroup($groupIdentifier)
Definition: CacheManager.php:190
‪TYPO3\CMS\Core\Cache\Exception\DuplicateIdentifierException
Definition: DuplicateIdentifierException.php:24
‪TYPO3\CMS\Core\Cache\Exception\InvalidCacheException
Definition: InvalidCacheException.php:24
‪TYPO3\CMS\Core\Cache\CacheManager\$caches
‪FrontendInterface[] $caches
Definition: CacheManager.php:38
‪TYPO3\CMS\Core\Cache\CacheManager\$defaultCacheConfiguration
‪array $defaultCacheConfiguration
Definition: CacheManager.php:55
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Cache\CacheManager\registerCache
‪registerCache(FrontendInterface $cache, array $groups=[])
Definition: CacheManager.php:122
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:23
‪TYPO3\CMS\Core\Cache\Exception\NoSuchCacheGroupException
Definition: NoSuchCacheGroupException.php:24
‪TYPO3\CMS\Core\Cache\CacheManager\setCacheConfigurations
‪setCacheConfigurations(array $cacheConfigurations)
Definition: CacheManager.php:89
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesByTag
‪flushCachesByTag($tag)
Definition: CacheManager.php:257
‪TYPO3\CMS\Core\Cache\CacheManager\__construct
‪__construct(bool $disableCaching=false)
Definition: CacheManager.php:69