julienmonnerie/kirby/src/Cms/AppCaches.php

132 lines
3 KiB
PHP
Raw Normal View History

2022-06-17 17:51:59 +02:00
<?php
namespace Kirby\Cms;
2022-12-19 14:56:05 +01:00
use Kirby\Cache\Cache;
2022-06-17 17:51:59 +02:00
use Kirby\Cache\NullCache;
use Kirby\Exception\InvalidArgumentException;
/**
* AppCaches
*
* @package Kirby Cms
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://getkirby.com/license
*/
trait AppCaches
{
2025-04-21 18:57:21 +02:00
protected array $caches = [];
2022-08-31 15:02:43 +02:00
/**
* Returns a cache instance by key
*/
2025-04-21 18:57:21 +02:00
public function cache(string $key): Cache
2022-08-31 15:02:43 +02:00
{
if (isset($this->caches[$key]) === true) {
return $this->caches[$key];
}
// get the options for this cache type
$options = $this->cacheOptions($key);
if ($options['active'] === false) {
// use a dummy cache that does nothing
return $this->caches[$key] = new NullCache();
}
$type = strtolower($options['type']);
$types = $this->extensions['cacheTypes'] ?? [];
if (array_key_exists($type, $types) === false) {
throw new InvalidArgumentException([
2023-04-14 16:34:06 +02:00
'key' => 'cache.type.invalid',
2022-08-31 15:02:43 +02:00
'data' => ['type' => $type]
]);
}
$className = $types[$type];
// initialize the cache class
$cache = new $className($options);
// check if it is a usable cache object
2022-12-19 14:56:05 +01:00
if ($cache instanceof Cache === false) {
2022-08-31 15:02:43 +02:00
throw new InvalidArgumentException([
2023-04-14 16:34:06 +02:00
'key' => 'cache.type.invalid',
2022-08-31 15:02:43 +02:00
'data' => ['type' => $type]
]);
}
return $this->caches[$key] = $cache;
}
/**
* Returns the cache options by key
*/
protected function cacheOptions(string $key): array
{
2022-12-19 14:56:05 +01:00
$options = $this->option($this->cacheOptionsKey($key), null);
$options ??= $this->core()->caches()[$key] ?? false;
2022-08-31 15:02:43 +02:00
if ($options === false) {
return [
'active' => false
];
}
2023-04-14 16:34:06 +02:00
$prefix =
str_replace(['/', ':'], '_', $this->system()->indexUrl()) .
'/' .
str_replace(['/', '.'], ['_', '/'], $key);
2022-08-31 15:02:43 +02:00
$defaults = [
'active' => true,
'type' => 'file',
'extension' => 'cache',
'root' => $this->root('cache'),
'prefix' => $prefix
];
if ($options === true) {
return $defaults;
}
2022-12-19 14:56:05 +01:00
return array_merge($defaults, $options);
2022-08-31 15:02:43 +02:00
}
/**
* Takes care of converting prefixed plugin cache setups
* to the right cache key, while leaving regular cache
* setups untouched.
*/
protected function cacheOptionsKey(string $key): string
{
$prefixedKey = 'cache.' . $key;
if (isset($this->options[$prefixedKey])) {
return $prefixedKey;
}
// plain keys without dots don't need further investigation
// since they can never be from a plugin.
if (strpos($key, '.') === false) {
return $prefixedKey;
}
// try to extract the plugin name
$parts = explode('.', $key);
$pluginName = implode('/', array_slice($parts, 0, 2));
$pluginPrefix = implode('.', array_slice($parts, 0, 2));
$cacheName = implode('.', array_slice($parts, 2));
// check if such a plugin exists
if ($this->plugin($pluginName)) {
return empty($cacheName) === true ? $pluginPrefix . '.cache' : $pluginPrefix . '.cache.' . $cacheName;
}
return $prefixedKey;
}
2022-06-17 17:51:59 +02:00
}