msd Backup hinzugefügt
This commit is contained in:
296
msd/vendor/desarrolla2/cache/src/AbstractCache.php
vendored
Normal file
296
msd/vendor/desarrolla2/cache/src/AbstractCache.php
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Option\PrefixTrait as PrefixOption;
|
||||
use Desarrolla2\Cache\Option\TtlTrait as TtlOption;
|
||||
use Desarrolla2\Cache\Packer\PackingTrait as Packing;
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
use DateTimeImmutable;
|
||||
use DateInterval;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* AbstractAdapter
|
||||
*/
|
||||
abstract class AbstractCache implements CacheInterface
|
||||
{
|
||||
use PrefixOption;
|
||||
use TtlOption;
|
||||
use Packing;
|
||||
|
||||
/**
|
||||
* Make a clone of this object.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
protected function cloneSelf(): self
|
||||
{
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function withOption(string $key, $value): self
|
||||
{
|
||||
return $this->withOptions([$key => $value]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function withOptions(array $options): self
|
||||
{
|
||||
$cache = $this->cloneSelf();
|
||||
|
||||
foreach ($options as $key => $value) {
|
||||
$method = "set" . str_replace('-', '', $key) . "Option";
|
||||
|
||||
if (empty($key) || !method_exists($cache, $method)) {
|
||||
throw new InvalidArgumentException("unknown option '$key'");
|
||||
}
|
||||
|
||||
$cache->$method($value);
|
||||
}
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOption($key)
|
||||
{
|
||||
$method = "get" . str_replace('-', '', $key) . "Option";
|
||||
|
||||
if (empty($key) || !method_exists($this, $method)) {
|
||||
throw new InvalidArgumentException("unknown option '$key'");
|
||||
}
|
||||
|
||||
return $this->$method();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate the key
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function assertKey($key): void
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
$type = (is_object($key) ? get_class($key) . ' ' : '') . gettype($key);
|
||||
throw new InvalidArgumentException("Expected key to be a string, not $type");
|
||||
}
|
||||
|
||||
if ($key === '' || preg_match('~[{}()/\\\\@:]~', $key)) {
|
||||
throw new InvalidArgumentException("Invalid key '$key'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the keys are an array or traversable
|
||||
*
|
||||
* @param iterable $subject
|
||||
* @param string $msg
|
||||
* @return void
|
||||
* @throws InvalidArgumentException if subject are not iterable
|
||||
*/
|
||||
protected function assertIterable($subject, $msg): void
|
||||
{
|
||||
$iterable = function_exists('is_iterable')
|
||||
? is_iterable($subject)
|
||||
: is_array($subject) || $subject instanceof Traversable;
|
||||
|
||||
if (!$iterable) {
|
||||
throw new InvalidArgumentException($msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the key into a cache identifier
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function keyToId($key): string
|
||||
{
|
||||
$this->assertKey($key);
|
||||
|
||||
return sprintf('%s%s', $this->prefix, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a map with keys and ids
|
||||
*
|
||||
* @param iterable $keys
|
||||
* @return array
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function mapKeysToIds($keys): array
|
||||
{
|
||||
$this->assertIterable($keys, 'keys not iterable');
|
||||
|
||||
$map = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$id = $this->keyToId($key);
|
||||
$map[$id] = $key;
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pack all values and turn keys into ids
|
||||
*
|
||||
* @param iterable $values
|
||||
* @return array
|
||||
*/
|
||||
protected function packValues(iterable $values): array
|
||||
{
|
||||
$packed = [];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$id = $this->keyToId(is_int($key) ? (string)$key : $key);
|
||||
$packed[$id] = $this->pack($value);
|
||||
}
|
||||
|
||||
return $packed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
$this->assertIterable($keys, 'keys not iterable');
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$result[$key] = $this->get($key, $default);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$this->assertIterable($values, 'values not iterable');
|
||||
|
||||
$success = true;
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$success = $this->set(is_int($key) ? (string)$key : $key, $value, $ttl) && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
$this->assertIterable($keys, 'keys not iterable');
|
||||
|
||||
$success = true;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$success = $this->delete($key) && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current time.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function currentTimestamp(): int
|
||||
{
|
||||
return time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert TTL to seconds from now
|
||||
*
|
||||
* @param null|int|DateInterval $ttl
|
||||
* @return int|null
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function ttlToSeconds($ttl): ?int
|
||||
{
|
||||
if (!isset($ttl)) {
|
||||
return $this->ttl;
|
||||
}
|
||||
|
||||
if ($ttl instanceof DateInterval) {
|
||||
$reference = new DateTimeImmutable();
|
||||
$endTime = $reference->add($ttl);
|
||||
|
||||
$ttl = $endTime->getTimestamp() - $reference->getTimestamp();
|
||||
}
|
||||
|
||||
if (!is_int($ttl)) {
|
||||
$type = (is_object($ttl) ? get_class($ttl) . ' ' : '') . gettype($ttl);
|
||||
throw new InvalidArgumentException("ttl should be of type int or DateInterval, not $type");
|
||||
}
|
||||
|
||||
return isset($this->ttl) ? min($ttl, $this->ttl) : $ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert TTL to epoch timestamp
|
||||
*
|
||||
* @param null|int|DateInterval $ttl
|
||||
* @return int|null
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function ttlToTimestamp($ttl): ?int
|
||||
{
|
||||
if (!isset($ttl)) {
|
||||
return isset($this->ttl) ? time() + $this->ttl : null;
|
||||
}
|
||||
|
||||
if (is_int($ttl)) {
|
||||
return time() + (isset($this->ttl) ? min($ttl, $this->ttl) : $ttl);
|
||||
}
|
||||
|
||||
if ($ttl instanceof DateInterval) {
|
||||
$timestamp = (new DateTimeImmutable())->add($ttl)->getTimestamp();
|
||||
|
||||
return isset($this->ttl) ? min($timestamp, time() + $this->ttl) : $timestamp;
|
||||
}
|
||||
|
||||
$type = (is_object($ttl) ? get_class($ttl) . ' ' : '') . gettype($ttl);
|
||||
throw new InvalidArgumentException("ttl should be of type int or DateInterval, not $type");
|
||||
}
|
||||
}
|
216
msd/vendor/desarrolla2/cache/src/AbstractFile.php
vendored
Normal file
216
msd/vendor/desarrolla2/cache/src/AbstractFile.php
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
use Desarrolla2\Cache\Option\FilenameTrait as FilenameOption;
|
||||
|
||||
/**
|
||||
* Abstract class for using files as cache.
|
||||
*
|
||||
* @package Desarrolla2\Cache
|
||||
*/
|
||||
abstract class AbstractFile extends AbstractCache
|
||||
{
|
||||
use FilenameOption;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $cacheDir;
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string|null $cacheDir
|
||||
*/
|
||||
public function __construct(?string $cacheDir = null)
|
||||
{
|
||||
if (!$cacheDir) {
|
||||
$cacheDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'cache';
|
||||
if(!is_dir($cacheDir)) {
|
||||
mkdir($cacheDir, 0777, true);
|
||||
}
|
||||
}
|
||||
|
||||
$this->cacheDir = rtrim($cacheDir, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the key
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function assertKey($key): void
|
||||
{
|
||||
parent::assertKey($key);
|
||||
|
||||
if (strpos($key, '*')) {
|
||||
throw new InvalidArgumentException("Key may not contain the character '*'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the contents of the cache file.
|
||||
*
|
||||
* @param string $cacheFile
|
||||
* @return string
|
||||
*/
|
||||
protected function readFile(string $cacheFile): string
|
||||
{
|
||||
return file_get_contents($cacheFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the first line of the cache file.
|
||||
*
|
||||
* @param string $cacheFile
|
||||
* @return string
|
||||
*/
|
||||
protected function readLine(string $cacheFile): string
|
||||
{
|
||||
$fp = fopen($cacheFile, 'r');
|
||||
$line = fgets($fp);
|
||||
fclose($fp);
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a cache file
|
||||
*
|
||||
* @param string $cacheFile
|
||||
* @param string $contents
|
||||
* @return bool
|
||||
*/
|
||||
protected function writeFile(string $cacheFile, string $contents): bool
|
||||
{
|
||||
$dir = dirname($cacheFile);
|
||||
|
||||
if ($dir !== $this->cacheDir && !is_dir($dir)) {
|
||||
mkdir($dir, 0775, true);
|
||||
}
|
||||
|
||||
return (bool)file_put_contents($cacheFile, $contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cache file
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
protected function deleteFile(string $file): bool
|
||||
{
|
||||
return !is_file($file) || unlink($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all files from a directory.
|
||||
*/
|
||||
protected function removeFiles(string $dir): bool
|
||||
{
|
||||
$success = true;
|
||||
|
||||
$generator = $this->getFilenameOption();
|
||||
$objects = $this->streamSafeGlob($dir, $generator('*'));
|
||||
|
||||
foreach ($objects as $object) {
|
||||
$success = $this->deleteFile($object) && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive delete an empty directory.
|
||||
*
|
||||
* @param string $dir
|
||||
*/
|
||||
protected function removeRecursively(string $dir): bool
|
||||
{
|
||||
$success = $this->removeFiles($dir);
|
||||
|
||||
$objects = $this->streamSafeGlob($dir, '*');
|
||||
|
||||
foreach ($objects as $object) {
|
||||
if (!is_dir($object)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_link($object)) {
|
||||
unlink($object);
|
||||
} else {
|
||||
$success = $this->removeRecursively($object) && $success;
|
||||
rmdir($object);
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$cacheFile = $this->getFilename($key);
|
||||
|
||||
return $this->deleteFile($cacheFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cache directory.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->removeRecursively($this->cacheDir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Glob that is safe with streams (vfs for example)
|
||||
*
|
||||
* @param string $directory
|
||||
* @param string $filePattern
|
||||
* @return array
|
||||
*/
|
||||
protected function streamSafeGlob(string $directory, string $filePattern): array
|
||||
{
|
||||
$filePattern = basename($filePattern);
|
||||
$files = scandir($directory);
|
||||
$found = [];
|
||||
|
||||
foreach ($files as $filename) {
|
||||
if (in_array($filename, ['.', '..'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fnmatch($filePattern, $filename) || fnmatch($filePattern . '.ttl', $filename)) {
|
||||
$found[] = "{$directory}/{$filename}";
|
||||
}
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
}
|
88
msd/vendor/desarrolla2/cache/src/Apcu.php
vendored
Normal file
88
msd/vendor/desarrolla2/cache/src/Apcu.php
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Exception\CacheException;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\NopPacker;
|
||||
|
||||
/**
|
||||
* Apcu
|
||||
*/
|
||||
class Apcu extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* Create the default packer for this cache implementation
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new NopPacker();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$ttlSeconds = $this->ttlToSeconds($ttl);
|
||||
|
||||
if (isset($ttlSeconds) && $ttlSeconds <= 0) {
|
||||
return $this->delete($key);
|
||||
}
|
||||
|
||||
return apcu_store($this->keyToId($key), $this->pack($value), $ttlSeconds ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$packed = apcu_fetch($this->keyToId($key), $success);
|
||||
|
||||
return $success ? $this->unpack($packed) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return apcu_exists($this->keyToId($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
|
||||
return apcu_delete($id) || !apcu_exists($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return apcu_clear_cache();
|
||||
}
|
||||
}
|
58
msd/vendor/desarrolla2/cache/src/CacheInterface.php
vendored
Normal file
58
msd/vendor/desarrolla2/cache/src/CacheInterface.php
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface as PsrCacheInterface;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\KeyMaker\KeyMakerInterface;
|
||||
|
||||
/**
|
||||
* CacheInterface
|
||||
*/
|
||||
interface CacheInterface extends PsrCacheInterface
|
||||
{
|
||||
/**
|
||||
* Set option for cache
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return static
|
||||
*/
|
||||
public function withOption(string $key, $value);
|
||||
|
||||
/**
|
||||
* Set multiple options for cache
|
||||
*
|
||||
* @param array $options
|
||||
* @return static
|
||||
*/
|
||||
public function withOptions(array $options);
|
||||
|
||||
/**
|
||||
* Get option for cache
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOption($key);
|
||||
|
||||
/**
|
||||
* Set the packer
|
||||
*
|
||||
* @param PackerInterface $packer
|
||||
* @return static
|
||||
*/
|
||||
public function withPacker(PackerInterface $packer);
|
||||
}
|
192
msd/vendor/desarrolla2/cache/src/Chain.php
vendored
Normal file
192
msd/vendor/desarrolla2/cache/src/Chain.php
vendored
Normal file
@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Packer\NopPacker;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Use multiple cache adapters.
|
||||
*/
|
||||
class Chain extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* @var CacheInterface[]
|
||||
*/
|
||||
protected $adapters;
|
||||
|
||||
/**
|
||||
* Create the default packer for this cache implementation
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new NopPacker();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Chain constructor.
|
||||
*
|
||||
* @param CacheInterface[] $adapters Fastest to slowest
|
||||
*/
|
||||
public function __construct(array $adapters)
|
||||
{
|
||||
foreach ($adapters as $adapter) {
|
||||
if (!$adapter instanceof CacheInterface) {
|
||||
throw new InvalidArgumentException("All adapters should be a cache implementation");
|
||||
}
|
||||
}
|
||||
|
||||
$this->adapters = $adapters;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$success = true;
|
||||
|
||||
foreach ($this->adapters as $adapter) {
|
||||
$success = $adapter->set($key, $value, $ttl) && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$success = true;
|
||||
|
||||
foreach ($this->adapters as $adapter) {
|
||||
$success = $adapter->setMultiple($values, $ttl) && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
foreach ($this->adapters as $adapter) {
|
||||
$result = $adapter->get($key); // Not using $default as we want to get null if the adapter doesn't have it
|
||||
|
||||
if (isset($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
$this->assertIterable($keys, 'keys are not iterable');
|
||||
|
||||
$missing = [];
|
||||
$values = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$this->assertKey($key);
|
||||
|
||||
$missing[] = $key;
|
||||
$values[$key] = $default;
|
||||
}
|
||||
|
||||
foreach ($this->adapters as $adapter) {
|
||||
if (empty($missing)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$found = [];
|
||||
foreach ($adapter->getMultiple($missing) as $key => $value) {
|
||||
if (isset($value)) {
|
||||
$found[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$values = array_merge($values, $found);
|
||||
$missing = array_values(array_diff($missing, array_keys($found)));
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
foreach ($this->adapters as $adapter) {
|
||||
if ($adapter->has($key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$success = true;
|
||||
|
||||
foreach ($this->adapters as $adapter) {
|
||||
$success = $adapter->delete($key) && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
$success = true;
|
||||
|
||||
foreach ($this->adapters as $adapter) {
|
||||
$success = $adapter->deleteMultiple($keys) && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$success = true;
|
||||
|
||||
foreach ($this->adapters as $adapter) {
|
||||
$success = $adapter->clear() && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
25
msd/vendor/desarrolla2/cache/src/Exception/BadMethodCallException.php
vendored
Normal file
25
msd/vendor/desarrolla2/cache/src/Exception/BadMethodCallException.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Exception;
|
||||
|
||||
use Psr\SimpleCache\CacheException as PsrCacheException;
|
||||
|
||||
/**
|
||||
* Exception bad method calls
|
||||
*/
|
||||
class BadMethodCallException extends \BadMethodCallException implements PsrCacheException
|
||||
{
|
||||
}
|
25
msd/vendor/desarrolla2/cache/src/Exception/CacheException.php
vendored
Normal file
25
msd/vendor/desarrolla2/cache/src/Exception/CacheException.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Exception;
|
||||
|
||||
use Psr\SimpleCache\CacheException as PsrCacheException;
|
||||
|
||||
/**
|
||||
* Interface used for all types of exceptions thrown by the implementing library.
|
||||
*/
|
||||
class CacheException extends \RuntimeException implements PsrCacheException
|
||||
{
|
||||
}
|
25
msd/vendor/desarrolla2/cache/src/Exception/InvalidArgumentException.php
vendored
Normal file
25
msd/vendor/desarrolla2/cache/src/Exception/InvalidArgumentException.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Exception;
|
||||
|
||||
use Psr\SimpleCache\InvalidArgumentException as PsrInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Exception for invalid cache arguments.
|
||||
*/
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements PsrInvalidArgumentException
|
||||
{
|
||||
}
|
25
msd/vendor/desarrolla2/cache/src/Exception/UnexpectedValueException.php
vendored
Normal file
25
msd/vendor/desarrolla2/cache/src/Exception/UnexpectedValueException.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Exception;
|
||||
|
||||
use Psr\SimpleCache\CacheException as PsrCacheException;
|
||||
|
||||
/**
|
||||
* Exception for unexpected values when reading from cache.
|
||||
*/
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements PsrCacheException
|
||||
{
|
||||
}
|
175
msd/vendor/desarrolla2/cache/src/File.php
vendored
Normal file
175
msd/vendor/desarrolla2/cache/src/File.php
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
use Desarrolla2\Cache\Exception\UnexpectedValueException;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\SerializePacker;
|
||||
|
||||
/**
|
||||
* Cache file.
|
||||
*/
|
||||
class File extends AbstractFile
|
||||
{
|
||||
/**
|
||||
* @var string 'embed', 'file', 'mtime'
|
||||
*/
|
||||
protected $ttlStrategy = 'embed';
|
||||
|
||||
/**
|
||||
* Create the default packer for this cache implementation
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new SerializePacker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set TTL strategy
|
||||
*
|
||||
* @param string $strategy
|
||||
*/
|
||||
protected function setTtlStrategyOption($strategy)
|
||||
{
|
||||
if (!in_array($strategy, ['embed', 'file', 'mtime'])) {
|
||||
throw new InvalidArgumentException("Unknown strategy '$strategy', should be 'embed', 'file' or 'mtime'");
|
||||
}
|
||||
|
||||
$this->ttlStrategy = $strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TTL strategy
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTtlStrategyOption(): string
|
||||
{
|
||||
return $this->ttlStrategy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the TTL using one of the strategies
|
||||
*
|
||||
* @param string $cacheFile
|
||||
* @return int
|
||||
*/
|
||||
protected function getTtl(string $cacheFile)
|
||||
{
|
||||
switch ($this->ttlStrategy) {
|
||||
case 'embed':
|
||||
return (int)$this->readLine($cacheFile);
|
||||
case 'file':
|
||||
return file_exists("$cacheFile.ttl")
|
||||
? (int)file_get_contents("$cacheFile.ttl")
|
||||
: PHP_INT_MAX;
|
||||
case 'mtime':
|
||||
return $this->getTtl($cacheFile) > 0 ? filemtime($cacheFile) + $this->ttl : PHP_INT_MAX;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException("Invalid TTL strategy '{$this->ttlStrategy}'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the TTL using one of the strategies
|
||||
*
|
||||
* @param int|null $expiration
|
||||
* @param string $contents
|
||||
* @param string $cacheFile
|
||||
* @return string The (modified) contents
|
||||
*/
|
||||
protected function setTtl($expiration, $contents, $cacheFile)
|
||||
{
|
||||
switch ($this->ttlStrategy) {
|
||||
case 'embed':
|
||||
$contents = ($expiration ?? PHP_INT_MAX) . "\n" . $contents;
|
||||
break;
|
||||
case 'file':
|
||||
if ($expiration !== null) {
|
||||
file_put_contents("$cacheFile.ttl", $expiration);
|
||||
}
|
||||
break;
|
||||
case 'mtime':
|
||||
// nothing
|
||||
break;
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if (!$this->has($key)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$cacheFile = $this->getFilename($key);
|
||||
$packed = $this->readFile($cacheFile);
|
||||
|
||||
if ($this->ttlStrategy === 'embed') {
|
||||
$packed = substr($packed, strpos($packed, "\n") + 1);
|
||||
}
|
||||
|
||||
return $this->unpack($packed);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
$cacheFile = $this->getFilename($key);
|
||||
|
||||
if (!file_exists($cacheFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ttl = $this->getTtl($cacheFile);
|
||||
|
||||
if ($ttl <= time()) {
|
||||
$this->deleteFile($cacheFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$cacheFile = $this->getFilename($key);
|
||||
$packed = $this->pack($value);
|
||||
|
||||
if (!is_string($packed)) {
|
||||
throw new UnexpectedValueException("Packer must create a string for the data to be cached to file");
|
||||
}
|
||||
|
||||
$contents = $this->setTtl($this->ttlToTimestamp($ttl), $packed, $cacheFile);
|
||||
|
||||
return $this->writeFile($cacheFile, $contents);
|
||||
}
|
||||
}
|
68
msd/vendor/desarrolla2/cache/src/File/BasicFilename.php
vendored
Normal file
68
msd/vendor/desarrolla2/cache/src/File/BasicFilename.php
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\File;
|
||||
|
||||
/**
|
||||
* Create a path for a key
|
||||
*/
|
||||
class BasicFilename
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $format;
|
||||
|
||||
/**
|
||||
* BasicFilename constructor.
|
||||
*
|
||||
* @param string $format
|
||||
*/
|
||||
public function __construct(string $format)
|
||||
{
|
||||
$this->format = $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormat(): string
|
||||
{
|
||||
return $this->format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the path for a key
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke(string $key): string
|
||||
{
|
||||
return sprintf($this->format, $key ?: '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast to string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->getFormat();
|
||||
}
|
||||
}
|
121
msd/vendor/desarrolla2/cache/src/File/TrieFilename.php
vendored
Normal file
121
msd/vendor/desarrolla2/cache/src/File/TrieFilename.php
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\File;
|
||||
|
||||
/**
|
||||
* Create a path for a key as prefix tree directory structure.
|
||||
*
|
||||
* @see https://en.wikipedia.org/wiki/Trie
|
||||
*/
|
||||
class TrieFilename
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $format;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $levels;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $hash;
|
||||
|
||||
|
||||
/**
|
||||
* TrieFilename constructor.
|
||||
*
|
||||
* @param string $format
|
||||
* @param int $levels The depth of the structure
|
||||
* @param bool $hash MD5 hash the key to get a better spread
|
||||
*/
|
||||
public function __construct(string $format, int $levels = 1, bool $hash = false)
|
||||
{
|
||||
$this->format = $format;
|
||||
$this->levels = $levels;
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormat(): string
|
||||
{
|
||||
return $this->format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the depth of the structure
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLevels(): int
|
||||
{
|
||||
return $this->levels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will the key be hashed to create the trie.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isHashed(): bool
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the path for a key
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke(string $key): string
|
||||
{
|
||||
if (empty($key)) {
|
||||
return $this->wildcardPath();
|
||||
}
|
||||
|
||||
$dirname = $this->hash ? base_convert(md5($key), 16, 36) : $key;
|
||||
$filename = sprintf($this->format, $key);
|
||||
|
||||
$path = '';
|
||||
|
||||
for ($length = 1; $length <= $this->levels; $length++) {
|
||||
$path .= substr($dirname, 0, $length) . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
return $path . $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a path for all files (using glob)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function wildcardPath(): string
|
||||
{
|
||||
$filename = sprintf($this->format, '*');
|
||||
|
||||
return str_repeat('*' . DIRECTORY_SEPARATOR, $this->levels) . $filename;
|
||||
}
|
||||
}
|
218
msd/vendor/desarrolla2/cache/src/Memcached.php
vendored
Normal file
218
msd/vendor/desarrolla2/cache/src/Memcached.php
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\NopPacker;
|
||||
use Memcached as MemcachedServer;
|
||||
|
||||
/**
|
||||
* Memcached
|
||||
*/
|
||||
class Memcached extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* @var MemcachedServer
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* @param MemcachedServer $server
|
||||
*/
|
||||
public function __construct(MemcachedServer $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the default packer for this cache implementation
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new NopPacker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the key
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function assertKey($key): void
|
||||
{
|
||||
parent::assertKey($key);
|
||||
|
||||
if (strlen($key) > 250) {
|
||||
throw new InvalidArgumentException("Key to long, max 250 characters");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack all values and turn keys into ids
|
||||
*
|
||||
* @param iterable $values
|
||||
* @return array
|
||||
*/
|
||||
protected function packValues(iterable $values): array
|
||||
{
|
||||
$packed = [];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$this->assertKey(is_int($key) ? (string)$key : $key);
|
||||
$packed[$key] = $this->pack($value);
|
||||
}
|
||||
|
||||
return $packed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$this->assertKey($key);
|
||||
|
||||
$data = $this->server->get($key);
|
||||
|
||||
if ($this->server->getResultCode() !== MemcachedServer::RES_SUCCESS) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->unpack($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
$this->assertKey($key);
|
||||
$this->server->get($key);
|
||||
|
||||
$result = $this->server->getResultCode();
|
||||
|
||||
return $result === MemcachedServer::RES_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$this->assertKey($key);
|
||||
|
||||
$packed = $this->pack($value);
|
||||
$ttlTime = $this->ttlToMemcachedTime($ttl);
|
||||
|
||||
if ($ttlTime === false) {
|
||||
return $this->delete($key);
|
||||
}
|
||||
|
||||
$success = $this->server->set($key, $packed, $ttlTime);
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$this->server->delete($this->keyToId($key));
|
||||
|
||||
$result = $this->server->getResultCode();
|
||||
|
||||
return $result === MemcachedServer::RES_SUCCESS || $result === MemcachedServer::RES_NOTFOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
$this->assertIterable($keys, 'keys not iterable');
|
||||
$keysArr = is_array($keys) ? $keys : iterator_to_array($keys, false);
|
||||
array_walk($keysArr, [$this, 'assertKey']);
|
||||
|
||||
$result = $this->server->getMulti($keysArr);
|
||||
|
||||
if ($result === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$items = array_fill_keys($keysArr, $default);
|
||||
|
||||
foreach ($result as $key => $value) {
|
||||
$items[$key] = $this->unpack($value);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$this->assertIterable($values, 'values not iterable');
|
||||
|
||||
$packed = $this->packValues($values);
|
||||
$ttlTime = $this->ttlToMemcachedTime($ttl);
|
||||
|
||||
if ($ttlTime === false) {
|
||||
return $this->server->deleteMulti(array_keys($packed));
|
||||
}
|
||||
|
||||
return $this->server->setMulti($packed, $ttlTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return $this->server->flush();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert ttl to timestamp or seconds.
|
||||
*
|
||||
* @see http://php.net/manual/en/memcached.expiration.php
|
||||
*
|
||||
* @param null|int|\DateInterval $ttl
|
||||
* @return int|null
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function ttlToMemcachedTime($ttl)
|
||||
{
|
||||
$seconds = $this->ttlToSeconds($ttl);
|
||||
|
||||
if ($seconds <= 0) {
|
||||
return isset($seconds) ? false : 0;
|
||||
}
|
||||
|
||||
/* 2592000 seconds = 30 days */
|
||||
return $seconds <= 2592000 ? $seconds : $this->ttlToTimestamp($ttl);
|
||||
}
|
||||
}
|
165
msd/vendor/desarrolla2/cache/src/Memory.php
vendored
Normal file
165
msd/vendor/desarrolla2/cache/src/Memory.php
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\SerializePacker;
|
||||
|
||||
/**
|
||||
* Memory
|
||||
*/
|
||||
class Memory extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* Limit the amount of entries
|
||||
* @var int
|
||||
*/
|
||||
protected $limit = PHP_INT_MAX;
|
||||
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $cache = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $cacheTtl = [];
|
||||
|
||||
|
||||
/**
|
||||
* Create the default packer for this cache implementation.
|
||||
* {@internal NopPacker might fail PSR-16, as cached objects would change}
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new SerializePacker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a clone of this object.
|
||||
* Set by cache reference, thus using the same pool.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
protected function cloneSelf(): AbstractCache
|
||||
{
|
||||
$clone = clone $this;
|
||||
|
||||
$clone->cache =& $this->cache;
|
||||
$clone->cacheTtl =& $this->cacheTtl;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max number of items
|
||||
*
|
||||
* @param int $limit
|
||||
*/
|
||||
protected function setLimitOption($limit)
|
||||
{
|
||||
$this->limit = (int)$limit ?: PHP_INT_MAX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the max number of items
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getLimitOption()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if (!$this->has($key)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$id = $this->keyToId($key);
|
||||
|
||||
return $this->unpack($this->cache[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
|
||||
if (!isset($this->cacheTtl[$id])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->cacheTtl[$id] <= time()) {
|
||||
unset($this->cache[$id], $this->cacheTtl[$id]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
if (count($this->cache) >= $this->limit) {
|
||||
$deleteKey = key($this->cache);
|
||||
unset($this->cache[$deleteKey], $this->cacheTtl[$deleteKey]);
|
||||
}
|
||||
|
||||
$id = $this->keyToId($key);
|
||||
|
||||
$this->cache[$id] = $this->pack($value);
|
||||
$this->cacheTtl[$id] = $this->ttlToTimestamp($ttl) ?? PHP_INT_MAX;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
unset($this->cache[$id], $this->cacheTtl[$id]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->cache = [];
|
||||
$this->cacheTtl = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
273
msd/vendor/desarrolla2/cache/src/MongoDB.php
vendored
Normal file
273
msd/vendor/desarrolla2/cache/src/MongoDB.php
vendored
Normal file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\MongoDBBinaryPacker;
|
||||
use Desarrolla2\Cache\Option\InitializeTrait as InitializeOption;
|
||||
use MongoDB\Collection;
|
||||
use MongoDB\BSON\UTCDatetime as BSONUTCDateTime;
|
||||
use MongoDB\Driver\Exception\RuntimeException as MongoDBRuntimeException;
|
||||
|
||||
/**
|
||||
* MongoDB cache implementation
|
||||
*/
|
||||
class MongoDB extends AbstractCache
|
||||
{
|
||||
use InitializeOption;
|
||||
|
||||
/**
|
||||
* @var Collection
|
||||
*/
|
||||
protected $collection;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function __construct(Collection $collection)
|
||||
{
|
||||
$this->collection = $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the DB collection.
|
||||
* Set TTL index.
|
||||
*/
|
||||
protected function initialize(): void
|
||||
{
|
||||
$this->collection->createIndex(['ttl' => 1], ['expireAfterSeconds' => 0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the default packer for this cache implementation.
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new MongoDBBinaryPacker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filter for key and ttl.
|
||||
*
|
||||
* @param string|iterable $key
|
||||
* @return array
|
||||
*/
|
||||
protected function filter($key)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$key = ['$in' => $key];
|
||||
}
|
||||
|
||||
return [
|
||||
'_id' => $key,
|
||||
'$or' => [
|
||||
['ttl' => ['$gt' => new BSONUTCDateTime($this->currentTimestamp() * 1000)]],
|
||||
['ttl' => null]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$filter = $this->filter($this->keyToId($key));
|
||||
|
||||
try {
|
||||
$data = $this->collection->findOne($filter);
|
||||
} catch (MongoDBRuntimeException $e) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return isset($data) ? $this->unpack($data['value']) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
$idKeyPairs = $this->mapKeysToIds($keys);
|
||||
|
||||
if (empty($idKeyPairs)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$filter = $this->filter(array_keys($idKeyPairs));
|
||||
$items = array_fill_keys(array_values($idKeyPairs), $default);
|
||||
|
||||
try {
|
||||
$rows = $this->collection->find($filter);
|
||||
} catch (MongoDBRuntimeException $e) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$id = $row['_id'];
|
||||
$key = $idKeyPairs[$id];
|
||||
|
||||
$items[$key] = $this->unpack($row['value']);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
$filter = $this->filter($this->keyToId($key));
|
||||
|
||||
try {
|
||||
$count = $this->collection->count($filter);
|
||||
} catch (MongoDBRuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
|
||||
$item = [
|
||||
'_id' => $id,
|
||||
'ttl' => $this->getTtlBSON($ttl),
|
||||
'value' => $this->pack($value)
|
||||
];
|
||||
|
||||
try {
|
||||
$this->collection->replaceOne(['_id' => $id], $item, ['upsert' => true]);
|
||||
} catch (MongoDBRuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$this->assertIterable($values, 'values not iterable');
|
||||
|
||||
if (empty($values)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$bsonTtl = $this->getTtlBSON($ttl);
|
||||
$items = [];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$id = $this->keyToId(is_int($key) ? (string)$key : $key);
|
||||
|
||||
$items[] = [
|
||||
'replaceOne' => [
|
||||
['_id' => $id],
|
||||
[
|
||||
'_id' => $id,
|
||||
'ttl' => $bsonTtl,
|
||||
'value' => $this->pack($value)
|
||||
],
|
||||
[ 'upsert' => true ]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
try {
|
||||
$this->collection->bulkWrite($items);
|
||||
} catch (MongoDBRuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
|
||||
try {
|
||||
$this->collection->deleteOne(['_id' => $id]);
|
||||
} catch (MongoDBRuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
$idKeyPairs = $this->mapKeysToIds($keys);
|
||||
|
||||
try {
|
||||
if (!empty($idKeyPairs)) {
|
||||
$this->collection->deleteMany(['_id' => ['$in' => array_keys($idKeyPairs)]]);
|
||||
}
|
||||
} catch (MongoDBRuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
try {
|
||||
$this->collection->drop();
|
||||
} catch (MongoDBRuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->requireInitialization();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get TTL as Date type BSON object
|
||||
*
|
||||
* @param null|int|\DateInterval $ttl
|
||||
* @return BSONUTCDatetime|null
|
||||
*/
|
||||
protected function getTtlBSON($ttl): ?BSONUTCDatetime
|
||||
{
|
||||
return isset($ttl) ? new BSONUTCDateTime($this->ttlToTimestamp($ttl) * 1000) : null;
|
||||
}
|
||||
}
|
312
msd/vendor/desarrolla2/cache/src/Mysqli.php
vendored
Normal file
312
msd/vendor/desarrolla2/cache/src/Mysqli.php
vendored
Normal file
@ -0,0 +1,312 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Option\InitializeTrait;
|
||||
use mysqli as Server;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\SerializePacker;
|
||||
|
||||
/**
|
||||
* Mysqli cache adapter.
|
||||
*
|
||||
* Errors are silently ignored but exceptions are **not** caught. Beware when using `mysqli_report()` to throw a
|
||||
* `mysqli_sql_exception` on error.
|
||||
*/
|
||||
class Mysqli extends AbstractCache
|
||||
{
|
||||
use InitializeTrait;
|
||||
|
||||
/**
|
||||
* @var Server
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'cache';
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param Server $server
|
||||
*/
|
||||
public function __construct(Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize table.
|
||||
* Automatically delete old cache.
|
||||
*/
|
||||
protected function initialize(): void
|
||||
{
|
||||
if ($this->initialized !== false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->query(
|
||||
"CREATE TABLE IF NOT EXISTS `{table}` "
|
||||
. "( `key` VARCHAR(255), `value` BLOB, `ttl` BIGINT UNSIGNED, PRIMARY KEY (`key`) )"
|
||||
);
|
||||
|
||||
$this->query(
|
||||
"CREATE EVENT IF NOT EXISTS `apply_ttl_{$this->table}` ON SCHEDULE EVERY 1 HOUR DO BEGIN"
|
||||
. " DELETE FROM {table} WHERE `ttl` < UNIX_TIMESTAMP();"
|
||||
. " END"
|
||||
);
|
||||
|
||||
$this->initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the default packer for this cache implementation.
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new SerializePacker();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the table name
|
||||
*
|
||||
* @param string $table
|
||||
*/
|
||||
public function setTableOption(string $table)
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->requireInitialization();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTableOption(): string
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$result = $this->query(
|
||||
'SELECT `value` FROM {table} WHERE `key` = ? AND (`ttl` > ? OR `ttl` IS NULL) LIMIT 1',
|
||||
'si',
|
||||
$this->keyToId($key),
|
||||
$this->currentTimestamp()
|
||||
);
|
||||
|
||||
$row = $result !== false ? $result->fetch_row() : null;
|
||||
|
||||
return $row ? $this->unpack($row[0]) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
$idKeyPairs = $this->mapKeysToIds($keys);
|
||||
|
||||
if (empty($idKeyPairs)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$this->initialize();
|
||||
|
||||
$values = array_fill_keys(array_values($idKeyPairs), $default);
|
||||
|
||||
$placeholders = rtrim(str_repeat('?, ', count($idKeyPairs)), ', ');
|
||||
$paramTypes = str_repeat('s', count($idKeyPairs)) . 'i';
|
||||
$params = array_keys($idKeyPairs);
|
||||
$params[] = $this->currentTimestamp();
|
||||
|
||||
$result = $this->query(
|
||||
"SELECT `key`, `value` FROM {table} WHERE `key` IN ($placeholders) AND (`ttl` > ? OR `ttl` IS NULL)",
|
||||
$paramTypes,
|
||||
...$params
|
||||
);
|
||||
|
||||
while (([$id, $value] = $result->fetch_row())) {
|
||||
$key = $idKeyPairs[$id];
|
||||
$values[$key] = $this->unpack($value);
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$result = $this->query(
|
||||
'SELECT COUNT(`key`) FROM {table} WHERE `key` = ? AND (`ttl` > ? OR `ttl` IS NULL) LIMIT 1',
|
||||
'si',
|
||||
$this->keyToId($key),
|
||||
$this->currentTimestamp()
|
||||
);
|
||||
|
||||
[$count] = $result ? $result->fetch_row() : [null];
|
||||
|
||||
return isset($count) && $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$result = $this->query(
|
||||
'REPLACE INTO {table} (`key`, `value`, `ttl`) VALUES (?, ?, ?)',
|
||||
'ssi',
|
||||
$this->keyToId($key),
|
||||
$this->pack($value),
|
||||
$this->ttlToTimestamp($ttl)
|
||||
);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$this->assertIterable($values, 'values not iterable');
|
||||
|
||||
if (empty($values)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->initialize();
|
||||
|
||||
$count = 0;
|
||||
$params = [];
|
||||
$timeTtl = $this->ttlToTimestamp($ttl);
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$count++;
|
||||
$params[] = $this->keyToId(is_int($key) ? (string)$key : $key);
|
||||
$params[] = $this->pack($value);
|
||||
$params[] = $timeTtl;
|
||||
}
|
||||
|
||||
$query = 'REPLACE INTO {table} (`key`, `value`, `ttl`) VALUES '
|
||||
. rtrim(str_repeat('(?, ?, ?), ', $count), ', ');
|
||||
|
||||
return (bool)$this->query($query, str_repeat('ssi', $count), ...$params);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return (bool)$this->query(
|
||||
'DELETE FROM {table} WHERE `key` = ?',
|
||||
's',
|
||||
$this->keyToId($key)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
$idKeyPairs = $this->mapKeysToIds($keys);
|
||||
|
||||
if (empty($idKeyPairs)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->initialize();
|
||||
|
||||
$placeholders = rtrim(str_repeat('?, ', count($idKeyPairs)), ', ');
|
||||
$paramTypes = str_repeat('s', count($idKeyPairs));
|
||||
|
||||
return (bool)$this->query(
|
||||
"DELETE FROM {table} WHERE `key` IN ($placeholders)",
|
||||
$paramTypes,
|
||||
...array_keys($idKeyPairs)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->initialize();
|
||||
return (bool)$this->query('TRUNCATE {table}');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query the MySQL server
|
||||
*
|
||||
* @param string $query
|
||||
* @param string $types
|
||||
* @param mixed[] $params
|
||||
* @return \mysqli_result|bool
|
||||
*/
|
||||
protected function query($query, $types = '', ...$params)
|
||||
{
|
||||
$sql = str_replace('{table}', $this->table, $query);
|
||||
|
||||
if ($params === []) {
|
||||
$ret = $this->server->query($sql);
|
||||
} else {
|
||||
$statement = $this->server->prepare($sql);
|
||||
|
||||
if ($statement !== false) {
|
||||
$statement->bind_param($types, ...$params);
|
||||
|
||||
$ret = $statement->execute();
|
||||
$ret = $ret ? ($statement->get_result() ?: true) : false;
|
||||
} else {
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->server->error) {
|
||||
trigger_error($this->server->error . " $sql", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
93
msd/vendor/desarrolla2/cache/src/NotCache.php
vendored
Normal file
93
msd/vendor/desarrolla2/cache/src/NotCache.php
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\AbstractCache;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\NopPacker;
|
||||
|
||||
/**
|
||||
* Dummy cache handler
|
||||
*/
|
||||
class NotCache extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* Create the default packer for this cache implementation.
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new NopPacker();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
91
msd/vendor/desarrolla2/cache/src/Option/FilenameTrait.php
vendored
Normal file
91
msd/vendor/desarrolla2/cache/src/Option/FilenameTrait.php
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Option;
|
||||
|
||||
use TypeError;
|
||||
use Desarrolla2\Cache\File\BasicFilename;
|
||||
|
||||
/**
|
||||
* Use filename generator
|
||||
*/
|
||||
trait FilenameTrait
|
||||
{
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
|
||||
/**
|
||||
* Filename format or callable.
|
||||
* The filename format will be applied using sprintf, replacing `%s` with the key.
|
||||
*
|
||||
* @param string|callable $filename
|
||||
* @return void
|
||||
*/
|
||||
protected function setFilenameOption($filename): void
|
||||
{
|
||||
if (is_string($filename)) {
|
||||
$filename = new BasicFilename($filename);
|
||||
}
|
||||
|
||||
if (!is_callable($filename)) {
|
||||
throw new TypeError("Filename should be a string or callable");
|
||||
}
|
||||
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filename callable
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
protected function getFilenameOption(): callable
|
||||
{
|
||||
if (!isset($this->filename)) {
|
||||
$this->filename = new BasicFilename('%s.' . $this->getPacker()->getType());
|
||||
}
|
||||
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a filename based on the key
|
||||
*
|
||||
* @param string|mixed $key
|
||||
* @return string
|
||||
*/
|
||||
protected function getFilename($key): string
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
$generator = $this->getFilenameOption();
|
||||
|
||||
return $this->cacheDir . DIRECTORY_SEPARATOR . $generator($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a wildcard for all files
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getWildcard(): string
|
||||
{
|
||||
$generator = $this->getFilenameOption();
|
||||
|
||||
return $this->cacheDir . DIRECTORY_SEPARATOR . $generator('');
|
||||
}
|
||||
}
|
65
msd/vendor/desarrolla2/cache/src/Option/InitializeTrait.php
vendored
Normal file
65
msd/vendor/desarrolla2/cache/src/Option/InitializeTrait.php
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Option;
|
||||
|
||||
/**
|
||||
* Auto initialize the cache
|
||||
*/
|
||||
trait InitializeTrait
|
||||
{
|
||||
/**
|
||||
* Is cache initialized
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $initialized = false;
|
||||
|
||||
|
||||
/**
|
||||
* Enable/disable initialization
|
||||
*
|
||||
* @param bool $enabled
|
||||
*/
|
||||
public function setInitializeOption(bool $enabled)
|
||||
{
|
||||
$this->initialized = $enabled ? (bool)$this->initialized : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should initialize
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function getInitializeOption(): bool
|
||||
{
|
||||
return $this->initialized !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark as initialization required (if enabled)
|
||||
*/
|
||||
protected function requireInitialization()
|
||||
{
|
||||
$this->initialized = isset($this->initialized) ? false : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function initialize(): void;
|
||||
}
|
49
msd/vendor/desarrolla2/cache/src/Option/PrefixTrait.php
vendored
Normal file
49
msd/vendor/desarrolla2/cache/src/Option/PrefixTrait.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Option;
|
||||
|
||||
/**
|
||||
* Prefix option
|
||||
*/
|
||||
trait PrefixTrait
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix = '';
|
||||
|
||||
|
||||
/**
|
||||
* Set the key prefix
|
||||
*
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
protected function setPrefixOption(string $prefix): void
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPrefixOption(): string
|
||||
{
|
||||
return $this->prefix;
|
||||
}
|
||||
}
|
54
msd/vendor/desarrolla2/cache/src/Option/TtlTrait.php
vendored
Normal file
54
msd/vendor/desarrolla2/cache/src/Option/TtlTrait.php
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Option;
|
||||
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* TTL option
|
||||
*/
|
||||
trait TtlTrait
|
||||
{
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
protected $ttl = null;
|
||||
|
||||
/**
|
||||
* Set the maximum time to live (ttl)
|
||||
*
|
||||
* @param int|null $value Seconds or null to live forever
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function setTtlOption(?int $value): void
|
||||
{
|
||||
if (isset($value) && $value < 1) {
|
||||
throw new InvalidArgumentException('ttl cant be lower than 1');
|
||||
}
|
||||
|
||||
$this->ttl = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum time to live (ttl)
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
protected function getTtlOption(): ?int
|
||||
{
|
||||
return $this->ttl;
|
||||
}
|
||||
}
|
69
msd/vendor/desarrolla2/cache/src/Packer/JsonPacker.php
vendored
Normal file
69
msd/vendor/desarrolla2/cache/src/Packer/JsonPacker.php
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Packer;
|
||||
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Pack value through serialization
|
||||
*/
|
||||
class JsonPacker implements PackerInterface
|
||||
{
|
||||
/**
|
||||
* Get cache type (might be used as file extension)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'json';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
public function pack($value)
|
||||
{
|
||||
return json_encode($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack the value
|
||||
*
|
||||
* @param string $packed
|
||||
* @return mixed
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function unpack($packed)
|
||||
{
|
||||
if (!is_string($packed)) {
|
||||
throw new InvalidArgumentException("packed value should be a string");
|
||||
}
|
||||
|
||||
$ret = json_decode($packed);
|
||||
|
||||
if (!isset($ret) && json_last_error()) {
|
||||
throw new \UnexpectedValueException("packed value is not a valid JSON string");
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
77
msd/vendor/desarrolla2/cache/src/Packer/MongoDBBinaryPacker.php
vendored
Normal file
77
msd/vendor/desarrolla2/cache/src/Packer/MongoDBBinaryPacker.php
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Cache\Packer;
|
||||
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use MongoDB\BSON\Binary;
|
||||
|
||||
/**
|
||||
* Pack as BSON binary
|
||||
*
|
||||
* @todo Don't use serialize when packer chain is here.
|
||||
*/
|
||||
class MongoDBBinaryPacker implements PackerInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* SerializePacker constructor
|
||||
*
|
||||
* @param array $options Any options to be provided to unserialize()
|
||||
*/
|
||||
public function __construct(array $options = ['allowed_classes' => true])
|
||||
{
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache type (might be used as file extension)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'bson';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
public function pack($value)
|
||||
{
|
||||
return new Binary(serialize($value), Binary::TYPE_GENERIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack the value
|
||||
*
|
||||
* @param string $packed
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException if he value can't be unpacked
|
||||
*/
|
||||
public function unpack($packed)
|
||||
{
|
||||
if (!$packed instanceof Binary) {
|
||||
throw new \InvalidArgumentException("packed value should be BSON binary");
|
||||
}
|
||||
|
||||
return unserialize((string)$packed, $this->options);
|
||||
}
|
||||
}
|
57
msd/vendor/desarrolla2/cache/src/Packer/NopPacker.php
vendored
Normal file
57
msd/vendor/desarrolla2/cache/src/Packer/NopPacker.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Packer;
|
||||
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
|
||||
/**
|
||||
* Don't pack, just straight passthrough
|
||||
*/
|
||||
class NopPacker implements PackerInterface
|
||||
{
|
||||
/**
|
||||
* Get cache type (might be used as file extension)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'data';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function pack($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack the value
|
||||
*
|
||||
* @param mixed $packed
|
||||
* @return mixed
|
||||
*/
|
||||
public function unpack($packed)
|
||||
{
|
||||
return $packed;
|
||||
}
|
||||
}
|
47
msd/vendor/desarrolla2/cache/src/Packer/PackerInterface.php
vendored
Normal file
47
msd/vendor/desarrolla2/cache/src/Packer/PackerInterface.php
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Packer;
|
||||
|
||||
/**
|
||||
* Interface for packer / unpacker
|
||||
*/
|
||||
interface PackerInterface
|
||||
{
|
||||
/**
|
||||
* Get cache type (might be used as file extension)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType();
|
||||
|
||||
/**
|
||||
* Pack the value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string|mixed
|
||||
*/
|
||||
public function pack($value);
|
||||
|
||||
/**
|
||||
* Unpack the value
|
||||
*
|
||||
* @param string|mixed $packed
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException if the value can't be unpacked
|
||||
*/
|
||||
public function unpack($packed);
|
||||
}
|
86
msd/vendor/desarrolla2/cache/src/Packer/PackingTrait.php
vendored
Normal file
86
msd/vendor/desarrolla2/cache/src/Packer/PackingTrait.php
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Packer;
|
||||
|
||||
/**
|
||||
* Support packing for Caching adapter
|
||||
*/
|
||||
trait PackingTrait
|
||||
{
|
||||
/**
|
||||
* @var PackerInterface
|
||||
*/
|
||||
protected $packer;
|
||||
|
||||
|
||||
/**
|
||||
* Create the default packer for this cache implementation
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
abstract protected static function createDefaultPacker(): PackerInterface;
|
||||
|
||||
/**
|
||||
* Set a packer to pack (serialialize) and unpack (unserialize) the data.
|
||||
*
|
||||
* @param PackerInterface $packer
|
||||
* @return static
|
||||
*/
|
||||
public function withPacker(PackerInterface $packer)
|
||||
{
|
||||
$cache = $this->cloneSelf();
|
||||
$cache->packer = $packer;
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packer
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected function getPacker(): PackerInterface
|
||||
{
|
||||
if (!isset($this->packer)) {
|
||||
$this->packer = static::createDefaultPacker();
|
||||
}
|
||||
|
||||
return $this->packer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string|mixed
|
||||
*/
|
||||
protected function pack($value)
|
||||
{
|
||||
return $this->getPacker()->pack($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack the data to retrieve the value
|
||||
*
|
||||
* @param string|mixed $packed
|
||||
* @return mixed
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
protected function unpack($packed)
|
||||
{
|
||||
return $this->getPacker()->unpack($packed);
|
||||
}
|
||||
}
|
78
msd/vendor/desarrolla2/cache/src/Packer/SerializePacker.php
vendored
Normal file
78
msd/vendor/desarrolla2/cache/src/Packer/SerializePacker.php
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache\Packer;
|
||||
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Pack value through serialization
|
||||
*/
|
||||
class SerializePacker implements PackerInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* SerializePacker constructor
|
||||
*
|
||||
* @param array $options Any options to be provided to unserialize()
|
||||
*/
|
||||
public function __construct(array $options = ['allowed_classes' => true])
|
||||
{
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache type (might be used as file extension)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'php.cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
public function pack($value)
|
||||
{
|
||||
return serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack the value
|
||||
*
|
||||
* @param string $packed
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException if he value can't be unpacked
|
||||
*/
|
||||
public function unpack($packed)
|
||||
{
|
||||
if (!is_string($packed)) {
|
||||
throw new InvalidArgumentException("packed value should be a string");
|
||||
}
|
||||
|
||||
return unserialize($packed, $this->options);
|
||||
}
|
||||
}
|
111
msd/vendor/desarrolla2/cache/src/PhpFile.php
vendored
Normal file
111
msd/vendor/desarrolla2/cache/src/PhpFile.php
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\AbstractFile;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\SerializePacker;
|
||||
use Desarrolla2\Cache\File\BasicFilename;
|
||||
|
||||
/**
|
||||
* Cache file as PHP script.
|
||||
*/
|
||||
class PhpFile extends AbstractFile
|
||||
{
|
||||
/**
|
||||
* Create the default packer for this cache implementation.
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new SerializePacker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filename callable
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
protected function getFilenameOption(): callable
|
||||
{
|
||||
if (!isset($this->filename)) {
|
||||
$this->filename = new BasicFilename('%s.php');
|
||||
}
|
||||
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PHP script returning the cached value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param int|null $ttl
|
||||
* @return string
|
||||
*/
|
||||
public function createScript($value, ?int $ttl): string
|
||||
{
|
||||
$macro = var_export($value, true);
|
||||
|
||||
if (strpos($macro, 'stdClass::__set_state') !== false) {
|
||||
$macro = preg_replace_callback("/('([^'\\\\]++|''\\.)')|stdClass::__set_state/", $macro, function($match) {
|
||||
return empty($match[1]) ? '(object)' : $match[1];
|
||||
});
|
||||
}
|
||||
|
||||
return $ttl !== null
|
||||
? "<?php return time() < {$ttl} ? {$macro} : false;"
|
||||
: "<?php return {$macro};";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$cacheFile = $this->getFilename($key);
|
||||
|
||||
if (!file_exists($cacheFile)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$packed = include $cacheFile;
|
||||
|
||||
return $packed === false ? $default : $this->unpack($packed);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return $this->get($key) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$cacheFile = $this->getFilename($key);
|
||||
|
||||
$packed = $this->pack($value);
|
||||
$script = $this->createScript($packed, $this->ttlToTimestamp($ttl));
|
||||
|
||||
return $this->writeFile($cacheFile, $script);
|
||||
}
|
||||
}
|
245
msd/vendor/desarrolla2/cache/src/Predis.php
vendored
Normal file
245
msd/vendor/desarrolla2/cache/src/Predis.php
vendored
Normal file
@ -0,0 +1,245 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Cache package.
|
||||
*
|
||||
* Copyright (c) Daniel González
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Daniel González <daniel@desarrolla2.com>
|
||||
* @author Arnold Daniels <arnold@jasny.net>
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desarrolla2\Cache;
|
||||
|
||||
use Desarrolla2\Cache\AbstractCache;
|
||||
use Desarrolla2\Cache\Exception\UnexpectedValueException;
|
||||
use Desarrolla2\Cache\Packer\PackerInterface;
|
||||
use Desarrolla2\Cache\Packer\SerializePacker;
|
||||
use Predis\Client;
|
||||
use Predis\Response\ServerException;
|
||||
use Predis\Response\Status;
|
||||
use Predis\Response\ErrorInterface;
|
||||
|
||||
/**
|
||||
* Predis cache adapter.
|
||||
*
|
||||
* Errors are silently ignored but ServerExceptions are **not** caught. To PSR-16 compliant disable the `exception`
|
||||
* option.
|
||||
*/
|
||||
class Predis extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected $predis;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
* @see predis documentation about how know your configuration https://github.com/nrk/predis
|
||||
*
|
||||
* @param Client $client
|
||||
*/
|
||||
public function __construct(Client $client)
|
||||
{
|
||||
$this->predis = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the default packer for this cache implementation.
|
||||
*
|
||||
* @return PackerInterface
|
||||
*/
|
||||
protected static function createDefaultPacker(): PackerInterface
|
||||
{
|
||||
return new SerializePacker();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run a predis command.
|
||||
*
|
||||
* @param string $cmd
|
||||
* @param mixed ...$args
|
||||
* @return mixed|bool
|
||||
*/
|
||||
protected function execCommand(string $cmd, ...$args)
|
||||
{
|
||||
$command = $this->predis->createCommand($cmd, $args);
|
||||
$response = $this->predis->executeCommand($command);
|
||||
|
||||
if ($response instanceof ErrorInterface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($response instanceof Status) {
|
||||
return $response->getPayload() === 'OK';
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set multiple (mset) with expire
|
||||
*
|
||||
* @param array $dictionary
|
||||
* @param int|null $ttlSeconds
|
||||
* @return bool
|
||||
*/
|
||||
protected function msetExpire(array $dictionary, ?int $ttlSeconds): bool
|
||||
{
|
||||
if (empty($dictionary)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isset($ttlSeconds)) {
|
||||
return $this->execCommand('MSET', $dictionary);
|
||||
}
|
||||
|
||||
$transaction = $this->predis->transaction();
|
||||
|
||||
foreach ($dictionary as $key => $value) {
|
||||
$transaction->set($key, $value, 'EX', $ttlSeconds);
|
||||
}
|
||||
|
||||
try {
|
||||
$responses = $transaction->execute();
|
||||
} catch (ServerException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ok = array_reduce($responses, function($ok, $response) {
|
||||
return $ok && $response instanceof Status && $response->getPayload() === 'OK';
|
||||
}, true);
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
$response = $this->execCommand('GET', $id);
|
||||
|
||||
return !empty($response) ? $this->unpack($response) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
$idKeyPairs = $this->mapKeysToIds($keys);
|
||||
$ids = array_keys($idKeyPairs);
|
||||
|
||||
$response = $this->execCommand('MGET', $ids);
|
||||
|
||||
if ($response === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$items = [];
|
||||
$packedItems = array_combine(array_values($idKeyPairs), $response);
|
||||
|
||||
foreach ($packedItems as $key => $packed) {
|
||||
$items[$key] = isset($packed) ? $this->unpack($packed) : $default;
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return $this->execCommand('EXISTS', $this->keyToId($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
$packed = $this->pack($value);
|
||||
|
||||
if (!is_string($packed)) {
|
||||
throw new UnexpectedValueException("Packer must create a string for the data");
|
||||
}
|
||||
|
||||
$ttlSeconds = $this->ttlToSeconds($ttl);
|
||||
|
||||
if (isset($ttlSeconds) && $ttlSeconds <= 0) {
|
||||
return $this->execCommand('DEL', [$id]);
|
||||
}
|
||||
|
||||
return !isset($ttlSeconds)
|
||||
? $this->execCommand('SET', $id, $packed)
|
||||
: $this->execCommand('SETEX', $id, $ttlSeconds, $packed);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$this->assertIterable($values, 'values not iterable');
|
||||
|
||||
$dictionary = [];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$id = $this->keyToId(is_int($key) ? (string)$key : $key);
|
||||
$packed = $this->pack($value);
|
||||
|
||||
if (!is_string($packed)) {
|
||||
throw new UnexpectedValueException("Packer must create a string for the data");
|
||||
}
|
||||
|
||||
$dictionary[$id] = $packed;
|
||||
}
|
||||
|
||||
$ttlSeconds = $this->ttlToSeconds($ttl);
|
||||
|
||||
if (isset($ttlSeconds) && $ttlSeconds <= 0) {
|
||||
return $this->execCommand('DEL', array_keys($dictionary));
|
||||
}
|
||||
|
||||
return $this->msetExpire($dictionary, $ttlSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$id = $this->keyToId($key);
|
||||
|
||||
return $this->execCommand('DEL', [$id]) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
$ids = array_keys($this->mapKeysToIds($keys));
|
||||
|
||||
return empty($ids) || $this->execCommand('DEL', $ids) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return $this->execCommand('FLUSHDB');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user