lib/Phpfastcache/Config/ConfigurationOption.php
<?php
/**
*
* This file is part of Phpfastcache.
*
* @license MIT License (MIT)
*
* For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
*
* @author Georges.L (Geolim4) <contact@geolim4.com>
* @author Contributors https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
*/
declare(strict_types=1);
namespace Phpfastcache\Config;
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
use Phpfastcache\Exceptions\PhpfastcacheInvalidConfigurationException;
use Phpfastcache\Exceptions\PhpfastcacheInvalidTypeException;
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
class ConfigurationOption extends AbstractConfigurationOption implements ConfigurationOptionInterface
{
protected bool $itemDetailedDate = false;
protected bool $autoTmpFallback = false;
protected int $defaultTtl = 900;
/**
* @var string|callable
*/
protected mixed $defaultKeyHashFunction = 'md5';
/**
* @var string|callable
*/
protected mixed $defaultFileNameHashFunction = 'md5';
protected string $path = '';
protected bool $preventCacheSlams = false;
protected int $cacheSlamsTimeout = 15;
protected bool $useStaticItemCaching = true;
protected ?object $superGlobalAccessor = null;
/**
* @inheritDoc
* @throws PhpfastcacheInvalidConfigurationException
* @throws PhpfastcacheInvalidTypeException
*/
public function __construct(array $parameters = [])
{
foreach ($parameters as $configKey => $configVal) {
try {
if (\property_exists($this, $configKey)) {
$this->{'set' . \ucfirst($configKey)}($configVal);
} else {
throw new PhpfastcacheInvalidConfigurationException(
sprintf(
'Unknown configuration option name "%s" for the config class "%s". Allowed configurations options are "%s"',
$configKey,
$this::class,
\implode('", "', \array_keys($this->toArray())),
)
);
}
} catch (\TypeError $e) {
throw new PhpfastcacheInvalidTypeException(
\sprintf(
'TypeError exception thrown while trying to set your configuration: %s',
$e->getMessage()
)
);
}
}
}
public function toArray(): array
{
return \get_object_vars($this);
}
/**
* @throws \ReflectionException
*/
public function isValueSerializable(mixed $val): bool
{
return !\is_callable($val) && !(is_object($val) && (new \ReflectionClass($val))->isAnonymous());
}
/**
* @param string $optionName
* @return bool
*/
public function isValidOption(string $optionName): bool
{
return \property_exists($this, $optionName);
}
/**
* @return bool
*/
public function isItemDetailedDate(): bool
{
return $this->itemDetailedDate;
}
/**
* @param bool $itemDetailedDate
* @return ConfigurationOption
* @throws PhpfastcacheLogicException
*/
public function setItemDetailedDate(bool $itemDetailedDate): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->itemDetailedDate = $itemDetailedDate;
return $this;
}
/**
* @return bool
*/
public function isAutoTmpFallback(): bool
{
return $this->autoTmpFallback;
}
/**
* @param bool $autoTmpFallback
* @return ConfigurationOption
* @throws PhpfastcacheLogicException
*/
public function setAutoTmpFallback(bool $autoTmpFallback): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->autoTmpFallback = $autoTmpFallback;
return $this;
}
/**
* @return int
*/
public function getDefaultTtl(): int
{
return $this->defaultTtl;
}
/**
* @param int $defaultTtl
* @return ConfigurationOption
* @throws PhpfastcacheLogicException
*/
public function setDefaultTtl(int $defaultTtl): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->defaultTtl = $defaultTtl;
return $this;
}
/**
* @return callable|string
*/
public function getDefaultKeyHashFunction(): callable|string
{
return $this->defaultKeyHashFunction;
}
/**
* @param callable|string $defaultKeyHashFunction
* @return ConfigurationOption
* @throws PhpfastcacheInvalidConfigurationException
* @throws PhpfastcacheLogicException
*/
public function setDefaultKeyHashFunction(callable|string $defaultKeyHashFunction): static
{
$this->enforceLockedProperty(__FUNCTION__);
if ($defaultKeyHashFunction && !\is_callable($defaultKeyHashFunction) && (\is_string($defaultKeyHashFunction) && !\function_exists($defaultKeyHashFunction))) {
throw new PhpfastcacheInvalidConfigurationException('defaultKeyHashFunction must be a valid function name string');
}
$this->defaultKeyHashFunction = $defaultKeyHashFunction;
return $this;
}
/**
* @return callable|string
*/
public function getDefaultFileNameHashFunction(): callable|string
{
return $this->defaultFileNameHashFunction;
}
/**
* @param callable|string $defaultFileNameHashFunction
* @return ConfigurationOption
* @throws PhpfastcacheInvalidConfigurationException
* @throws PhpfastcacheLogicException
*/
public function setDefaultFileNameHashFunction(callable|string $defaultFileNameHashFunction): static
{
$this->enforceLockedProperty(__FUNCTION__);
if (!\is_callable($defaultFileNameHashFunction) && (\is_string($defaultFileNameHashFunction) && !\function_exists($defaultFileNameHashFunction))) {
throw new PhpfastcacheInvalidConfigurationException('defaultFileNameHashFunction must be a valid function name string');
}
$this->defaultFileNameHashFunction = $defaultFileNameHashFunction;
return $this;
}
/**
* @return string
*/
public function getPath(): string
{
return $this->path;
}
/**
* @param string $path
* @return ConfigurationOption
* @throws PhpfastcacheLogicException
*/
public function setPath(string $path): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->path = $path;
return $this;
}
/**
* @deprecated This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.
* @return bool
*/
public function isPreventCacheSlams(): bool
{
return $this->preventCacheSlams;
}
/**
* @deprecated This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.
* @param bool $preventCacheSlams
* @return ConfigurationOption
* @throws PhpfastcacheLogicException
*/
public function setPreventCacheSlams(bool $preventCacheSlams): static
{
if ($preventCacheSlams !== $this->preventCacheSlams) {
trigger_error(
'This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.',
E_USER_DEPRECATED
);
}
$this->enforceLockedProperty(__FUNCTION__);
$this->preventCacheSlams = $preventCacheSlams;
return $this;
}
/**
* @deprecated This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.
* @return int
*/
public function getCacheSlamsTimeout(): int
{
return $this->cacheSlamsTimeout;
}
/**
* @deprecated This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.
* @param int $cacheSlamsTimeout
* @return ConfigurationOption
* @throws PhpfastcacheLogicException
*/
public function setCacheSlamsTimeout(int $cacheSlamsTimeout): static
{
if ($cacheSlamsTimeout !== $this->cacheSlamsTimeout) {
trigger_error(
'This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.',
E_USER_DEPRECATED
);
}
$this->enforceLockedProperty(__FUNCTION__);
$this->cacheSlamsTimeout = $cacheSlamsTimeout;
return $this;
}
/**
* @return bool
*/
public function isUseStaticItemCaching(): bool
{
return $this->useStaticItemCaching;
}
/**
* @param bool $useStaticItemCaching
* @return ConfigurationOption
* @throws PhpfastcacheLogicException
*/
public function setUseStaticItemCaching(bool $useStaticItemCaching): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->useStaticItemCaching = $useStaticItemCaching;
return $this;
}
/**
* @return object
*/
public function getSuperGlobalAccessor(): object
{
if (!isset($this->superGlobalAccessor)) {
$this->superGlobalAccessor = $this->getDefaultSuperGlobalAccessor();
}
return $this->superGlobalAccessor;
}
/**
* @param ?object $superGlobalAccessor
* @return static
* @throws PhpfastcacheInvalidArgumentException
* @throws PhpfastcacheLogicException
*/
public function setSuperGlobalAccessor(?object $superGlobalAccessor): static
{
$this->enforceLockedProperty(__FUNCTION__);
/**
* Symfony's implementation for users that want a good control of their code:
*
* $config['superGlobalAccessor'] = \Closure::fromCallable(static function(string $superGlobalName, string $keyName) use ($request) {
* return match ($superGlobalName) {
* 'SERVER' => $request->server->get($keyName),
* 'REQUEST' => $request->request->get($keyName),
* };
* });
*/
if ($superGlobalAccessor === null) {
$this->superGlobalAccessor = $this->getDefaultSuperGlobalAccessor();
} elseif (!\is_callable($superGlobalAccessor)) {
throw new PhpfastcacheInvalidArgumentException('The "superGlobalAccessor" callback must be callable using "__invoke" or \Closure implementation');
} else {
$this->superGlobalAccessor = $superGlobalAccessor;
}
return $this;
}
/**
* @return \Closure
* @SuppressWarnings(PHPMD.Superglobals)
*/
protected function getDefaultSuperGlobalAccessor(): \Closure
{
return \Closure::fromCallable(static function (string $superGlobalName, ?string $keyName = null): string|int|float|array|bool|null {
return match ($superGlobalName) {
'SERVER' => $keyName !== null ? $_SERVER[$keyName] ?? null : $_SERVER,
'REQUEST' => $keyName !== null ? $_REQUEST[$keyName] ?? null : $_REQUEST,
'COOKIE' => $keyName !== null ? $_COOKIE[$keyName] ?? null : $_COOKIE,
default => null,
};
});
}
}