Run 'compose update'
This commit is contained in:
@ -1,3 +1,30 @@
|
||||
# Changelog 4.0.5 (2020-03-15)
|
||||
|
||||
- fix "symfony/var-exporter" for OpCache
|
||||
|
||||
# Changelog 4.0.4 (2020-03-15)
|
||||
|
||||
- use "symfony/var-exporter" for OpCache
|
||||
|
||||
-> better performance, because we don't need to serialize the data
|
||||
|
||||
-> but it's optional, because it required PHP >= 7.1
|
||||
|
||||
# Changelog 4.0.3 (2019-11-18)
|
||||
|
||||
- "iSerializer" -> add "getName()"
|
||||
- fix usage of "file_put_contents"
|
||||
- fix errors from php 7.4
|
||||
- fix return of "CacheChain" (return true, if one cache-instance was successfully)
|
||||
|
||||
|
||||
# Changelog 4.0.2 (2019-04-23)
|
||||
|
||||
- fix errors reported by phpstan (level 7)
|
||||
- fix for APC(u) + CLI usage
|
||||
- fix & new tests for "CacheChain" -> now accepts Cache objects instead of "iCache"
|
||||
|
||||
|
||||
# Changelog 4.0.1 (2019-03-03)
|
||||
|
||||
- hide "warning" about Zend OPcache API is restricted by "restrict_api"
|
||||
|
@ -27,6 +27,10 @@
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~6.0 || ~7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/var-exporter" : "~3.0 || ~4.0 || ~5.0",
|
||||
"predis/predis": "~1.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"voku\\cache\\": "src/voku/cache/"
|
||||
|
21
bundled-libs/voku/simple-cache/phpstan.neon
Normal file
21
bundled-libs/voku/simple-cache/phpstan.neon
Normal file
@ -0,0 +1,21 @@
|
||||
parameters:
|
||||
level: max
|
||||
paths:
|
||||
- %currentWorkingDirectory%/src/
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
checkMissingIterableValueType: false
|
||||
excludes_analyse:
|
||||
- %currentWorkingDirectory%/vendor/*
|
||||
- %currentWorkingDirectory%/tests/*
|
||||
autoload_files:
|
||||
- %currentWorkingDirectory%/vendor/autoload.php
|
||||
ignoreErrors:
|
||||
- '/always false/'
|
||||
- '/always true/'
|
||||
- '/Predis\\Client/'
|
||||
- '/Symfony\\Component\\VarExporter/'
|
||||
- '/Memcache(d)*/'
|
||||
- '/MEMCACHE_COMPRESSED/'
|
||||
- '/Function checkForDev not found\./'
|
||||
- '/Function msgpack/'
|
||||
- '/function unserialize expects array/'
|
@ -43,6 +43,8 @@ class AdapterApc implements iAdapter
|
||||
&&
|
||||
\ini_get('apc.enable_cli')
|
||||
) {
|
||||
\ini_set('apc.use_request_time', '0');
|
||||
|
||||
$this->installed = true;
|
||||
}
|
||||
}
|
||||
@ -85,12 +87,19 @@ class AdapterApc implements iAdapter
|
||||
* @param bool $limited - If $limited is TRUE, the return value will exclude the individual list of cache
|
||||
* entries. This is useful when trying to optimize calls for statistics gathering
|
||||
*
|
||||
* @return array|false
|
||||
* <p>Array of cached data (and meta-data) or FALSE on failure.</p>
|
||||
* @return array
|
||||
* <p>Array of cached data (and meta-data) or empty array on failure.</p>
|
||||
*/
|
||||
public function cacheInfo(string $type = '', bool $limited = false): array
|
||||
{
|
||||
return \apc_cache_info($type, $limited);
|
||||
/** @var array|false $return */
|
||||
$return = \apc_cache_info($type, $limited);
|
||||
|
||||
if ($return === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,6 +43,8 @@ class AdapterApcu implements iAdapter
|
||||
&&
|
||||
\ini_get('apc.enable_cli')
|
||||
) {
|
||||
\ini_set('apc.use_request_time', '0');
|
||||
|
||||
$this->installed = true;
|
||||
}
|
||||
}
|
||||
@ -84,12 +86,19 @@ class AdapterApcu implements iAdapter
|
||||
* @param bool $limited - If $limited is TRUE, the return value will exclude the individual list of cache
|
||||
* entries. This is useful when trying to optimize calls for statistics gathering
|
||||
*
|
||||
* @return array|false
|
||||
* <p>Array of cached data (and meta-data) or FALSE on failure.</p>
|
||||
* @return array
|
||||
* <p>Array of cached data (and meta-data) or empty array on failure.</p>
|
||||
*/
|
||||
public function cacheInfo(bool $limited = false): array
|
||||
{
|
||||
return \apcu_cache_info($limited);
|
||||
/** @var array|false $return */
|
||||
$return = \apcu_cache_info($limited);
|
||||
|
||||
if ($return === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ class AdapterArray implements iAdapter
|
||||
private static $values = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, array<int>>
|
||||
*/
|
||||
private static $expired = [];
|
||||
|
||||
@ -89,7 +89,7 @@ class AdapterArray implements iAdapter
|
||||
{
|
||||
self::$values[$key] = $value;
|
||||
|
||||
if ($ttl !== null) {
|
||||
if ($ttl !== 0) {
|
||||
self::$expired[$key] = [\time(), $ttl];
|
||||
}
|
||||
|
||||
@ -114,6 +114,8 @@ class AdapterArray implements iAdapter
|
||||
}
|
||||
|
||||
list($time, $ttl) = self::$expired[$key];
|
||||
\assert(\is_int($time));
|
||||
\assert(\is_int($ttl));
|
||||
|
||||
if (\time() > ($time + $ttl)) {
|
||||
unset(self::$values[$key]);
|
||||
|
@ -34,7 +34,7 @@ abstract class AdapterFileAbstract implements iAdapter
|
||||
protected $fileMode = '0755';
|
||||
|
||||
/**
|
||||
* @param \callable|string|null $cacheDir
|
||||
* @param callable|string|null $cacheDir
|
||||
*/
|
||||
public function __construct($cacheDir = null)
|
||||
{
|
||||
@ -204,6 +204,8 @@ abstract class AdapterFileAbstract implements iAdapter
|
||||
* e.g. '0777', or '0755' ...
|
||||
*
|
||||
* @param string $fileMode
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFileMode($fileMode)
|
||||
{
|
||||
@ -243,4 +245,56 @@ abstract class AdapterFileAbstract implements iAdapter
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* copy&past from https://github.com/webimpress/safe-writer (thx @michalbundyra)
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $content
|
||||
* @param int|null $chmod
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function writeFile($file, $content, $chmod = null): bool
|
||||
{
|
||||
if (!$file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($chmod === null) {
|
||||
$chmod = \intval($this->fileMode, 8);
|
||||
}
|
||||
|
||||
$dir = \dirname($file);
|
||||
|
||||
$tmp = \tempnam($dir, 'wsw');
|
||||
if ($tmp === false) {
|
||||
throw Exception\RuntimeException::unableToCreateTemporaryFile($dir);
|
||||
}
|
||||
|
||||
if (\file_put_contents($tmp, $content) === false) {
|
||||
\unlink($tmp);
|
||||
|
||||
throw Exception\WriteContentException::unableToWriteContent($tmp);
|
||||
}
|
||||
|
||||
if (\chmod($tmp, $chmod & ~\umask()) === false) {
|
||||
\unlink($tmp);
|
||||
|
||||
throw Exception\ChmodException::unableToChangeChmod($tmp);
|
||||
}
|
||||
|
||||
// On windows try again if rename was not successful but target file is writable.
|
||||
/** @noinspection PhpUsageOfSilenceOperatorInspection */
|
||||
while (@\rename($tmp, $file) === false) {
|
||||
if (\is_writable($file) && \stripos(\PHP_OS, 'WIN') === 0) {
|
||||
continue;
|
||||
}
|
||||
\unlink($tmp);
|
||||
|
||||
throw Exception\RenameException::unableToMoveFile($tmp, $file);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ class AdapterFileSimple extends AdapterFileAbstract
|
||||
{
|
||||
const CACHE_FILE_PREFIX = '__simple_';
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
protected function getContext()
|
||||
{
|
||||
static $CONTEXT_CACHE = null;
|
||||
@ -74,16 +77,14 @@ class AdapterFileSimple extends AdapterFileAbstract
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
return (bool) \file_put_contents(
|
||||
return $this->writeFile(
|
||||
$this->getFileName($key),
|
||||
$this->serializer->serialize(
|
||||
[
|
||||
'value' => $value,
|
||||
'ttl' => $ttl ? $ttl + \time() : 0,
|
||||
]
|
||||
),
|
||||
0,
|
||||
$this->getContext()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
use Memcache;
|
||||
use voku\cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
@ -17,7 +18,7 @@ class AdapterMemcache implements iAdapter
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* @var \Memcache
|
||||
* @var Memcache
|
||||
*/
|
||||
private $memcache;
|
||||
|
||||
@ -29,19 +30,19 @@ class AdapterMemcache implements iAdapter
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param \Memcache|null $memcache
|
||||
* @param Memcache|null $memcache
|
||||
*/
|
||||
public function __construct($memcache = null)
|
||||
{
|
||||
if ($memcache instanceof \Memcache) {
|
||||
if ($memcache instanceof Memcache) {
|
||||
$this->setMemcache($memcache);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Memcache $memcache
|
||||
* @param Memcache $memcache
|
||||
*/
|
||||
public function setMemcache(\Memcache $memcache)
|
||||
public function setMemcache(Memcache $memcache)
|
||||
{
|
||||
$this->memcache = $memcache;
|
||||
$this->installed = true;
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
use Memcached;
|
||||
use voku\cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
@ -17,26 +18,26 @@ class AdapterMemcached implements iAdapter
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* @var \Memcached
|
||||
* @var Memcached
|
||||
*/
|
||||
private $memcached;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param \Memcached|null $memcached
|
||||
* @param Memcached|null $memcached
|
||||
*/
|
||||
public function __construct($memcached = null)
|
||||
{
|
||||
if ($memcached instanceof \Memcached) {
|
||||
if ($memcached instanceof Memcached) {
|
||||
$this->setMemcached($memcached);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Memcached $memcached
|
||||
* @param Memcached $memcached
|
||||
*/
|
||||
public function setMemcached(\Memcached $memcached)
|
||||
public function setMemcached(Memcached $memcached)
|
||||
{
|
||||
$this->memcached = $memcached;
|
||||
$this->installed = true;
|
||||
@ -90,7 +91,7 @@ class AdapterMemcached implements iAdapter
|
||||
public function set(string $key, $value): bool
|
||||
{
|
||||
// Make sure we are under the proper limit
|
||||
if (\strlen($this->memcached->getOption(\Memcached::OPT_PREFIX_KEY) . $key) > 250) {
|
||||
if (\strlen($this->memcached->getOption(Memcached::OPT_PREFIX_KEY) . $key) > 250) {
|
||||
throw new InvalidArgumentException('The passed cache key is over 250 bytes:' . \print_r($key, true));
|
||||
}
|
||||
|
||||
@ -111,18 +112,22 @@ class AdapterMemcached implements iAdapter
|
||||
|
||||
/**
|
||||
* Set the MemCached settings.
|
||||
*
|
||||
* @noinspection PhpUndefinedClassConstantInspection -> MSGPACK is not added into phpstorm stubs
|
||||
*/
|
||||
private function setSettings()
|
||||
{
|
||||
// Use faster compression if available
|
||||
if (\Memcached::HAVE_IGBINARY) {
|
||||
$this->memcached->setOption(\Memcached::OPT_SERIALIZER, \Memcached::SERIALIZER_IGBINARY);
|
||||
if (Memcached::HAVE_IGBINARY) {
|
||||
$this->memcached->setOption(Memcached::OPT_SERIALIZER, Memcached::SERIALIZER_IGBINARY);
|
||||
} elseif (\defined('Memcached::HAVE_MSGPACK') && Memcached::HAVE_MSGPACK) {
|
||||
$this->memcached->setOption(Memcached::OPT_SERIALIZER, Memcached::SERIALIZER_MSGPACK);
|
||||
}
|
||||
$this->memcached->setOption(\Memcached::OPT_DISTRIBUTION, \Memcached::DISTRIBUTION_CONSISTENT);
|
||||
$this->memcached->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
|
||||
$this->memcached->setOption(\Memcached::OPT_NO_BLOCK, true);
|
||||
$this->memcached->setOption(\Memcached::OPT_TCP_NODELAY, true);
|
||||
$this->memcached->setOption(\Memcached::OPT_COMPRESSION, false);
|
||||
$this->memcached->setOption(\Memcached::OPT_CONNECT_TIMEOUT, 2);
|
||||
$this->memcached->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
|
||||
$this->memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
|
||||
$this->memcached->setOption(Memcached::OPT_NO_BLOCK, true);
|
||||
$this->memcached->setOption(Memcached::OPT_TCP_NODELAY, true);
|
||||
$this->memcached->setOption(Memcached::OPT_COMPRESSION, false);
|
||||
$this->memcached->setOption(Memcached::OPT_CONNECT_TIMEOUT, 2);
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,10 @@ class AdapterOpCache extends AdapterFileSimple
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @noinspection PhpUndefinedClassInspection
|
||||
* @noinspection PhpUndefinedNamespaceInspection
|
||||
* @noinspection BadExceptionsProcessingInspection
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
@ -86,17 +90,23 @@ class AdapterOpCache extends AdapterFileSimple
|
||||
'value' => $value,
|
||||
'ttl' => $ttl ? $ttl + \time() : 0,
|
||||
];
|
||||
$content = \var_export($item, true);
|
||||
if (\class_exists('\Symfony\Component\VarExporter\VarExporter')) {
|
||||
try {
|
||||
$content = \Symfony\Component\VarExporter\VarExporter::export($item);
|
||||
} catch (\Symfony\Component\VarExporter\Exception\ExceptionInterface $e) {
|
||||
$content = \var_export($item, true);
|
||||
}
|
||||
} else {
|
||||
$content = \var_export($item, true);
|
||||
}
|
||||
|
||||
$content = '<?php return ' . $content . ';';
|
||||
|
||||
$cacheFile = $this->getFileName($key);
|
||||
|
||||
$result = (bool) \file_put_contents(
|
||||
$result = $this->writeFile(
|
||||
$cacheFile,
|
||||
$content,
|
||||
0,
|
||||
$this->getContext()
|
||||
$content
|
||||
);
|
||||
|
||||
if (
|
||||
|
@ -33,6 +33,8 @@ class AdapterPredis implements iAdapter
|
||||
|
||||
/**
|
||||
* @param Client $client
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPredisClient(Client $client)
|
||||
{
|
||||
@ -45,7 +47,7 @@ class AdapterPredis implements iAdapter
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return $this->client->exists($key);
|
||||
return (bool) $this->client->exists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,7 +71,7 @@ class AdapterPredis implements iAdapter
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
return $this->client->del($key);
|
||||
return (bool) $this->client->del($key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,6 +95,6 @@ class AdapterPredis implements iAdapter
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
return $this->client->setex($key, $ttl, $value);
|
||||
return (bool) $this->client->setex($key, $ttl, $value);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ namespace voku\cache;
|
||||
*/
|
||||
class AdapterXcache implements iAdapter
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,11 @@ class Cache implements iCache
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $unserialize_options = ['allowed_classes' => true];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@ -92,27 +97,30 @@ class Cache implements iCache
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param iAdapter|null $adapter
|
||||
* @param iSerializer|null $serializer
|
||||
* @param bool $checkForUsage <p>check for admin-session && check for
|
||||
* server-ip == client-ip
|
||||
* && check for dev</p>
|
||||
* @param bool $cacheEnabled <p>false === disable the cache (use it
|
||||
* e.g. for global settings)</p>
|
||||
* @param bool $isAdminSession <p>true === disable cache for this user
|
||||
* (use it e.g. for admin user settings)
|
||||
* @param bool $useCheckForAdminSession <p>use $isAdminSession flag or not</p>
|
||||
* @param bool $useCheckForDev <p>use checkForDev() or not</p>
|
||||
* @param bool $useCheckForServerIpIsClientIp <p>use check for server-ip == client-ip
|
||||
* or
|
||||
* not</p>
|
||||
* @param string $disableCacheGetParameter <p>set the _GET parameter for disabling
|
||||
* the cache, disable this check via empty
|
||||
* string</p>
|
||||
* @param CacheAdapterAutoManager $cacheAdapterManagerForAutoConnect <p>Overwrite some Adapters for the
|
||||
* auto-connect-function.</p>
|
||||
* @param bool $cacheAdapterManagerForAutoConnectOverwrite <p>true === Use only Adapters from your
|
||||
* "CacheAdapterManager".</p>
|
||||
* @param iAdapter|null $adapter
|
||||
* @param iSerializer|null $serializer
|
||||
* @param bool $checkForUsage <p>check for admin-session && check
|
||||
* for server-ip == client-ip
|
||||
* && check for dev</p>
|
||||
* @param bool $cacheEnabled <p>false === disable the cache (use
|
||||
* it
|
||||
* e.g. for global settings)</p>
|
||||
* @param bool $isAdminSession <p>true === disable cache for this
|
||||
* user
|
||||
* (use it e.g. for admin user settings)
|
||||
* @param bool $useCheckForAdminSession <p>use $isAdminSession flag or
|
||||
* not</p>
|
||||
* @param bool $useCheckForDev <p>use checkForDev() or not</p>
|
||||
* @param bool $useCheckForServerIpIsClientIp <p>use check for server-ip ==
|
||||
* client-ip or not</p>
|
||||
* @param string $disableCacheGetParameter <p>set the _GET parameter for
|
||||
* disabling the cache, disable this
|
||||
* check via empty string</p>
|
||||
* @param CacheAdapterAutoManager $cacheAdapterManagerForAutoConnect <p>Overwrite some Adapters for the
|
||||
* auto-connect-function.</p>
|
||||
* @param bool $cacheAdapterManagerForAutoConnectOverwrite <p>true === Use only Adapters from
|
||||
* your
|
||||
* "CacheAdapterManager".</p>
|
||||
*/
|
||||
public function __construct(
|
||||
iAdapter $adapter = null,
|
||||
@ -153,13 +161,20 @@ class Cache implements iCache
|
||||
$adapter = $this->autoConnectToAvailableCacheSystem($cacheAdapterManagerForAutoConnect, $cacheAdapterManagerForAutoConnectOverwrite);
|
||||
}
|
||||
|
||||
// INFO: Memcache(d) has his own "serializer", so don't use it twice
|
||||
if (!\is_object($serializer) && $serializer === null) {
|
||||
if (
|
||||
$adapter instanceof AdapterMemcached
|
||||
||
|
||||
$adapter instanceof AdapterMemcache
|
||||
) {
|
||||
// INFO: Memcache(d) has his own "serializer", so don't use it twice
|
||||
$serializer = new SerializerNo();
|
||||
} elseif (
|
||||
$adapter instanceof AdapterOpCache
|
||||
&&
|
||||
\class_exists('\Symfony\Component\VarExporter\VarExporter')
|
||||
) {
|
||||
// INFO: opcache + Symfony-VarExporter don't need any "serializer"
|
||||
$serializer = new SerializerNo();
|
||||
} else {
|
||||
// set default serializer
|
||||
@ -177,17 +192,31 @@ class Cache implements iCache
|
||||
$this->setCacheIsReady(true);
|
||||
|
||||
$this->adapter = $adapter;
|
||||
|
||||
$this->serializer = $serializer;
|
||||
|
||||
$this->serializer->setUnserializeOptions($this->unserialize_options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUnserializeOptions(array $array = [])
|
||||
{
|
||||
$this->unserialize_options = $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-connect to the available cache-system on the server.
|
||||
*
|
||||
* @param CacheAdapterAutoManager $cacheAdapterManagerForAutoConnect <p>Overwrite some Adapters for the
|
||||
* auto-connect-function.</p>
|
||||
* @param bool $cacheAdapterManagerForAutoConnectOverwrite <p>true === Use only Adapters from your
|
||||
* "CacheAdapterManager".</p>
|
||||
* auto-connect-function.</p>
|
||||
* @param bool $cacheAdapterManagerForAutoConnectOverwrite <p>true === Use only Adapters from
|
||||
* your
|
||||
* "CacheAdapterManager".</p>
|
||||
*
|
||||
* @return iAdapter
|
||||
*/
|
||||
@ -381,7 +410,11 @@ class Cache implements iCache
|
||||
}
|
||||
|
||||
$serialized = $this->adapter->get($storeKey);
|
||||
$value = $serialized && $this->serializer ? $this->serializer->unserialize($serialized) : null;
|
||||
if ($this->serializer && $this->serializer instanceof SerializerNo) {
|
||||
$value = $serialized;
|
||||
} else {
|
||||
$value = $serialized && $this->serializer ? $this->serializer->unserialize($serialized) : null;
|
||||
}
|
||||
|
||||
self::$STATIC_CACHE_COUNTER[$storeKey]++;
|
||||
|
||||
@ -468,7 +501,7 @@ class Cache implements iCache
|
||||
* @param mixed $value
|
||||
* @param \DateInterval|int|null $ttl
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@ -493,7 +526,6 @@ class Cache implements iCache
|
||||
if ($ttl) {
|
||||
if ($ttl instanceof \DateInterval) {
|
||||
// Converting to a TTL in seconds
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
$ttl = (new \DateTimeImmutable('now'))->add($ttl)->getTimestamp() - \time();
|
||||
}
|
||||
|
||||
@ -593,6 +625,8 @@ class Cache implements iCache
|
||||
|
||||
/**
|
||||
* Set the default-prefix via "SERVER"-var + "SESSION"-language.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTheDefaultPrefix(): string
|
||||
{
|
||||
@ -600,18 +634,21 @@ class Cache implements iCache
|
||||
($_SERVER['THEME'] ?? '') . '_' .
|
||||
($_SERVER['STAGE'] ?? '') . '_' .
|
||||
($_SESSION['language'] ?? '') . '_' .
|
||||
($_SESSION['language_extra'] ?? '');
|
||||
($_SESSION['language_extra'] ?? '') . '_' .
|
||||
\PHP_VERSION_ID . '_' .
|
||||
($this->serializer ? $this->serializer->getName() : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current adapter class-name.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @psalm-return class-string|string
|
||||
*/
|
||||
public function getUsedAdapterClassName(): string
|
||||
{
|
||||
if ($this->adapter) {
|
||||
/** @noinspection GetClassUsageInspection */
|
||||
return \get_class($this->adapter);
|
||||
}
|
||||
|
||||
@ -622,11 +659,12 @@ class Cache implements iCache
|
||||
* Get the current serializer class-name.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @psalm-return class-string|string
|
||||
*/
|
||||
public function getUsedSerializerClassName(): string
|
||||
{
|
||||
if ($this->serializer) {
|
||||
/** @noinspection GetClassUsageInspection */
|
||||
return \get_class($this->serializer);
|
||||
}
|
||||
|
||||
@ -640,6 +678,7 @@ class Cache implements iCache
|
||||
*/
|
||||
public function isCacheActiveForTheCurrentUser(): bool
|
||||
{
|
||||
// init
|
||||
$active = true;
|
||||
|
||||
// test the cache, with this GET-parameter
|
||||
@ -685,6 +724,8 @@ class Cache implements iCache
|
||||
* enable / disable the cache
|
||||
*
|
||||
* @param bool $isActive
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setActive(bool $isActive)
|
||||
{
|
||||
@ -695,6 +736,8 @@ class Cache implements iCache
|
||||
* Set "isReady" state.
|
||||
*
|
||||
* @param bool $isReady
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setCacheIsReady(bool $isReady)
|
||||
{
|
||||
@ -707,6 +750,8 @@ class Cache implements iCache
|
||||
* WARNING: Do not use if you don't know what you do. Because this will overwrite the default prefix.
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPrefix(string $prefix)
|
||||
{
|
||||
@ -717,6 +762,8 @@ class Cache implements iCache
|
||||
* Set the static-hit-counter: Who often do we hit the cache, before we use static cache?
|
||||
*
|
||||
* @param int $staticCacheHitCounter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setStaticCacheHitCounter(int $staticCacheHitCounter)
|
||||
{
|
||||
|
@ -22,6 +22,8 @@ class CacheAdapterAutoManager
|
||||
* @param string $adapter
|
||||
* @param callable|null $callableFunction
|
||||
*
|
||||
* @psalm-param class-string $adapter
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return $this
|
||||
@ -29,8 +31,7 @@ class CacheAdapterAutoManager
|
||||
public function addAdapter(
|
||||
string $adapter,
|
||||
callable $callableFunction = null
|
||||
): self
|
||||
{
|
||||
): self {
|
||||
$this->validateAdapter($adapter);
|
||||
$this->validateCallable($callableFunction);
|
||||
|
||||
@ -55,7 +56,7 @@ class CacheAdapterAutoManager
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return CacheAdapterAutoManager
|
||||
* @return self
|
||||
*/
|
||||
public function merge(self $adapterManager): self
|
||||
{
|
||||
@ -80,7 +81,11 @@ class CacheAdapterAutoManager
|
||||
/**
|
||||
* @param string $replaceAdapter
|
||||
*
|
||||
* @psalm-param class-string $replaceAdapter
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function validateAdapter(string $replaceAdapter)
|
||||
{
|
||||
@ -95,6 +100,8 @@ class CacheAdapterAutoManager
|
||||
* @param callable $callableFunction
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function validateCallable(callable $callableFunction = null)
|
||||
{
|
||||
@ -170,6 +177,7 @@ class CacheAdapterAutoManager
|
||||
) {
|
||||
/** @noinspection PhpUndefinedNamespaceInspection */
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
/** @noinspection PhpFullyQualifiedNameUsageInspection */
|
||||
$redis = new \Predis\Client(
|
||||
[
|
||||
'scheme' => 'tcp',
|
||||
|
@ -7,7 +7,7 @@ namespace voku\cache;
|
||||
class CacheChain implements iCache
|
||||
{
|
||||
/**
|
||||
* @var array|iCache[]
|
||||
* @var Cache[]
|
||||
*/
|
||||
private $caches = [];
|
||||
|
||||
@ -40,17 +40,13 @@ class CacheChain implements iCache
|
||||
/**
|
||||
* add cache
|
||||
*
|
||||
* @param iCache $cache
|
||||
* @param bool $prepend
|
||||
* @param Cache $cache
|
||||
* @param bool $prepend
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @return void
|
||||
*/
|
||||
public function addCache(iCache $cache, $prepend = true)
|
||||
public function addCache(Cache $cache, $prepend = true)
|
||||
{
|
||||
if ($this === $cache) {
|
||||
throw new \InvalidArgumentException('loop-error, put into other cache');
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
\array_unshift($this->caches, $cache);
|
||||
} else {
|
||||
@ -72,6 +68,22 @@ class CacheChain implements iCache
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "isReady" state.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getCacheIsReady(): bool
|
||||
{
|
||||
foreach ($this->caches as $cache) {
|
||||
if (!$cache->getCacheIsReady()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -84,7 +96,7 @@ class CacheChain implements iCache
|
||||
$results[] = $cache->setItem($key, $value, $ttl);
|
||||
}
|
||||
|
||||
return !\in_array(false, $results, true);
|
||||
return \in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,12 +107,27 @@ class CacheChain implements iCache
|
||||
// init
|
||||
$results = [];
|
||||
|
||||
/* @var $cache iCache */
|
||||
foreach ($this->caches as $cache) {
|
||||
$results[] = $cache->setItemToDate($key, $value, $date);
|
||||
}
|
||||
|
||||
return !\in_array(false, $results, true);
|
||||
return \in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* !!! Set the prefix. !!!
|
||||
*
|
||||
* WARNING: Do not use if you don't know what you do. Because this will overwrite the default prefix.
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPrefix(string $prefix)
|
||||
{
|
||||
foreach ($this->caches as $cache) {
|
||||
$cache->setPrefix($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,7 +142,7 @@ class CacheChain implements iCache
|
||||
$results[] = $cache->removeItem($key);
|
||||
}
|
||||
|
||||
return !\in_array(false, $results, true);
|
||||
return \in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,6 +171,6 @@ class CacheChain implements iCache
|
||||
$results[] = $cache->removeAll();
|
||||
}
|
||||
|
||||
return !\in_array(false, $results, true);
|
||||
return \in_array(true, $results, true);
|
||||
}
|
||||
}
|
||||
|
18
bundled-libs/voku/simple-cache/src/voku/cache/Exception/ChmodException.php
vendored
Normal file
18
bundled-libs/voku/simple-cache/src/voku/cache/Exception/ChmodException.php
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache\Exception;
|
||||
|
||||
final class ChmodException extends \RuntimeException implements FileErrorExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function unableToChangeChmod($file)
|
||||
{
|
||||
return new self(\sprintf('Could not change chmod of the file "%s"', $file));
|
||||
}
|
||||
}
|
9
bundled-libs/voku/simple-cache/src/voku/cache/Exception/FileErrorExceptionInterface.php
vendored
Normal file
9
bundled-libs/voku/simple-cache/src/voku/cache/Exception/FileErrorExceptionInterface.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache\Exception;
|
||||
|
||||
interface FileErrorExceptionInterface
|
||||
{
|
||||
}
|
24
bundled-libs/voku/simple-cache/src/voku/cache/Exception/RenameException.php
vendored
Normal file
24
bundled-libs/voku/simple-cache/src/voku/cache/Exception/RenameException.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache\Exception;
|
||||
|
||||
final class RenameException extends \RuntimeException implements FileErrorExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function unableToMoveFile($source, $target)
|
||||
{
|
||||
return new self(\sprintf(
|
||||
'Could not move file "%s" to location "%s": '
|
||||
. 'either the source file is not readable, or the destination is not writable',
|
||||
$source,
|
||||
$target
|
||||
));
|
||||
}
|
||||
}
|
18
bundled-libs/voku/simple-cache/src/voku/cache/Exception/RuntimeException.php
vendored
Normal file
18
bundled-libs/voku/simple-cache/src/voku/cache/Exception/RuntimeException.php
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache\Exception;
|
||||
|
||||
final class RuntimeException extends \RuntimeException implements FileErrorExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $dir
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function unableToCreateTemporaryFile($dir)
|
||||
{
|
||||
return new self(\sprintf('Could not create temporary file in directory "%s"', $dir));
|
||||
}
|
||||
}
|
18
bundled-libs/voku/simple-cache/src/voku/cache/Exception/WriteContentException.php
vendored
Normal file
18
bundled-libs/voku/simple-cache/src/voku/cache/Exception/WriteContentException.php
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache\Exception;
|
||||
|
||||
final class WriteContentException extends \RuntimeException implements FileErrorExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function unableToWriteContent($file)
|
||||
{
|
||||
return new self(\sprintf('Could not write content to the file "%s"', $file));
|
||||
}
|
||||
}
|
@ -9,6 +9,11 @@ namespace voku\cache;
|
||||
*/
|
||||
class SerializerDefault implements iSerializer
|
||||
{
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
private $unserialize_options;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -17,11 +22,34 @@ class SerializerDefault implements iSerializer
|
||||
return \serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'default';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($value)
|
||||
{
|
||||
if ($this->unserialize_options !== null) {
|
||||
return \unserialize($value, $this->unserialize_options);
|
||||
}
|
||||
|
||||
/** @noinspection UnserializeExploitsInspection */
|
||||
return \unserialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUnserializeOptions(array $options)
|
||||
{
|
||||
$this->unserialize_options = $options;
|
||||
}
|
||||
}
|
||||
|
@ -14,16 +14,42 @@ class SerializerIgbinary implements iSerializer
|
||||
*/
|
||||
public static $_exists_igbinary;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
private $unserialize_options;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name = '';
|
||||
|
||||
/**
|
||||
* SerializerIgbinary constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$_exists_igbinary = (
|
||||
\function_exists('igbinary_serialize')
|
||||
&&
|
||||
\function_exists('igbinary_unserialize')
|
||||
);
|
||||
if (self::$_exists_igbinary === null) {
|
||||
self::$_exists_igbinary = (
|
||||
\function_exists('igbinary_serialize')
|
||||
&&
|
||||
\function_exists('igbinary_unserialize')
|
||||
);
|
||||
}
|
||||
|
||||
if (self::$_exists_igbinary) {
|
||||
$this->name = 'igbinary';
|
||||
} else {
|
||||
$this->name = 'default';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,6 +59,7 @@ class SerializerIgbinary implements iSerializer
|
||||
{
|
||||
if (self::$_exists_igbinary === true) {
|
||||
/** @noinspection PhpUndefinedFunctionInspection */
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
return \igbinary_serialize($value);
|
||||
}
|
||||
|
||||
@ -47,10 +74,26 @@ class SerializerIgbinary implements iSerializer
|
||||
{
|
||||
if (self::$_exists_igbinary === true) {
|
||||
/** @noinspection PhpUndefinedFunctionInspection */
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
return \igbinary_unserialize($value);
|
||||
}
|
||||
|
||||
// fallback
|
||||
if ($this->unserialize_options !== null) {
|
||||
return \unserialize($value, $this->unserialize_options);
|
||||
}
|
||||
|
||||
/** @noinspection UnserializeExploitsInspection */
|
||||
return \unserialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUnserializeOptions(array $options)
|
||||
{
|
||||
$this->unserialize_options = $options;
|
||||
}
|
||||
}
|
||||
|
97
bundled-libs/voku/simple-cache/src/voku/cache/SerializerMsgpack.php
vendored
Normal file
97
bundled-libs/voku/simple-cache/src/voku/cache/SerializerMsgpack.php
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* SerializerMsgpack: serialize / unserialize
|
||||
*/
|
||||
class SerializerMsgpack implements iSerializer
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $_exists_msgpack;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
private $unserialize_options;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name = '';
|
||||
|
||||
/**
|
||||
* SerializerIgbinary constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (self::$_exists_msgpack === null) {
|
||||
self::$_exists_msgpack = (
|
||||
\function_exists('msgpack_pack')
|
||||
&&
|
||||
\function_exists('msgpack_unpack')
|
||||
);
|
||||
}
|
||||
|
||||
if (self::$_exists_msgpack) {
|
||||
$this->name = 'msgpack';
|
||||
} else {
|
||||
$this->name = 'default';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize($value)
|
||||
{
|
||||
if (self::$_exists_msgpack === true) {
|
||||
/** @noinspection PhpUndefinedFunctionInspection */
|
||||
return \msgpack_pack($value);
|
||||
}
|
||||
|
||||
// fallback
|
||||
return \serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($value)
|
||||
{
|
||||
if (self::$_exists_msgpack === true) {
|
||||
/** @noinspection PhpUndefinedFunctionInspection */
|
||||
return \msgpack_unpack($value);
|
||||
}
|
||||
|
||||
// fallback
|
||||
if ($this->unserialize_options !== null) {
|
||||
return \unserialize($value, $this->unserialize_options);
|
||||
}
|
||||
|
||||
/** @noinspection UnserializeExploitsInspection */
|
||||
return \unserialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUnserializeOptions(array $options)
|
||||
{
|
||||
$this->unserialize_options = $options;
|
||||
}
|
||||
}
|
@ -24,4 +24,22 @@ class SerializerNo implements iSerializer
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'no';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUnserializeOptions(array $options)
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,8 @@ interface iAdapter
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed|null <p>will return NULL if the key not exists</p>
|
||||
* @return mixed|null
|
||||
* <p>will return NULL if the key not exists</p>
|
||||
*/
|
||||
public function get(string $key);
|
||||
|
||||
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
* iCache: cache-global interface
|
||||
*/
|
||||
@ -34,11 +36,11 @@ interface iCache
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTimeInterface $date
|
||||
* @param DateTimeInterface $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setItemToDate(string $key, $value, \DateTimeInterface $date): bool;
|
||||
public function setItemToDate(string $key, $value, DateTimeInterface $date): bool;
|
||||
|
||||
/**
|
||||
* remove item
|
||||
|
@ -10,16 +10,28 @@ namespace voku\cache;
|
||||
interface iSerializer
|
||||
{
|
||||
/**
|
||||
* serialize
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize($value);
|
||||
|
||||
/**
|
||||
* unserialize
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function unserialize($value);
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUnserializeOptions(array $options);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string;
|
||||
}
|
||||
|
Reference in New Issue
Block a user