Add voku/simplecache as alternative to Cache/Lite and use it cache
Cache/Lite is abandoned
This commit is contained in:
parent
fc02b0306b
commit
d52f0004a4
48
bundled-libs/voku/simple-cache/CHANGELOG.md
Normal file
48
bundled-libs/voku/simple-cache/CHANGELOG.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Changelog 3.2.2 (2018-12-21)
|
||||
|
||||
- fix APC(u) detection for CLI usage
|
||||
|
||||
|
||||
# Changelog 3.2.1 (2018-12-20)
|
||||
|
||||
- use phpcs fixer
|
||||
|
||||
|
||||
# Changelog 3.2.0 (2018-12-03)
|
||||
|
||||
- "AdapterOpCache" -> use "opcache_compile_file()"
|
||||
- add "AdapterFileSimple" + tests
|
||||
- "Cache" -> add the possibility to disable the cache behavior via constructor() -> "disableCacheGetParameter, useCheckForAdminSession, useCheckForServerIpIsClientIp, useCheckForDev"
|
||||
|
||||
|
||||
# Changelog 3.1.1 (2018-01-07)
|
||||
|
||||
- "AdapterApcu" -> fixed php-warning from "apcu_clear_cache()"
|
||||
|
||||
|
||||
# Changelog 3.1.0 (2018-01-07)
|
||||
|
||||
- "AdapterOpCache" -> added
|
||||
- "AdapterFile" -> remove duplicate file-get code
|
||||
|
||||
|
||||
# Changelog 3.0.2 (2017-12-14)
|
||||
|
||||
- "AdapterFile" -> fix php warning
|
||||
|
||||
|
||||
# Chabgelog 3.0.1 (2017-12-01)
|
||||
|
||||
- fix return from the "CacheChain"-class
|
||||
- update phpunit-config
|
||||
|
||||
|
||||
# Changelog 3.0.0 (2017-11-25)
|
||||
|
||||
- drop support for PHP < 7.0
|
||||
- use "strict_types"
|
||||
|
||||
|
||||
# Changelog 2.4.0 (2017-10-06)
|
||||
|
||||
- add support for PSR-16
|
19
bundled-libs/voku/simple-cache/LICENSE
Normal file
19
bundled-libs/voku/simple-cache/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015 Lars Moelleken
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
105
bundled-libs/voku/simple-cache/README.md
Normal file
105
bundled-libs/voku/simple-cache/README.md
Normal file
@ -0,0 +1,105 @@
|
||||
[](https://travis-ci.org/voku/simple-cache)
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fvoku%2Fsimple-cache?ref=badge_shield)
|
||||
[](https://coveralls.io/github/voku/simple-cache?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/voku/simple-cache/?branch=master)
|
||||
[](https://www.codacy.com/app/voku/simple-cache)
|
||||
[](https://packagist.org/packages/voku/simple-cache)
|
||||
[](https://packagist.org/packages/voku/simple-cache)
|
||||
[](https://packagist.org/packages/voku/simple-cache)
|
||||
|
||||
|
||||
:zap: Simple Cache Class
|
||||
===================
|
||||
|
||||
This is a simple Cache Abstraction Layer for PHP >= 7.0 that provides a simple interaction
|
||||
with your cache-server. You can define the Adapter / Serializer in the "constructor" or the class will auto-detect you server-cache in this order:
|
||||
|
||||
1. Memcached / Memcache
|
||||
2. Redis
|
||||
3. Xcache
|
||||
4. APC / APCu
|
||||
5. OpCache (via PHP-files)
|
||||
6. Static-PHP-Cache
|
||||
|
||||
## Get "Simple Cache"
|
||||
|
||||
You can download it from here, or require it using [composer](https://packagist.org/packages/voku/simple-cache).
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"voku/simple-cache": "3.*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Install via "composer require"
|
||||
|
||||
```shell
|
||||
composer require voku/simple-cache
|
||||
composer require predis/predis # if you will use redis as cache, then add predis
|
||||
```
|
||||
|
||||
|
||||
## Quick Start
|
||||
|
||||
```php
|
||||
use voku\cache\Cache;
|
||||
|
||||
require_once 'composer/autoload.php';
|
||||
|
||||
$cache = new Cache();
|
||||
$ttl = 3600; // 60s * 60 = 1h
|
||||
$cache->setItem('foo', 'bar', $ttl);
|
||||
$bar = $cache->getItem('foo');
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```php
|
||||
use voku\cache\Cache;
|
||||
|
||||
$cache = new Cache();
|
||||
|
||||
if ($cache->getCacheIsReady() === true && $cache->existsItem('foo')) {
|
||||
return $cache->getItem('foo');
|
||||
} else {
|
||||
$bar = someSpecialFunctionsWithAReturnValue();
|
||||
$cache->setItem('foo', $bar);
|
||||
return $bar;
|
||||
}
|
||||
```
|
||||
|
||||
If you have an heavy task e.g. a really-big-loop, then you can also use static-cache.
|
||||
But keep in mind, that this will be stored into PHP (it needs more memory).
|
||||
|
||||
```php
|
||||
use voku\cache\Cache;
|
||||
|
||||
$cache = new Cache();
|
||||
|
||||
if ($cache->getCacheIsReady() === true && $cache->existsItem('foo')) {
|
||||
for ($i = 0; $i <= 100000; $i++) {
|
||||
echo $this->cache->getItem('foo', 3); // use also static-php-cache, when we hit the cache 3-times
|
||||
}
|
||||
return $cache->getItem('foo');
|
||||
} else {
|
||||
$bar = someSpecialFunctionsWithAReturnValue();
|
||||
$cache->setItem('foo', $bar);
|
||||
return $bar;
|
||||
}
|
||||
```
|
||||
|
||||
PS: By default, the static cache is also used by >= 10 cache hits. But you can configure
|
||||
this behavior via $cache->setStaticCacheHitCounter(INT).
|
||||
|
||||
## No-Cache for the admin or a specific ip-address
|
||||
|
||||
If you use the parameter "$checkForUser" (=== true) in the constructor, then the cache isn't used for the admin-session.
|
||||
|
||||
-> You can also overwrite the check for the user, if you add a global function named "checkForDev()".
|
||||
|
||||
|
||||
## License
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fvoku%2Fsimple-cache?ref=badge_large)
|
35
bundled-libs/voku/simple-cache/composer.json
Normal file
35
bundled-libs/voku/simple-cache/composer.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "voku/simple-cache",
|
||||
"description": "Simple Cache library",
|
||||
"keywords": [
|
||||
"php",
|
||||
"cache",
|
||||
"simple cache",
|
||||
"caching"
|
||||
],
|
||||
"type": "library",
|
||||
"homepage": "https://github.com/voku/simple-cache",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Lars Moelleken",
|
||||
"homepage": "http://www.moelleken.org/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"provide": {
|
||||
"psr/simple-cache-implementation": "1.0"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"psr/simple-cache": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~6.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"voku\\cache\\": "src/voku/cache/"
|
||||
}
|
||||
}
|
||||
}
|
158
bundled-libs/voku/simple-cache/src/voku/cache/AdapterApc.php
vendored
Normal file
158
bundled-libs/voku/simple-cache/src/voku/cache/AdapterApc.php
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* AdapterApc: a APC-Cache adapter
|
||||
*
|
||||
* @see http://php.net/manual/de/book.apc.php
|
||||
*/
|
||||
class AdapterApc implements iAdapter
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $debug = false;
|
||||
|
||||
/**
|
||||
* __construct()
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (
|
||||
\PHP_SAPI !== 'cli'
|
||||
&&
|
||||
\function_exists('apc_store') === true
|
||||
&&
|
||||
\ini_get('apc.enabled')
|
||||
) {
|
||||
$this->installed = true;
|
||||
}
|
||||
|
||||
if (
|
||||
\PHP_SAPI === 'cli'
|
||||
&&
|
||||
\function_exists('apc_store') === true
|
||||
&&
|
||||
\ini_get('apc.enable_cli')
|
||||
) {
|
||||
$this->installed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if apc-cache exists.
|
||||
*
|
||||
* WARNING: use $this->exists($key) instead
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function apc_cache_exists($key): bool
|
||||
{
|
||||
return (bool) \apc_fetch($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the APC cache by type.
|
||||
*
|
||||
* @param string $type - If $type is "user", the user cache will be cleared; otherwise,
|
||||
* the system cache (cached files) will be cleared
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function cacheClear(string $type): bool
|
||||
{
|
||||
return (bool) \apc_clear_cache($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves cached information from APC's data store
|
||||
*
|
||||
* @param string $type - If $type is "user", information about the user cache will be returned
|
||||
* @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|bool <p>Array of cached data (and meta-data) or FALSE on failure.</p>
|
||||
*/
|
||||
public function cacheInfo(string $type = '', bool $limited = false): array
|
||||
{
|
||||
return \apc_cache_info($type, $limited);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
if (\function_exists('apc_exists')) {
|
||||
return (bool) \apc_exists($key);
|
||||
}
|
||||
|
||||
return $this->apc_cache_exists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
if ($this->exists($key)) {
|
||||
return \apc_fetch($key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
return (bool) \apc_delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
return (bool) ($this->cacheClear('system') && $this->cacheClear('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set(string $key, $value): bool
|
||||
{
|
||||
return (bool) \apc_store($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $data, int $ttl = 0): bool
|
||||
{
|
||||
return (bool) \apc_store($key, $data, $ttl);
|
||||
}
|
||||
}
|
153
bundled-libs/voku/simple-cache/src/voku/cache/AdapterApcu.php
vendored
Normal file
153
bundled-libs/voku/simple-cache/src/voku/cache/AdapterApcu.php
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* AdapterApcu: a APCu-Cache adapter
|
||||
*
|
||||
* @see http://php.net/manual/de/book.apcu.php
|
||||
*/
|
||||
class AdapterApcu implements iAdapter
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $debug = false;
|
||||
|
||||
/**
|
||||
* __construct()
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (
|
||||
\PHP_SAPI !== 'cli'
|
||||
&&
|
||||
\function_exists('apcu_store') === true
|
||||
&&
|
||||
\ini_get('apc.enabled')
|
||||
) {
|
||||
$this->installed = true;
|
||||
}
|
||||
|
||||
if (
|
||||
\PHP_SAPI === 'cli'
|
||||
&&
|
||||
\function_exists('apcu_store') === true
|
||||
&&
|
||||
\ini_get('apc.enable_cli')
|
||||
) {
|
||||
$this->installed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if apcu-cache exists.
|
||||
*
|
||||
* WARNING: we only keep this method for compatibly-reasons
|
||||
* -> use ->exists($key)
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function apcu_cache_exists($key): bool
|
||||
{
|
||||
return $this->exists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the APCu cache by type.
|
||||
*
|
||||
* @param string $type <p>WARNING: is not used in APCu only valid for APC</p>
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function cacheClear(string $type): bool
|
||||
{
|
||||
return (bool) \apcu_clear_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves cached information from APCu's data store
|
||||
*
|
||||
* @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|bool <p>Array of cached data (and meta-data) or FALSE on failure.</p>
|
||||
*/
|
||||
public function cacheInfo(bool $limited = false): array
|
||||
{
|
||||
return \apcu_cache_info($limited);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return (bool) \apcu_exists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
if ($this->exists($key)) {
|
||||
return \apcu_fetch($key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
return (bool) \apcu_delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
return (bool) ($this->cacheClear('system') && $this->cacheClear('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set(string $key, $value): bool
|
||||
{
|
||||
return (bool) \apcu_store($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $data, int $ttl = 0): bool
|
||||
{
|
||||
return (bool) \apcu_store($key, $data, $ttl);
|
||||
}
|
||||
}
|
128
bundled-libs/voku/simple-cache/src/voku/cache/AdapterArray.php
vendored
Normal file
128
bundled-libs/voku/simple-cache/src/voku/cache/AdapterArray.php
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* AdapterArray: simple array-cache adapter
|
||||
*/
|
||||
class AdapterArray implements iAdapter
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $values = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $expired = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
$this->removeExpired($key);
|
||||
|
||||
return \array_key_exists($key, self::$values);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
return $this->exists($key) ? self::$values[$key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
$this->removeExpired($key);
|
||||
|
||||
if (\array_key_exists($key, self::$values) === true) {
|
||||
unset(self::$values[$key]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
self::$values = [];
|
||||
self::$expired = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set(string $key, $value): bool
|
||||
{
|
||||
self::$values[$key] = $value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
self::$values[$key] = $value;
|
||||
|
||||
if ($ttl !== null) {
|
||||
self::$expired[$key] = [\time(), $ttl];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove expired cache.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function removeExpired($key): bool
|
||||
{
|
||||
if (
|
||||
\array_key_exists($key, self::$expired) === false
|
||||
||
|
||||
\array_key_exists($key, self::$values) === false
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
list($time, $ttl) = self::$expired[$key];
|
||||
|
||||
if (\time() > ($time + $ttl)) {
|
||||
unset(self::$values[$key]);
|
||||
}
|
||||
|
||||
if (!isset(self::$values[$key])) {
|
||||
unset(self::$expired[$key]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
93
bundled-libs/voku/simple-cache/src/voku/cache/AdapterFile.php
vendored
Normal file
93
bundled-libs/voku/simple-cache/src/voku/cache/AdapterFile.php
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* AdapterFile: File-adapter
|
||||
*/
|
||||
class AdapterFile extends AdapterFileAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
$path = $this->getFileName($key);
|
||||
|
||||
if (
|
||||
\file_exists($path) === false
|
||||
||
|
||||
\filesize($path) === 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// init
|
||||
$string = '';
|
||||
|
||||
/** @noinspection PhpUsageOfSilenceOperatorInspection */
|
||||
$fp = @\fopen($path, 'rb');
|
||||
if ($fp && \flock($fp, \LOCK_SH | \LOCK_NB)) {
|
||||
while (!\feof($fp)) {
|
||||
$line = \fgets($fp);
|
||||
$string .= $line;
|
||||
}
|
||||
\flock($fp, \LOCK_UN);
|
||||
}
|
||||
if ($fp) {
|
||||
\fclose($fp);
|
||||
}
|
||||
|
||||
if (!$string) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $this->serializer->unserialize($string);
|
||||
|
||||
if (!$data || !$this->validateDataFromCache($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->ttlHasExpired($data['ttl']) === true) {
|
||||
$this->remove($key);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
$item = $this->serializer->serialize(
|
||||
[
|
||||
'value' => $value,
|
||||
'ttl' => $ttl ? $ttl + \time() : 0,
|
||||
]
|
||||
);
|
||||
|
||||
// init
|
||||
$octetWritten = false;
|
||||
|
||||
$cacheFile = $this->getFileName($key);
|
||||
|
||||
// Open the file for writing only. If the file does not exist, it is created.
|
||||
// If it exists, it is neither truncated, nor the call to this function fails.
|
||||
/** @noinspection PhpUsageOfSilenceOperatorInspection */
|
||||
$fp = @\fopen($cacheFile, 'cb');
|
||||
if ($fp && \flock($fp, \LOCK_EX | \LOCK_NB)) {
|
||||
\ftruncate($fp, 0);
|
||||
$octetWritten = \fwrite($fp, $item);
|
||||
\fflush($fp);
|
||||
\flock($fp, \LOCK_UN);
|
||||
}
|
||||
\fclose($fp);
|
||||
|
||||
return $octetWritten !== false;
|
||||
}
|
||||
}
|
242
bundled-libs/voku/simple-cache/src/voku/cache/AdapterFileAbstract.php
vendored
Normal file
242
bundled-libs/voku/simple-cache/src/voku/cache/AdapterFileAbstract.php
vendored
Normal file
@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* AdapterFileSimple: File-adapter (simple)
|
||||
*/
|
||||
abstract class AdapterFileAbstract implements iAdapter
|
||||
{
|
||||
const CACHE_FILE_PREFIX = '__';
|
||||
|
||||
const CACHE_FILE_SUBFIX = '.php.cache';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $cacheDir;
|
||||
|
||||
/**
|
||||
* @var iSerializer
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fileMode = '0755';
|
||||
|
||||
/**
|
||||
* @param string|null $cacheDir
|
||||
*/
|
||||
public function __construct($cacheDir = null)
|
||||
{
|
||||
$this->serializer = new SerializerIgbinary();
|
||||
|
||||
if (!$cacheDir) {
|
||||
$cacheDir = \realpath(\sys_get_temp_dir()) . '/simple_php_cache';
|
||||
}
|
||||
|
||||
$this->cacheDir = (string) $cacheDir;
|
||||
|
||||
if ($this->createCacheDirectory($cacheDir) === true) {
|
||||
$this->installed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively creates & chmod directories.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function createCacheDirectory($path): bool
|
||||
{
|
||||
if (
|
||||
!$path
|
||||
||
|
||||
$path === '/'
|
||||
||
|
||||
$path === '.'
|
||||
||
|
||||
$path === '\\'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the directory already exists, just return true
|
||||
if (\is_dir($path) && \is_writable($path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if more than one level, try parent first
|
||||
if (\dirname($path) !== '.') {
|
||||
$return = $this->createCacheDirectory(\dirname($path));
|
||||
// if creating parent fails, we can abort immediately
|
||||
if (!$return) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$mode_dec = \intval($this->fileMode, 8);
|
||||
$old_umask = \umask(0);
|
||||
|
||||
/** @noinspection PhpUsageOfSilenceOperatorInspection */
|
||||
if (!@\mkdir($path, $mode_dec) && !\is_dir($path)) {
|
||||
$return = false;
|
||||
} else {
|
||||
$return = true;
|
||||
}
|
||||
|
||||
if (\is_dir($path) && !\is_writable($path)) {
|
||||
$return = \chmod($path, $mode_dec);
|
||||
}
|
||||
|
||||
\umask($old_umask);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $cacheFile
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function deleteFile($cacheFile): bool
|
||||
{
|
||||
if (\is_file($cacheFile)) {
|
||||
return \unlink($cacheFile);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
$value = $this->get($key);
|
||||
|
||||
return $value !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function get(string $key);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
$cacheFile = $this->getFileName($key);
|
||||
|
||||
return $this->deleteFile($cacheFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
if (!$this->cacheDir) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$return = [];
|
||||
foreach (new \DirectoryIterator($this->cacheDir) as $fileInfo) {
|
||||
if (!$fileInfo->isDot()) {
|
||||
$return[] = \unlink($fileInfo->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
return \in_array(false, $return, true) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set(string $key, $value): bool
|
||||
{
|
||||
return $this->setExpired($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function setExpired(string $key, $value, int $ttl = 0): bool;
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFileName(string $key): string
|
||||
{
|
||||
return $this->cacheDir . \DIRECTORY_SEPARATOR . self::CACHE_FILE_PREFIX . $key . self::CACHE_FILE_SUBFIX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the file-mode for new cache-files.
|
||||
*
|
||||
* e.g. '0777', or '0755' ...
|
||||
*
|
||||
* @param $fileMode
|
||||
*/
|
||||
public function setFileMode($fileMode)
|
||||
{
|
||||
$this->fileMode = $fileMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ttl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function ttlHasExpired(int $ttl): bool
|
||||
{
|
||||
if ($ttl === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return \time() > $ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateDataFromCache($data): bool
|
||||
{
|
||||
if (!\is_array($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (['value', 'ttl'] as $missing) {
|
||||
if (!\array_key_exists($missing, $data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
89
bundled-libs/voku/simple-cache/src/voku/cache/AdapterFileSimple.php
vendored
Normal file
89
bundled-libs/voku/simple-cache/src/voku/cache/AdapterFileSimple.php
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* AdapterFileSimple: File-adapter (simple)
|
||||
*/
|
||||
class AdapterFileSimple extends AdapterFileAbstract
|
||||
{
|
||||
const CACHE_FILE_PREFIX = '__simple_';
|
||||
|
||||
protected function getContext()
|
||||
{
|
||||
static $CONTEXT_CACHE = null;
|
||||
|
||||
if ($CONTEXT_CACHE === null) {
|
||||
$CONTEXT_CACHE = \stream_context_create(
|
||||
[
|
||||
'http' => [
|
||||
'timeout' => 2,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $CONTEXT_CACHE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
$path = $this->getFileName($key);
|
||||
|
||||
if (
|
||||
\file_exists($path) === false
|
||||
||
|
||||
\filesize($path) === 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// init
|
||||
$string = \file_get_contents(
|
||||
$path,
|
||||
false,
|
||||
$this->getContext()
|
||||
);
|
||||
|
||||
if (!$string) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $this->serializer->unserialize($string);
|
||||
|
||||
if (!$data || !$this->validateDataFromCache($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->ttlHasExpired($data['ttl']) === true) {
|
||||
$this->remove($key);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
return (bool) \file_put_contents(
|
||||
$this->getFileName($key),
|
||||
$this->serializer->serialize(
|
||||
[
|
||||
'value' => $value,
|
||||
'ttl' => $ttl ? $ttl + \time() : 0,
|
||||
]
|
||||
),
|
||||
0,
|
||||
$this->getContext()
|
||||
);
|
||||
}
|
||||
}
|
144
bundled-libs/voku/simple-cache/src/voku/cache/AdapterMemcache.php
vendored
Normal file
144
bundled-libs/voku/simple-cache/src/voku/cache/AdapterMemcache.php
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
use voku\cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* AdapterMemcache: Memcache-adapter
|
||||
*/
|
||||
class AdapterMemcache implements iAdapter
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* @var \Memcache
|
||||
*/
|
||||
private $memcache;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $compressed = false;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param \Memcache|null $memcache
|
||||
*/
|
||||
public function __construct($memcache = null)
|
||||
{
|
||||
if ($memcache instanceof \Memcache) {
|
||||
$this->setMemcache($memcache);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Memcache $memcache
|
||||
*/
|
||||
public function setMemcache(\Memcache $memcache)
|
||||
{
|
||||
$this->memcache = $memcache;
|
||||
$this->installed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return $this->get($key) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
return $this->memcache->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
return $this->memcache->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
return $this->memcache->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set(string $key, $value): bool
|
||||
{
|
||||
// Make sure we are under the proper limit
|
||||
if (\strlen($key) > 250) {
|
||||
throw new InvalidArgumentException('The passed cache key is over 250 bytes:' . \print_r($key, true));
|
||||
}
|
||||
|
||||
return $this->memcache->set($key, $value, $this->getCompressedFlag());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
if ($ttl > 2592000) {
|
||||
$ttl = 2592000;
|
||||
}
|
||||
|
||||
return $this->memcache->set($key, $value, $this->getCompressedFlag(), $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compressed-flag from MemCache.
|
||||
*
|
||||
* @return int 2 || 0
|
||||
*/
|
||||
private function getCompressedFlag(): int
|
||||
{
|
||||
return $this->isCompressed() ? \MEMCACHE_COMPRESSED : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if compression from MemCache is active.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCompressed(): bool
|
||||
{
|
||||
return $this->compressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the compression from MemCache.
|
||||
*
|
||||
* @param mixed $value will be converted to bool
|
||||
*/
|
||||
public function setCompressed($value)
|
||||
{
|
||||
$this->compressed = (bool) $value;
|
||||
}
|
||||
}
|
128
bundled-libs/voku/simple-cache/src/voku/cache/AdapterMemcached.php
vendored
Normal file
128
bundled-libs/voku/simple-cache/src/voku/cache/AdapterMemcached.php
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
use voku\cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* AdapterMemcached: Memcached-adapter
|
||||
*/
|
||||
class AdapterMemcached implements iAdapter
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* @var \Memcached
|
||||
*/
|
||||
private $memcached;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param \Memcached|null $memcached
|
||||
*/
|
||||
public function __construct($memcached = null)
|
||||
{
|
||||
if ($memcached instanceof \Memcached) {
|
||||
$this->setMemcached($memcached);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Memcached $memcached
|
||||
*/
|
||||
public function setMemcached(\Memcached $memcached)
|
||||
{
|
||||
$this->memcached = $memcached;
|
||||
$this->installed = true;
|
||||
|
||||
$this->setSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return $this->get($key) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
return $this->memcached->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
return $this->memcached->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
return $this->memcached->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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) {
|
||||
throw new InvalidArgumentException('The passed cache key is over 250 bytes:' . \print_r($key, true));
|
||||
}
|
||||
|
||||
return $this->memcached->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
if ($ttl > 2592000) {
|
||||
$ttl = 2592000;
|
||||
}
|
||||
|
||||
return $this->memcached->set($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the MemCached settings.
|
||||
*/
|
||||
private function setSettings()
|
||||
{
|
||||
// Use faster compression if available
|
||||
if (\Memcached::HAVE_IGBINARY) {
|
||||
$this->memcached->setOption(\Memcached::OPT_SERIALIZER, \Memcached::SERIALIZER_IGBINARY);
|
||||
}
|
||||
$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);
|
||||
}
|
||||
}
|
115
bundled-libs/voku/simple-cache/src/voku/cache/AdapterOpCache.php
vendored
Normal file
115
bundled-libs/voku/simple-cache/src/voku/cache/AdapterOpCache.php
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* AdapterOpCache: PHP-OPcache
|
||||
*
|
||||
* OPcache improves PHP performance by storing precompiled script bytecode
|
||||
* in shared memory, thereby removing the need for PHP to load and
|
||||
* parse scripts on each request.
|
||||
*/
|
||||
class AdapterOpCache extends AdapterFileSimple
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $hasCompileFileFunction;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct($cacheDir = null)
|
||||
{
|
||||
parent::__construct($cacheDir);
|
||||
|
||||
$this->serializer = new SerializerNo();
|
||||
|
||||
if (self::$hasCompileFileFunction === null) {
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
self::$hasCompileFileFunction = \function_exists('opcache_compile_file') && !empty(\opcache_get_status());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
$path = $this->getFileName($key);
|
||||
|
||||
if (
|
||||
\file_exists($path) === false
|
||||
||
|
||||
\filesize($path) === 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$data = include $path;
|
||||
|
||||
if (!$data || !$this->validateDataFromCache($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->ttlHasExpired($data['ttl']) === true) {
|
||||
$this->remove($key);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getFileName(string $key): string
|
||||
{
|
||||
return $this->cacheDir . \DIRECTORY_SEPARATOR . self::CACHE_FILE_PREFIX . $key . '.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
$item = [
|
||||
'value' => $value,
|
||||
'ttl' => $ttl ? $ttl + \time() : 0,
|
||||
];
|
||||
$content = \var_export($item, true);
|
||||
|
||||
$content = '<?php return ' . $content . ';';
|
||||
|
||||
$cacheFile = $this->getFileName($key);
|
||||
|
||||
$result = (bool) \file_put_contents(
|
||||
$cacheFile,
|
||||
$content,
|
||||
0,
|
||||
$this->getContext()
|
||||
);
|
||||
|
||||
if (
|
||||
$result === true
|
||||
&&
|
||||
self::$hasCompileFileFunction === true
|
||||
) {
|
||||
// opcache will only compile and cache files older than the script execution start.
|
||||
// set a date before the script execution date, then opcache will compile and cache the generated file.
|
||||
/** @noinspection SummerTimeUnsafeTimeManipulationInspection */
|
||||
\touch($cacheFile, \time() - 86400);
|
||||
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
\opcache_invalidate($cacheFile);
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
\opcache_compile_file($cacheFile);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
98
bundled-libs/voku/simple-cache/src/voku/cache/AdapterPredis.php
vendored
Normal file
98
bundled-libs/voku/simple-cache/src/voku/cache/AdapterPredis.php
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
use Predis\Client;
|
||||
|
||||
/**
|
||||
* AdapterPredis: Memcached-adapter
|
||||
*/
|
||||
class AdapterPredis implements iAdapter
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @param Client|null $client
|
||||
*/
|
||||
public function __construct($client = null)
|
||||
{
|
||||
if ($client instanceof Client) {
|
||||
$this->setPredisClient($client);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Client $client
|
||||
*/
|
||||
public function setPredisClient(Client $client)
|
||||
{
|
||||
$this->installed = true;
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return $this->client->exists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
return $this->client->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
return $this->client->del($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
return $this->client->flushall();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set(string $key, $value): bool
|
||||
{
|
||||
return $this->client->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
return $this->client->setex($key, $ttl, $value);
|
||||
}
|
||||
}
|
88
bundled-libs/voku/simple-cache/src/voku/cache/AdapterXcache.php
vendored
Normal file
88
bundled-libs/voku/simple-cache/src/voku/cache/AdapterXcache.php
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* AdapterXcache: Xcache-adapter
|
||||
*/
|
||||
class AdapterXcache implements iAdapter
|
||||
{
|
||||
public $installed = false;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (\extension_loaded('xcache') === true) {
|
||||
$this->installed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return \xcache_isset($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
return \xcache_get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove(string $key): bool
|
||||
{
|
||||
return \xcache_unset($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
if (\defined('XC_TYPE_VAR')) {
|
||||
$xCacheCount = xcache_count(XC_TYPE_VAR);
|
||||
for ($i = 0; $i < $xCacheCount; $i++) {
|
||||
\xcache_clear_cache(XC_TYPE_VAR, $i);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set(string $key, $value): bool
|
||||
{
|
||||
return \xcache_set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl = 0): bool
|
||||
{
|
||||
return \xcache_set($key, $value, $ttl);
|
||||
}
|
||||
}
|
798
bundled-libs/voku/simple-cache/src/voku/cache/Cache.php
vendored
Normal file
798
bundled-libs/voku/simple-cache/src/voku/cache/Cache.php
vendored
Normal file
@ -0,0 +1,798 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
use voku\cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Cache: global-cache class
|
||||
*
|
||||
* can use different cache-adapter:
|
||||
* - Redis
|
||||
* - Memcache / Memcached
|
||||
* - APC / APCu
|
||||
* - Xcache
|
||||
* - Array
|
||||
* - File / OpCache
|
||||
*/
|
||||
class Cache implements iCache
|
||||
{
|
||||
/**
|
||||
* @var iAdapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var iSerializer
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isReady = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isActive = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $useCheckForDev;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $useCheckForAdminSession;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $useCheckForServerIpIsClientIp;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $disableCacheGetParameter;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isAdminSession;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $STATIC_CACHE = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $STATIC_CACHE_EXPIRE = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $STATIC_CACHE_COUNTER = [];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $staticCacheHitCounter = 10;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param iAdapter|null $adapter
|
||||
* @param iSerializer|null $serializer
|
||||
* @param bool $checkForUsage <p>admin-session || server-ip == client-ip || check for
|
||||
* dev</p>
|
||||
* @param bool $cacheEnabled <p>false will disable the cache (use it e.g. for global
|
||||
* settings)</p>
|
||||
* @param bool|string $isAdminSession <p>set a admin-id, if the user is a admin (so we can
|
||||
* disable cache for this user)
|
||||
* @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>
|
||||
*/
|
||||
public function __construct(
|
||||
iAdapter $adapter = null,
|
||||
iSerializer $serializer = null,
|
||||
bool $checkForUsage = true,
|
||||
bool $cacheEnabled = true,
|
||||
bool $isAdminSession = false,
|
||||
bool $useCheckForDev = true,
|
||||
bool $useCheckForAdminSession = true,
|
||||
bool $useCheckForServerIpIsClientIp = true,
|
||||
string $disableCacheGetParameter = 'testWithoutCache'
|
||||
) {
|
||||
$this->isAdminSession = $isAdminSession;
|
||||
|
||||
$this->useCheckForDev = $useCheckForDev;
|
||||
$this->useCheckForAdminSession = $useCheckForAdminSession;
|
||||
$this->useCheckForServerIpIsClientIp = $useCheckForServerIpIsClientIp;
|
||||
|
||||
$this->disableCacheGetParameter = $disableCacheGetParameter;
|
||||
|
||||
// First check if the cache is active at all.
|
||||
$this->isActive = $cacheEnabled;
|
||||
if (
|
||||
$this->isActive === true
|
||||
&&
|
||||
$checkForUsage === true
|
||||
) {
|
||||
$this->setActive($this->isCacheActiveForTheCurrentUser());
|
||||
}
|
||||
|
||||
// If the cache is active, then try to auto-connect to the best possible cache-system.
|
||||
if ($this->isActive === true) {
|
||||
$this->setPrefix($this->getTheDefaultPrefix());
|
||||
|
||||
if ($adapter === null) {
|
||||
$adapter = $this->autoConnectToAvailableCacheSystem();
|
||||
}
|
||||
|
||||
// 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
|
||||
) {
|
||||
$serializer = new SerializerNo();
|
||||
} else {
|
||||
// set default serializer
|
||||
$serializer = new SerializerIgbinary();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Final checks ...
|
||||
if (
|
||||
$serializer !== null
|
||||
&&
|
||||
$adapter !== null
|
||||
) {
|
||||
$this->setCacheIsReady(true);
|
||||
|
||||
$this->adapter = $adapter;
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enable / disable the cache
|
||||
*
|
||||
* @param bool $isActive
|
||||
*/
|
||||
public function setActive(bool $isActive)
|
||||
{
|
||||
$this->isActive = $isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the current use is a admin || dev || server == client
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCacheActiveForTheCurrentUser(): bool
|
||||
{
|
||||
$active = true;
|
||||
|
||||
// test the cache, with this GET-parameter
|
||||
if ($this->disableCacheGetParameter) {
|
||||
$testCache = isset($_GET[$this->disableCacheGetParameter]) ? (int) $_GET[$this->disableCacheGetParameter] : 0;
|
||||
} else {
|
||||
$testCache = 0;
|
||||
}
|
||||
|
||||
if ($testCache !== 1) {
|
||||
if (
|
||||
// admin session is active
|
||||
(
|
||||
$this->useCheckForAdminSession
|
||||
&&
|
||||
$this->isAdminSession
|
||||
)
|
||||
||
|
||||
// server == client
|
||||
(
|
||||
$this->useCheckForServerIpIsClientIp === true
|
||||
&&
|
||||
isset($_SERVER['SERVER_ADDR'])
|
||||
&&
|
||||
$_SERVER['SERVER_ADDR'] === $this->getClientIp()
|
||||
)
|
||||
||
|
||||
// user is a dev
|
||||
(
|
||||
$this->useCheckForDev === true
|
||||
&&
|
||||
$this->checkForDev() === true
|
||||
)
|
||||
) {
|
||||
$active = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the IP address of the client
|
||||
*
|
||||
* @param bool $trust_proxy_headers <p>
|
||||
* Whether or not to trust the
|
||||
* proxy headers HTTP_CLIENT_IP
|
||||
* and HTTP_X_FORWARDED_FOR. ONLY
|
||||
* use if your $_SERVER is behind a
|
||||
* proxy that sets these values
|
||||
* </p>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getClientIp(bool $trust_proxy_headers = false): string
|
||||
{
|
||||
$remoteAddr = $_SERVER['REMOTE_ADDR'] ?? 'NO_REMOTE_ADDR';
|
||||
|
||||
if ($trust_proxy_headers) {
|
||||
return $remoteAddr;
|
||||
}
|
||||
|
||||
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
||||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
} else {
|
||||
$ip = $remoteAddr;
|
||||
}
|
||||
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for local developer.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkForDev(): bool
|
||||
{
|
||||
$return = false;
|
||||
|
||||
if (\function_exists('checkForDev')) {
|
||||
$return = checkForDev();
|
||||
} else {
|
||||
|
||||
// for testing with dev-address
|
||||
$noDev = isset($_GET['noDev']) ? (int) $_GET['noDev'] : 0;
|
||||
$remoteAddr = $_SERVER['REMOTE_ADDR'] ?? 'NO_REMOTE_ADDR';
|
||||
|
||||
if (
|
||||
$noDev !== 1
|
||||
&&
|
||||
(
|
||||
$remoteAddr === '127.0.0.1'
|
||||
||
|
||||
$remoteAddr === '::1'
|
||||
||
|
||||
\PHP_SAPI === 'cli'
|
||||
)
|
||||
) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default-prefix via "SERVER"-var + "SESSION"-language.
|
||||
*/
|
||||
protected function getTheDefaultPrefix(): string
|
||||
{
|
||||
return ($_SERVER['SERVER_NAME'] ?? '') . '_' .
|
||||
($_SERVER['THEME'] ?? '') . '_' .
|
||||
($_SERVER['STAGE'] ?? '') . '_' .
|
||||
($_SESSION['language'] ?? '') . '_' .
|
||||
($_SESSION['language_extra'] ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-connect to the available cache-system on the server.
|
||||
*
|
||||
* @return iAdapter
|
||||
*/
|
||||
protected function autoConnectToAvailableCacheSystem(): iAdapter
|
||||
{
|
||||
static $adapterCache;
|
||||
|
||||
if (\is_object($adapterCache) && $adapterCache instanceof iAdapter) {
|
||||
return $adapterCache;
|
||||
}
|
||||
|
||||
$memcached = null;
|
||||
$isMemcachedAvailable = false;
|
||||
if (\extension_loaded('memcached')) {
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
$memcached = new \Memcached();
|
||||
/** @noinspection PhpUsageOfSilenceOperatorInspection */
|
||||
$isMemcachedAvailable = @$memcached->addServer('127.0.0.1', 11211);
|
||||
}
|
||||
|
||||
if ($isMemcachedAvailable === false) {
|
||||
$memcached = null;
|
||||
}
|
||||
|
||||
$adapterMemcached = new AdapterMemcached($memcached);
|
||||
if ($adapterMemcached->installed() === true) {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// "Memcached"
|
||||
// -------------------------------------------------------------
|
||||
$adapter = $adapterMemcached;
|
||||
} else {
|
||||
$memcache = null;
|
||||
$isMemcacheAvailable = false;
|
||||
/** @noinspection ClassConstantCanBeUsedInspection */
|
||||
if (\class_exists('\Memcache')) {
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
$memcache = new \Memcache();
|
||||
/** @noinspection PhpUsageOfSilenceOperatorInspection */
|
||||
$isMemcacheAvailable = @$memcache->connect('127.0.0.1', 11211);
|
||||
}
|
||||
|
||||
if ($isMemcacheAvailable === false) {
|
||||
$memcache = null;
|
||||
}
|
||||
|
||||
$adapterMemcache = new AdapterMemcache($memcache);
|
||||
if ($adapterMemcache->installed() === true) {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// "Memcache"
|
||||
// -------------------------------------------------------------
|
||||
$adapter = $adapterMemcache;
|
||||
} else {
|
||||
$redis = null;
|
||||
$isRedisAvailable = false;
|
||||
if (
|
||||
\extension_loaded('redis')
|
||||
&&
|
||||
\class_exists('\Predis\Client')
|
||||
) {
|
||||
/** @noinspection PhpUndefinedNamespaceInspection */
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
$redis = new \Predis\Client(
|
||||
[
|
||||
'scheme' => 'tcp',
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6379,
|
||||
'timeout' => '2.0',
|
||||
]
|
||||
);
|
||||
|
||||
try {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$redis->connect();
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$isRedisAvailable = $redis->getConnection()->isConnected();
|
||||
} catch (\Exception $e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
||||
if ($isRedisAvailable === false) {
|
||||
$redis = null;
|
||||
}
|
||||
|
||||
$adapterRedis = new AdapterPredis($redis);
|
||||
if ($adapterRedis->installed() === true) {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Redis
|
||||
// -------------------------------------------------------------
|
||||
$adapter = $adapterRedis;
|
||||
} else {
|
||||
$adapterXcache = new AdapterXcache();
|
||||
if ($adapterXcache->installed() === true) {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// "Xcache"
|
||||
// -------------------------------------------------------------
|
||||
$adapter = $adapterXcache;
|
||||
} else {
|
||||
$adapterApcu = new AdapterApcu();
|
||||
if ($adapterApcu->installed() === true) {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// "APCu"
|
||||
// -------------------------------------------------------------
|
||||
$adapter = $adapterApcu;
|
||||
} else {
|
||||
$adapterApc = new AdapterApc();
|
||||
if ($adapterApc->installed() === true) {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// "APC"
|
||||
// -------------------------------------------------------------
|
||||
$adapter = $adapterApc;
|
||||
} else {
|
||||
$adapterObCache = new AdapterOpCache();
|
||||
if ($adapterObCache->installed() === true) {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// OpCache (via PHP-files)
|
||||
// -------------------------------------------------------------
|
||||
$adapter = $adapterObCache;
|
||||
} else {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Static-PHP-Cache
|
||||
// -------------------------------------------------------------
|
||||
$adapter = new AdapterArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save to static cache
|
||||
$adapterCache = $adapter;
|
||||
|
||||
return $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set "isReady" state.
|
||||
*
|
||||
* @param bool $isReady
|
||||
*/
|
||||
protected function setCacheIsReady(bool $isReady)
|
||||
{
|
||||
$this->isReady = $isReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "isReady" state.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getCacheIsReady(): bool
|
||||
{
|
||||
return $this->isReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached-item by key.
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $forceStaticCacheHitCounter
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getItem(string $key, int $forceStaticCacheHitCounter = 0)
|
||||
{
|
||||
if (!$this->adapter instanceof iAdapter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$storeKey = $this->calculateStoreKey($key);
|
||||
|
||||
// check if we already using static-cache
|
||||
$useStaticCache = true;
|
||||
if ($this->adapter instanceof AdapterArray) {
|
||||
$useStaticCache = false;
|
||||
}
|
||||
|
||||
if (!isset(self::$STATIC_CACHE_COUNTER[$storeKey])) {
|
||||
self::$STATIC_CACHE_COUNTER[$storeKey] = 0;
|
||||
}
|
||||
|
||||
// get from static-cache
|
||||
if (
|
||||
$useStaticCache === true
|
||||
&&
|
||||
$this->checkForStaticCache($storeKey) === true
|
||||
) {
|
||||
return self::$STATIC_CACHE[$storeKey];
|
||||
}
|
||||
|
||||
$serialized = $this->adapter->get($storeKey);
|
||||
$value = $serialized ? $this->serializer->unserialize($serialized) : null;
|
||||
|
||||
self::$STATIC_CACHE_COUNTER[$storeKey]++;
|
||||
|
||||
// save into static-cache if needed
|
||||
if (
|
||||
$useStaticCache === true
|
||||
&&
|
||||
(
|
||||
(
|
||||
$forceStaticCacheHitCounter !== 0
|
||||
&&
|
||||
self::$STATIC_CACHE_COUNTER[$storeKey] >= $forceStaticCacheHitCounter
|
||||
)
|
||||
||
|
||||
(
|
||||
$this->staticCacheHitCounter !== 0
|
||||
&&
|
||||
self::$STATIC_CACHE_COUNTER[$storeKey] >= $this->staticCacheHitCounter
|
||||
)
|
||||
)
|
||||
) {
|
||||
self::$STATIC_CACHE[$storeKey] = $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate store-key (prefix + $rawKey).
|
||||
*
|
||||
* @param string $rawKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function calculateStoreKey(string $rawKey): string
|
||||
{
|
||||
$str = $this->getPrefix() . $rawKey;
|
||||
|
||||
if ($this->adapter instanceof AdapterFileAbstract) {
|
||||
$str = $this->cleanStoreKey($str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean store-key (required e.g. for the "File"-Adapter).
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function cleanStoreKey(string $str): string
|
||||
{
|
||||
return \md5($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prefix.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPrefix(): string
|
||||
{
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* !!! 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
|
||||
*/
|
||||
public function setPrefix(string $prefix)
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value, when the static cache is used.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStaticCacheHitCounter(): int
|
||||
{
|
||||
return $this->staticCacheHitCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the static-hit-counter: Who often do we hit the cache, before we use static cache?
|
||||
*
|
||||
* @param int $staticCacheHitCounter
|
||||
*/
|
||||
public function setStaticCacheHitCounter(int $staticCacheHitCounter)
|
||||
{
|
||||
$this->staticCacheHitCounter = $staticCacheHitCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache-item by key => value + date.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTime $date <p>If the date is in the past, we will remove the existing cache-item.</p>
|
||||
*
|
||||
* @throws InvalidArgumentException <p>If the $date is in the past.</p>
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setItemToDate(string $key, $value, \DateTime $date): bool
|
||||
{
|
||||
$ttl = $date->getTimestamp() - \time();
|
||||
|
||||
if ($ttl <= 0) {
|
||||
throw new InvalidArgumentException('Date in the past.');
|
||||
}
|
||||
|
||||
return $this->setItem($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache-item by key => value + ttl.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateInterval|int|null $ttl
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setItem(string $key, $value, $ttl = 0): bool
|
||||
{
|
||||
if (
|
||||
!$this->adapter instanceof iAdapter
|
||||
||
|
||||
!$this->serializer instanceof iSerializer
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$storeKey = $this->calculateStoreKey($key);
|
||||
$serialized = $this->serializer->serialize($value);
|
||||
|
||||
// update static-cache, if it's exists
|
||||
if (\array_key_exists($storeKey, self::$STATIC_CACHE) === true) {
|
||||
self::$STATIC_CACHE[$storeKey] = $value;
|
||||
}
|
||||
|
||||
if ($ttl) {
|
||||
if ($ttl instanceof \DateInterval) {
|
||||
// Converting to a TTL in seconds
|
||||
$dateTimeNow = new \DateTime('now');
|
||||
$ttl = $dateTimeNow->add($ttl)->getTimestamp() - \time();
|
||||
}
|
||||
|
||||
// always cache the TTL time, maybe we need this later ...
|
||||
self::$STATIC_CACHE_EXPIRE[$storeKey] = ($ttl ? (int) $ttl + \time() : 0);
|
||||
|
||||
return $this->adapter->setExpired($storeKey, $serialized, $ttl);
|
||||
}
|
||||
|
||||
return $this->adapter->set($storeKey, $serialized);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a cached-item.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function removeItem(string $key): bool
|
||||
{
|
||||
if (!$this->adapter instanceof iAdapter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$storeKey = $this->calculateStoreKey($key);
|
||||
|
||||
// remove static-cache
|
||||
if (
|
||||
!empty(self::$STATIC_CACHE)
|
||||
&&
|
||||
\array_key_exists($storeKey, self::$STATIC_CACHE) === true
|
||||
) {
|
||||
unset(self::$STATIC_CACHE[$storeKey], self::$STATIC_CACHE_COUNTER[$storeKey], self::$STATIC_CACHE_EXPIRE[$storeKey]
|
||||
);
|
||||
}
|
||||
|
||||
return $this->adapter->remove($storeKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all cached-items.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
if (!$this->adapter instanceof iAdapter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove static-cache
|
||||
if (!empty(self::$STATIC_CACHE)) {
|
||||
self::$STATIC_CACHE = [];
|
||||
self::$STATIC_CACHE_COUNTER = [];
|
||||
self::$STATIC_CACHE_EXPIRE = [];
|
||||
}
|
||||
|
||||
return $this->adapter->removeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if cached-item exists.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function existsItem(string $key): bool
|
||||
{
|
||||
if (!$this->adapter instanceof iAdapter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$storeKey = $this->calculateStoreKey($key);
|
||||
|
||||
// check static-cache
|
||||
if ($this->checkForStaticCache($storeKey) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->adapter->exists($storeKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $storeKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkForStaticCache(string $storeKey): bool
|
||||
{
|
||||
return !empty(self::$STATIC_CACHE)
|
||||
&&
|
||||
\array_key_exists($storeKey, self::$STATIC_CACHE) === true
|
||||
&&
|
||||
\array_key_exists($storeKey, self::$STATIC_CACHE_EXPIRE) === true
|
||||
&&
|
||||
\time() <= self::$STATIC_CACHE_EXPIRE[$storeKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current adapter class-name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUsedAdapterClassName(): string
|
||||
{
|
||||
if ($this->adapter) {
|
||||
/** @noinspection GetClassUsageInspection */
|
||||
return \get_class($this->adapter);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current serializer class-name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUsedSerializerClassName(): string
|
||||
{
|
||||
if ($this->serializer) {
|
||||
/** @noinspection GetClassUsageInspection */
|
||||
return \get_class($this->serializer);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
152
bundled-libs/voku/simple-cache/src/voku/cache/CacheChain.php
vendored
Normal file
152
bundled-libs/voku/simple-cache/src/voku/cache/CacheChain.php
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* CacheChain: global-cache-chain class
|
||||
*/
|
||||
class CacheChain implements iCache
|
||||
{
|
||||
/**
|
||||
* @var array|iCache[]
|
||||
*/
|
||||
private $caches = [];
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param array $caches
|
||||
*/
|
||||
public function __construct(array $caches = [])
|
||||
{
|
||||
\array_map(
|
||||
[
|
||||
$this,
|
||||
'addCache',
|
||||
],
|
||||
$caches
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get caches
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCaches(): array
|
||||
{
|
||||
return $this->caches;
|
||||
}
|
||||
|
||||
/**
|
||||
* add cache
|
||||
*
|
||||
* @param iCache $cache
|
||||
* @param bool $prepend
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addCache(iCache $cache, $prepend = true)
|
||||
{
|
||||
if ($this === $cache) {
|
||||
throw new \InvalidArgumentException('loop-error, put into other cache');
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
\array_unshift($this->caches, $cache);
|
||||
} else {
|
||||
$this->caches[] = $cache;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItem(string $key)
|
||||
{
|
||||
foreach ($this->caches as $cache) {
|
||||
if ($cache->existsItem($key)) {
|
||||
return $cache->getItem($key);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setItem(string $key, $value, $ttl = null): bool
|
||||
{
|
||||
// init
|
||||
$results = [];
|
||||
|
||||
foreach ($this->caches as $cache) {
|
||||
$results[] = $cache->setItem($key, $value, $ttl);
|
||||
}
|
||||
|
||||
return \in_array(false, $results, true) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setItemToDate(string $key, $value, \DateTime $date): bool
|
||||
{
|
||||
// init
|
||||
$results = [];
|
||||
|
||||
/* @var $cache iCache */
|
||||
foreach ($this->caches as $cache) {
|
||||
$results[] = $cache->setItemToDate($key, $value, $date);
|
||||
}
|
||||
|
||||
return \in_array(false, $results, true) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeItem(string $key): bool
|
||||
{
|
||||
// init
|
||||
$results = [];
|
||||
|
||||
foreach ($this->caches as $cache) {
|
||||
$results[] = $cache->removeItem($key);
|
||||
}
|
||||
|
||||
return \in_array(false, $results, true) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function existsItem(string $key): bool
|
||||
{
|
||||
foreach ($this->caches as $cache) {
|
||||
if ($cache->existsItem($key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeAll(): bool
|
||||
{
|
||||
// init
|
||||
$results = [];
|
||||
|
||||
foreach ($this->caches as $cache) {
|
||||
$results[] = $cache->removeAll();
|
||||
}
|
||||
|
||||
return \in_array(false, $results, true) === false;
|
||||
}
|
||||
}
|
177
bundled-libs/voku/simple-cache/src/voku/cache/CachePsr16.php
vendored
Normal file
177
bundled-libs/voku/simple-cache/src/voku/cache/CachePsr16.php
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use voku\cache\Exception\InvalidArgumentException;
|
||||
|
||||
class CachePsr16 extends Cache implements CacheInterface
|
||||
{
|
||||
/**
|
||||
* Wipes clean the entire cache's keys.
|
||||
*
|
||||
* @return bool true on success and false on failure
|
||||
*/
|
||||
public function clear(): bool
|
||||
{
|
||||
return $this->removeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an item from the cache by its unique key.
|
||||
*
|
||||
* @param string $key the unique cache key of the item to delete
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return bool True if the item was successfully removed. False if there was an error.
|
||||
*/
|
||||
public function delete($key): bool
|
||||
{
|
||||
if (!\is_string($key)) {
|
||||
throw new InvalidArgumentException('$key is not a string:' . \print_r($key, true));
|
||||
}
|
||||
|
||||
return $this->removeItem($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes multiple cache items in a single operation.
|
||||
*
|
||||
* @param \iterable $keys a list of string-based keys to be deleted
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return bool True if the items were successfully removed. False if there was an error.
|
||||
*/
|
||||
public function deleteMultiple($keys): bool
|
||||
{
|
||||
if (!\is_array($keys) && !($keys instanceof \Traversable)) {
|
||||
throw new InvalidArgumentException('$keys is not iterable:' . \print_r($keys, true));
|
||||
}
|
||||
|
||||
$results = [];
|
||||
foreach ((array) $keys as $key) {
|
||||
$results = $this->delete($key);
|
||||
}
|
||||
|
||||
return \in_array(false, $results, true) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a value from the cache.
|
||||
*
|
||||
* @param string $key the unique key of this item in the cache
|
||||
* @param mixed $default default value to return if the key does not exist
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return mixed the value of the item from the cache, or $default in case of cache miss
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if ($this->has($key) === true) {
|
||||
return $this->getItem($key);
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains multiple cache items by their unique keys.
|
||||
*
|
||||
* @param \iterable $keys a list of keys that can obtained in a single operation
|
||||
* @param mixed $default default value to return for keys that do not exist
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return \iterable A list of key => value pairs. Cache keys that do not exist or are stale will have $default as
|
||||
* value.
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
if (!\is_array($keys) && !($keys instanceof \Traversable)) {
|
||||
throw new InvalidArgumentException('$keys is not iterable:' . \print_r($keys, true));
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ((array) $keys as $key) {
|
||||
$result[$key] = $this->has($key) ? $this->get($key) : $default;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether an item is present in the cache.
|
||||
*
|
||||
* NOTE: It is recommended that has() is only to be used for cache warming type purposes
|
||||
* and not to be used within your live applications operations for get/set, as this method
|
||||
* is subject to a race condition where your has() will return true and immediately after,
|
||||
* another script can remove it making the state of your app out of date.
|
||||
*
|
||||
* @param string $key the cache item key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key): bool
|
||||
{
|
||||
if (!\is_string($key)) {
|
||||
throw new InvalidArgumentException('$key is not a string:' . \print_r($key, true));
|
||||
}
|
||||
|
||||
return $this->existsItem($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
|
||||
*
|
||||
* @param string $key the key of the item to store
|
||||
* @param mixed $value the value of the item to store, must be serializable
|
||||
* @param \DateInterval|int|null $ttl Optional. The TTL value of this item. If no value is sent and
|
||||
* the driver supports TTL then the library may set a default value
|
||||
* for it or let the driver take care of that.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return bool true on success and false on failure
|
||||
*/
|
||||
public function set($key, $value, $ttl = null): bool
|
||||
{
|
||||
if (!\is_string($key)) {
|
||||
throw new InvalidArgumentException('$key is not a string:' . \print_r($key, true));
|
||||
}
|
||||
|
||||
return $this->setItem($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists a set of key => value pairs in the cache, with an optional TTL.
|
||||
*
|
||||
* @param \iterable $values a list of key => value pairs for a multiple-set operation
|
||||
* @param \DateInterval|int|null $ttl Optional. The TTL value of this item. If no value is sent and
|
||||
* the driver supports TTL then the library may set a default value
|
||||
* for it or let the driver take care of that.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return bool true on success and false on failure
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null): bool
|
||||
{
|
||||
if (!\is_array($values) && !($values instanceof \Traversable)) {
|
||||
throw new InvalidArgumentException('$values is not iterable:' . \print_r($values, true));
|
||||
}
|
||||
|
||||
$results = [];
|
||||
foreach ((array) $values as $key => $value) {
|
||||
$results = $this->set($key, $value, $ttl);
|
||||
}
|
||||
|
||||
return \in_array(false, $results, true) === false;
|
||||
}
|
||||
}
|
9
bundled-libs/voku/simple-cache/src/voku/cache/Exception/InvalidArgumentException.php
vendored
Normal file
9
bundled-libs/voku/simple-cache/src/voku/cache/Exception/InvalidArgumentException.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache\Exception;
|
||||
|
||||
class InvalidArgumentException extends \Exception implements \Psr\SimpleCache\InvalidArgumentException
|
||||
{
|
||||
}
|
27
bundled-libs/voku/simple-cache/src/voku/cache/SerializerDefault.php
vendored
Normal file
27
bundled-libs/voku/simple-cache/src/voku/cache/SerializerDefault.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* SerializerDefault: simple serialize / unserialize
|
||||
*/
|
||||
class SerializerDefault implements iSerializer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize($value)
|
||||
{
|
||||
return \serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($value)
|
||||
{
|
||||
return \unserialize($value);
|
||||
}
|
||||
}
|
56
bundled-libs/voku/simple-cache/src/voku/cache/SerializerIgbinary.php
vendored
Normal file
56
bundled-libs/voku/simple-cache/src/voku/cache/SerializerIgbinary.php
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* SerializerIgbinary: serialize / unserialize
|
||||
*/
|
||||
class SerializerIgbinary implements iSerializer
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $_exists_igbinary;
|
||||
|
||||
/**
|
||||
* SerializerIgbinary constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$_exists_igbinary = (
|
||||
\function_exists('igbinary_serialize')
|
||||
&&
|
||||
\function_exists('igbinary_unserialize')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize($value)
|
||||
{
|
||||
if (self::$_exists_igbinary === true) {
|
||||
/** @noinspection PhpUndefinedFunctionInspection */
|
||||
return \igbinary_serialize($value);
|
||||
}
|
||||
|
||||
// fallback
|
||||
return \serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($value)
|
||||
{
|
||||
if (self::$_exists_igbinary === true) {
|
||||
/** @noinspection PhpUndefinedFunctionInspection */
|
||||
return \igbinary_unserialize($value);
|
||||
}
|
||||
|
||||
// fallback
|
||||
return \unserialize($value);
|
||||
}
|
||||
}
|
27
bundled-libs/voku/simple-cache/src/voku/cache/SerializerNo.php
vendored
Normal file
27
bundled-libs/voku/simple-cache/src/voku/cache/SerializerNo.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* SerializerNo: no serialize / unserialize !!!
|
||||
*/
|
||||
class SerializerNo implements iSerializer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
}
|
73
bundled-libs/voku/simple-cache/src/voku/cache/iAdapter.php
vendored
Normal file
73
bundled-libs/voku/simple-cache/src/voku/cache/iAdapter.php
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* iAdapter: cache-adapter interface
|
||||
*/
|
||||
interface iAdapter
|
||||
{
|
||||
/**
|
||||
* Get cached-item by key.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed|null <p>will return NULL if the key not exists</p>
|
||||
*/
|
||||
public function get(string $key);
|
||||
|
||||
/**
|
||||
* Set cache-item by key => value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function set(string $key, $value): bool;
|
||||
|
||||
/**
|
||||
* Set cache-item by key => value + ttl.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $ttl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setExpired(string $key, $value, int $ttl): bool;
|
||||
|
||||
/**
|
||||
* Remove cached-item by key.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function remove(string $key): bool;
|
||||
|
||||
/**
|
||||
* Remove all cached items.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function removeAll(): bool;
|
||||
|
||||
/**
|
||||
* Check if cache-key exists.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(string $key): bool;
|
||||
|
||||
/**
|
||||
* Check if cache is installed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function installed(): bool;
|
||||
}
|
67
bundled-libs/voku/simple-cache/src/voku/cache/iCache.php
vendored
Normal file
67
bundled-libs/voku/simple-cache/src/voku/cache/iCache.php
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* iCache: cache-global interface
|
||||
*/
|
||||
interface iCache
|
||||
{
|
||||
/**
|
||||
* get item
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getItem(string $key);
|
||||
|
||||
/**
|
||||
* set item
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int|null $ttl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setItem(string $key, $value, $ttl = 0): bool;
|
||||
|
||||
/**
|
||||
* set item a special expire-date
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTime $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setItemToDate(string $key, $value, \DateTime $date): bool;
|
||||
|
||||
/**
|
||||
* remove item
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function removeItem(string $key): bool;
|
||||
|
||||
/**
|
||||
* remove all items
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function removeAll(): bool;
|
||||
|
||||
/**
|
||||
* check if item exists
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function existsItem(string $key): bool;
|
||||
}
|
29
bundled-libs/voku/simple-cache/src/voku/cache/iSerializer.php
vendored
Normal file
29
bundled-libs/voku/simple-cache/src/voku/cache/iSerializer.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace voku\cache;
|
||||
|
||||
/**
|
||||
* iSerializer: cache-serializer interface
|
||||
*/
|
||||
interface iSerializer
|
||||
{
|
||||
/**
|
||||
* serialize
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function serialize($value);
|
||||
|
||||
/**
|
||||
* unserialize
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function unserialize($value);
|
||||
}
|
@ -8,7 +8,8 @@
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"zendframework/zend-db": "2.*",
|
||||
"katzgrau/klogger": "1.0.*"
|
||||
"katzgrau/klogger": "1.0.*",
|
||||
"voku/simple-cache": "^3.2"
|
||||
},
|
||||
"config": {
|
||||
"vendor-dir": "bundled-libs"
|
||||
|
@ -213,9 +213,9 @@ function &serendipity_fetchEntries($range = null, $full = true, $limit = '', $fe
|
||||
$cache = serendipity_setupCache();
|
||||
$key = md5(serialize($initial_args) . $serendipity['short_archives'] . '||' . $serendipity['range'] . '||' . $serendipity['GET']['category'] . '||' . $serendipity['GET']['hide_category'] . '||' . $serendipity['GET']['viewAuthor'] . '||' . $serendipity['GET']['page'] . '||' . $serendipity['fetchLimit'] . '||' . $serendipity['max_fetch_limit'] . '||' . $serendipity['GET']['adminModule'] . '||' . serendipity_checkPermission('adminEntriesMaintainOthers') . '||' .$serendipity['showFutureEntries'] . '||' . $serendipity['archiveSortStable'] . '||' . $serendipity['plugindata']['smartyvars']['uriargs'] );
|
||||
|
||||
$entries = $cache->get($key, "fetchEntries");
|
||||
if ($entries !== false) {
|
||||
$serendipity['fullCountQuery'] = $cache->get($key . '_fullCountQuery', "fetchEntries");
|
||||
$entries = $cache->getItem($key);
|
||||
if ($entries && $entries !== false) {
|
||||
$serendipity['fullCountQuery'] = $cache->getItem($key . '_fullCountQuery');
|
||||
return unserialize($entries);
|
||||
}
|
||||
}
|
||||
@ -463,9 +463,9 @@ function &serendipity_fetchEntries($range = null, $full = true, $limit = '', $fe
|
||||
|
||||
if ($serendipity['useInternalCache']) {
|
||||
$key = md5(serialize($initial_args) . $serendipity['short_archives'] . '||' . $serendipity['range'] . '||' . $serendipity['GET']['category'] . '||' . $serendipity['GET']['hide_category'] . '||' . $serendipity['GET']['viewAuthor'] . '||' . $serendipity['GET']['page'] . '||' . $serendipity['fetchLimit'] . '||' . $serendipity['max_fetch_limit'] . '||' . $serendipity['GET']['adminModule'] . '||' . serendipity_checkPermission('adminEntriesMaintainOthers') . '||' .$serendipity['showFutureEntries'] . '||' . $serendipity['archiveSortStable'] . '||' . $serendipity['plugindata']['smartyvars']['uriargs']);
|
||||
|
||||
$cache->save(serialize($ret), $key, "fetchEntries");
|
||||
$cache->save($serendipity['fullCountQuery'], $key . '_fullCountQuery', "fetchEntries");
|
||||
|
||||
$cache->setItem($key, serialize($ret));
|
||||
$cache->setItem($key . '_fullCountQuery', $serendipity['fullCountQuery']);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
@ -1292,35 +1292,32 @@ function serendipity_printEntries($entries, $extended = 0, $preview = false, $sm
|
||||
} // end function serendipity_printEntries
|
||||
|
||||
function serendipity_cleanCache() {
|
||||
include_once 'Cache/Lite.php';
|
||||
|
||||
if (!class_exists('Cache_Lite')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'cacheDir' => $serendipity['serendipityPath'] . 'templates_c/',
|
||||
'lifeTime' => 3600,
|
||||
'hashedDirectoryLevel' => 2
|
||||
);
|
||||
$cache = new Cache_Lite($options);
|
||||
return $cache->clean("fetchEntries");
|
||||
$cache = serendipity_setupCache();
|
||||
return $cache->removeAll();
|
||||
}
|
||||
|
||||
//function serendipity_setupCache() {
|
||||
//include_once 'Cache/Lite.php';
|
||||
|
||||
//if (!class_exists('Cache_Lite')) {
|
||||
//return false;
|
||||
//}
|
||||
|
||||
//$options = array(
|
||||
//'cacheDir' => $serendipity['serendipityPath'] . 'templates_c/',
|
||||
//'lifeTime' => 3600,
|
||||
//'hashedDirectoryLevel' => 2
|
||||
//);
|
||||
|
||||
//return new Cache_Lite($options);
|
||||
//}
|
||||
|
||||
use voku\cache\Cache;
|
||||
function serendipity_setupCache() {
|
||||
include_once 'Cache/Lite.php';
|
||||
|
||||
if (!class_exists('Cache_Lite')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'cacheDir' => $serendipity['serendipityPath'] . 'templates_c/',
|
||||
'lifeTime' => 3600,
|
||||
'hashedDirectoryLevel' => 2
|
||||
);
|
||||
|
||||
return new Cache_Lite($options);
|
||||
$cache = new Cache();
|
||||
$ttl = 3600; // 60s * 60 = 1h
|
||||
return $cache;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user