msd Backup hinzugefügt
This commit is contained in:
18
msd/vendor/desarrolla2/cache/.formatter.yml
vendored
Normal file
18
msd/vendor/desarrolla2/cache/.formatter.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
use-sort:
|
||||
group:
|
||||
- _main
|
||||
group-type: each
|
||||
sort-type: alph
|
||||
sort-direction: asc
|
||||
|
||||
header: |
|
||||
/*
|
||||
* 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>
|
||||
*/
|
73
msd/vendor/desarrolla2/cache/.github/workflows/php.yml
vendored
Normal file
73
msd/vendor/desarrolla2/cache/.github/workflows/php.yml
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
name: PHP
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- 3306:3306
|
||||
env:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
redis:
|
||||
image: redis:6.0
|
||||
ports:
|
||||
- 6379:6379
|
||||
mongo:
|
||||
image: mongo:4.2-bionic
|
||||
ports:
|
||||
- 27017:27017
|
||||
memcached:
|
||||
image: memcached:1.6
|
||||
ports:
|
||||
- 11211:11211
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- php: 7.2
|
||||
composer: '--prefer-lowest'
|
||||
desc: "Lowest versions"
|
||||
- php: 7.4
|
||||
composer: '--prefer-lowest'
|
||||
desc: "Lowest versions"
|
||||
- php: 7.2
|
||||
- php: 7.3
|
||||
- php: 7.4
|
||||
coverage: '--coverage-clover /tmp/clover.xml'
|
||||
- php: 8.0
|
||||
name: PHP ${{ matrix.php }} ${{ matrix.desc }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: xdebug
|
||||
extensions: apcu, mongodb, memcached
|
||||
ini-values: apc.enable_cli=1,mysqli.default_host=127.0.0.1,mysqli.default_port=3306,mysqli.default_user=root
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer update --prefer-dist --no-progress ${{ matrix.composer }}
|
||||
|
||||
- name: Run PHPUnit
|
||||
run: vendor/bin/phpunit ${{ matrix.coverage }}
|
||||
|
||||
- name: Upload coverage to Scrutinizer
|
||||
if: ${{ matrix.coverage }}
|
||||
run: >
|
||||
wget https://scrutinizer-ci.com/ocular.phar -O "/tmp/ocular.phar" &&
|
||||
php "/tmp/ocular.phar" code-coverage:upload --format=php-clover /tmp/clover.xml
|
9
msd/vendor/desarrolla2/cache/.gitignore
vendored
Normal file
9
msd/vendor/desarrolla2/cache/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/build
|
||||
/composer.lock
|
||||
/tests/config.json
|
||||
/vendor
|
||||
/.idea
|
||||
/TODO.md
|
||||
*~
|
||||
*.swp
|
||||
/.phpunit.result.cache
|
31
msd/vendor/desarrolla2/cache/.scrutinizer.yml
vendored
Normal file
31
msd/vendor/desarrolla2/cache/.scrutinizer.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
#language: php
|
||||
checks:
|
||||
php: true
|
||||
filter:
|
||||
excluded_paths:
|
||||
- tests
|
||||
build:
|
||||
nodes:
|
||||
analysis:
|
||||
environment:
|
||||
php:
|
||||
version: 7.4
|
||||
pecl_extensions:
|
||||
- apcu
|
||||
- mongodb
|
||||
- memcached
|
||||
mysql: false
|
||||
postgresql: false
|
||||
redis: false
|
||||
mongodb: false
|
||||
tests:
|
||||
override:
|
||||
- phpcs-run src
|
||||
-
|
||||
command: vendor/bin/phpstan analyze --error-format=checkstyle | sed '/^\s*$/d' > phpstan-checkstyle.xml
|
||||
analysis:
|
||||
file: phpstan-checkstyle.xml
|
||||
format: 'general-checkstyle'
|
||||
- php-scrutinizer-run
|
||||
tools:
|
||||
external_code_coverage: true
|
19
msd/vendor/desarrolla2/cache/LICENSE
vendored
Normal file
19
msd/vendor/desarrolla2/cache/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2012-2013 Desarrolla2 - http://desarrolla2.com
|
||||
|
||||
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.
|
174
msd/vendor/desarrolla2/cache/README.md
vendored
Normal file
174
msd/vendor/desarrolla2/cache/README.md
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
# Desarolla2 Cache
|
||||
|
||||
A **simple cache** library, implementing the [PSR-16](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md) standard using **immutable** objects.
|
||||
|
||||

|
||||
|
||||
Caching is typically used throughout an applicatiton. Immutability ensure that modifying the cache behaviour in one
|
||||
location doesn't result in unexpected behaviour due to changes in unrelated code.
|
||||
|
||||
_Desarolla2 Cache aims to be the most complete, correct and best performing PSR-16 implementation available._
|
||||
|
||||
[![Latest version][ico-version]][link-packagist]
|
||||
[![Latest version][ico-pre-release]][link-packagist]
|
||||
[![Software License][ico-license]][link-license]
|
||||
[![Build Status][ico-github-actions]][link-github-actions]
|
||||
[![Coverage Status][ico-coverage]][link-scrutinizer]
|
||||
[![Quality Score][ico-code-quality]][link-scrutinizer]
|
||||
[![Total Downloads][ico-downloads]][link-downloads]
|
||||
[![Today Downloads][ico-today-downloads]][link-downloads]
|
||||
[![Gitter][ico-gitter]][link-gitter]
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
composer require desarrolla2/cache
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\Memory as Cache;
|
||||
|
||||
$cache = new Cache();
|
||||
|
||||
$value = $cache->get('key');
|
||||
|
||||
if (!isset($value)) {
|
||||
$value = do_something();
|
||||
$cache->set('key', $value, 3600);
|
||||
}
|
||||
|
||||
echo $value;
|
||||
```
|
||||
|
||||
## Adapters
|
||||
|
||||
* [Apcu](docs/implementations/apcu.md)
|
||||
* [File](docs/implementations/file.md)
|
||||
* [Memcached](docs/implementations/memcached.md)
|
||||
* [Memory](docs/implementations/memory.md)
|
||||
* [MongoDB](docs/implementations/mongodb.md)
|
||||
* [Mysqli](docs/implementations/mysqli.md)
|
||||
* [NotCache](docs/implementations/notcache.md)
|
||||
* [PhpFile](docs/implementations/phpfile.md)
|
||||
* [Predis](docs/implementations/predis.md)
|
||||
|
||||
The following implementation allows you to combine cache adapters.
|
||||
|
||||
* [Chain](docs/implementations/chain.md)
|
||||
|
||||
[Other implementations][todo-implementations] are planned. Please vote or
|
||||
provide a PR to speed up the process of adding the to this library.
|
||||
|
||||
[todo-implementations]: https://github.com/desarrolla2/Cache/issues?q=is%3Aissue+is%3Aopen+label%3Aadapter
|
||||
|
||||
### Options
|
||||
|
||||
You can set options for cache using the `withOption` or `withOptions` method.
|
||||
Note that all cache objects are immutable, setting an option creates a new
|
||||
object.
|
||||
|
||||
#### TTL
|
||||
|
||||
All cache implementations support the `ttl` option. This sets the default
|
||||
time (in seconds) that cache will survive. It defaults to one hour (3600
|
||||
seconds).
|
||||
|
||||
Setting the TTL to 0 or a negative number, means the cache should live forever.
|
||||
|
||||
## Methods
|
||||
|
||||
Each cache implementation has the following `Psr\SimpleCache\CacheInterface`
|
||||
methods:
|
||||
|
||||
##### `get(string $key [, mixed $default])`
|
||||
Retrieve the value corresponding to a provided key
|
||||
|
||||
##### `has(string $key)`
|
||||
Retrieve the if value corresponding to a provided key exist
|
||||
|
||||
##### `set(string $key, mixed $value [, int $ttl])`
|
||||
Add a value to the cache under a unique key
|
||||
|
||||
##### `delete(string $key)`
|
||||
Delete a value from the cache
|
||||
|
||||
##### `clear()`
|
||||
Clear all cache
|
||||
|
||||
##### `getMultiple(array $keys)`
|
||||
Obtains multiple cache items by their unique keys
|
||||
|
||||
##### `setMultiple(array $values [, int $ttl])`
|
||||
Persists a set of key => value pairs in the cache
|
||||
|
||||
##### `deleteMultiple(array $keys)`
|
||||
Deletes multiple cache items in a single operation
|
||||
|
||||
.
|
||||
|
||||
The `Desarrolla2\Cache\CacheInterface` also has the following methods:
|
||||
|
||||
##### `withOption(string $key, string $value)`
|
||||
Set option for implementation. Creates a new instance.
|
||||
|
||||
##### `withOptions(array $options)`
|
||||
Set multiple options for implementation. Creates a new instance.
|
||||
|
||||
##### `getOption(string $key)`
|
||||
Get option for implementation.
|
||||
|
||||
|
||||
## Packers
|
||||
|
||||
Cache objects typically hold a `Desarrolla2\Cache\Packer\PackerInterface`
|
||||
object. By default, packing is done using `serialize` and `unserialize`.
|
||||
|
||||
Available packers are:
|
||||
|
||||
* `SerializePacker` using `serialize` and `unserialize`
|
||||
* `JsonPacker` using `json_encode` and `json_decode`
|
||||
* `NopPacker` does no packing
|
||||
* `MongoDBBinaryPacker` using `serialize` and `unserialize` to store as [BSON Binary](http://php.net/manual/en/class.mongodb-bson-binary.php)
|
||||
|
||||
#### PSR-16 incompatible packers
|
||||
|
||||
The `JsonPacker` does not fully comply with PSR-16, as packing and
|
||||
unpacking an object will probably not result in an object of the same class.
|
||||
|
||||
The `NopPacker` is intended when caching string data only (like HTML output) or
|
||||
if the caching backend supports structured data. Using it when storing objects
|
||||
will might give unexpected results.
|
||||
|
||||
## Contributors
|
||||
|
||||
[](https://github.com/desarrolla2)
|
||||
Twitter: [@desarrolla2](https://twitter.com/desarrolla2)\
|
||||
[](https://github.com/jasny)
|
||||
Twitter: [@ArnoldDaniels](https://twitter.com/ArnoldDaniels)
|
||||
|
||||
[ico-version]: https://img.shields.io/packagist/v/desarrolla2/Cache.svg?style=flat-square
|
||||
[ico-pre-release]: https://img.shields.io/packagist/vpre/desarrolla2/Cache.svg?style=flat-square
|
||||
[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
|
||||
[ico-travis]: https://img.shields.io/travis/desarrolla2/Cache/master.svg?style=flat-square
|
||||
[ico-coveralls]: https://img.shields.io/coveralls/desarrolla2/Cache/master.svg?style=flat-square
|
||||
[ico-code-quality]: https://img.shields.io/scrutinizer/g/desarrolla2/cache.svg?style=flat-square
|
||||
[ico-coverage]: https://scrutinizer-ci.com/g/desarrolla2/Cache/badges/coverage.png?b=master
|
||||
[ico-sensiolabs]: https://img.shields.io/sensiolabs/i/5f139261-1ac1-4559-846a-723e09319a88.svg?style=flat-square
|
||||
[ico-downloads]: https://img.shields.io/packagist/dt/desarrolla2/cache.svg?style=flat-square
|
||||
[ico-today-downloads]: https://img.shields.io/packagist/dd/desarrolla2/cache.svg?style=flat-square
|
||||
[ico-gitter]: https://img.shields.io/badge/GITTER-JOIN%20CHAT%20%E2%86%92-brightgreen.svg?style=flat-square
|
||||
[ico-github-actions]: https://github.com/desarrolla2/Cache/workflows/PHP/badge.svg
|
||||
|
||||
[link-packagist]: https://packagist.org/packages/desarrolla2/cache
|
||||
[link-license]: http://hassankhan.mit-license.org
|
||||
[link-travis]: https://travis-ci.org/desarrolla2/Cache
|
||||
[link-github-actions]: https://github.com/desarrolla2/Cache/actions
|
||||
[link-coveralls]: https://coveralls.io/github/desarrolla2/Cache
|
||||
[link-scrutinizer]: https://scrutinizer-ci.com/g/desarrolla2/cache
|
||||
[link-sensiolabs]: https://insight.sensiolabs.com/projects/5f139261-1ac1-4559-846a-723e09319a88
|
||||
[link-downloads]: https://packagist.org/packages/desarrolla2/cache
|
||||
[link-gitter]: https://gitter.im/desarrolla2/Cache?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
100
msd/vendor/desarrolla2/cache/build.xml
vendored
Normal file
100
msd/vendor/desarrolla2/cache/build.xml
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project name="Cache" default="build">
|
||||
|
||||
<target name="install" depends="composer"
|
||||
description="Prepare for execution"/>
|
||||
|
||||
<target name="build" depends="install, init"
|
||||
description="Run all tests and build everything"/>
|
||||
|
||||
<target name="metrics" depends="build, phpunit, phpdoc, pdepend, phpcs, phpmd"
|
||||
description="Generate Metrics"/>
|
||||
|
||||
<target name="clean"
|
||||
description="Cleanup build artifacts">
|
||||
<delete dir="cache"/>
|
||||
<delete dir="build"/>
|
||||
</target>
|
||||
|
||||
<target name="init" depends="clean"
|
||||
description="Prepare for build">
|
||||
<mkdir dir="cache/htmlpurifier"/>
|
||||
<mkdir dir="build/api"/>
|
||||
<mkdir dir="build/coverage"/>
|
||||
<mkdir dir="build/pdepend"/>
|
||||
<mkdir dir="build/phpcs"/>
|
||||
<mkdir dir="build/phpmd"/>
|
||||
</target>
|
||||
|
||||
<target name="composer"
|
||||
description="Composer install">
|
||||
<exec executable="composer">
|
||||
<arg value="install"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpdoc"
|
||||
description="Generate API documentation using PHPDocumentor">
|
||||
<exec executable="phpdoc">
|
||||
<arg value="-d"/>
|
||||
<arg value="src"/>
|
||||
<arg value="-t"/>
|
||||
<arg value="build/api/"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpunit"
|
||||
description="Run unit tests using PHPUnit">
|
||||
<exec executable="phpunit">
|
||||
<arg value="-c"/>
|
||||
<arg value="phpunit.xml"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="pdepend"
|
||||
description="Generate software metrics charts using PHP_Depend">
|
||||
<exec executable="pdepend">
|
||||
<arg value="--jdepend-chart=build/pdepend/dependencies.svg"/>
|
||||
<arg value="--overview-pyramid=build/pdepend/overview-pyramid.svg"/>
|
||||
<arg value="src"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpcs"
|
||||
description="Generate coding standard metrics using PHPCS">
|
||||
<exec executable="phpcs">
|
||||
<arg value="--standard=PSR2"/>
|
||||
<arg value="--report-full=build/phpcs/full.txt"/>
|
||||
<arg value="--report-summary=build/phpcs/sumary.txt"/>
|
||||
<arg value="src"/>
|
||||
<arg value="tests"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpmd"
|
||||
description="Generate coding metrics for mess code using PHPMD">
|
||||
<exec executable="phpmd">
|
||||
<arg value="src"/>
|
||||
<arg value="text"/>
|
||||
<arg value="codesize,unusedcode,naming,design,controversial"/>
|
||||
<arg value="--reportfile"/>
|
||||
<arg value="build/phpmd/report.txt"/>
|
||||
</exec>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="cs" description="">
|
||||
<parallel>
|
||||
<exec executable="php-cs-fixer">
|
||||
<arg line="fix src"/>
|
||||
</exec>
|
||||
<exec executable="php-formatter">
|
||||
<arg line="formatter:header:fix src"/>
|
||||
</exec>
|
||||
<exec executable="php-formatter">
|
||||
<arg line="formatter:use:sort src"/>
|
||||
</exec>
|
||||
</parallel>
|
||||
</target>
|
||||
</project>
|
67
msd/vendor/desarrolla2/cache/composer.json
vendored
Normal file
67
msd/vendor/desarrolla2/cache/composer.json
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "desarrolla2/cache",
|
||||
"description": "Provides an cache interface for several adapters Apc, Apcu, File, Mongo, Memcache, Memcached, Mysql, Mongo, Redis is supported.",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"simple-cache",
|
||||
"psr-16",
|
||||
"apc",
|
||||
"apcu",
|
||||
"file",
|
||||
"memcached",
|
||||
"memcache",
|
||||
"mysql",
|
||||
"mongo",
|
||||
"redis"
|
||||
],
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/desarrolla2/Cache/",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Daniel González",
|
||||
"homepage": "http://desarrolla2.com/"
|
||||
},
|
||||
{
|
||||
"name": "Arnold Daniels",
|
||||
"homepage": "https://jasny.net/"
|
||||
}
|
||||
],
|
||||
"provide": {
|
||||
"psr/simple-cache-implementation": "1.0"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-apcu": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mysqli": "*",
|
||||
"ext-memcached": "*",
|
||||
"predis/predis": "~1.0.0",
|
||||
"mongodb/mongodb": "^1.3",
|
||||
"cache/integration-tests": "dev-master",
|
||||
"phpunit/phpunit": "^8.3 || ^9.0",
|
||||
"phpstan/phpstan": "^0.12.29",
|
||||
"symfony/phpunit-bridge": "^5.2",
|
||||
"mikey179/vfsstream": "v1.6.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Desarrolla2\\Cache\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Desarrolla2\\Test\\Cache\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": [
|
||||
"phpstan analyse",
|
||||
"phpunit --colors=always",
|
||||
"phpcs -p src"
|
||||
]
|
||||
}
|
||||
}
|
25
msd/vendor/desarrolla2/cache/docs/implementations/apcu.md
vendored
Normal file
25
msd/vendor/desarrolla2/cache/docs/implementations/apcu.md
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# Apcu
|
||||
|
||||
Use [APCu cache](http://php.net/manual/en/book.apcu.php) to cache to shared
|
||||
memory.
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\Apcu as ApcuCache;
|
||||
|
||||
$cache = new ApcuCache();
|
||||
```
|
||||
|
||||
_Note: by default APCu uses the time at the beginning of a request for ttl. In
|
||||
some cases, like with a long running script, this can be a problem. You can
|
||||
change this behaviour `ini_set('apc.use_request_time', false)`._
|
||||
|
||||
### Options
|
||||
|
||||
| name | type | default | |
|
||||
| --------- | ---- | ------- | ------------------------------------- |
|
||||
| ttl | int | null | Maximum time to live in seconds |
|
||||
| prefix | string | "" | Key prefix |
|
||||
|
||||
### Packer
|
||||
|
||||
By default the [`NopPacker`](../packers/nop.md) is used.
|
37
msd/vendor/desarrolla2/cache/docs/implementations/chain.md
vendored
Normal file
37
msd/vendor/desarrolla2/cache/docs/implementations/chain.md
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
# Chain
|
||||
|
||||
The Cache chain allows you to use multiple implementations to store cache. For
|
||||
instance, you can use both fast volatile (in-memory) storage and slower
|
||||
non-volatile (disk) storage. Alternatively you can have a local storage
|
||||
as well as a shared storage service.
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\Chain as CacheChain;
|
||||
use Desarrolla2\Cache\Memory as MemoryCache;
|
||||
use Desarrolla2\Cache\Predis as PredisCache;
|
||||
|
||||
$cache = new CacheChain([
|
||||
(new MemoryCache())->withOption('ttl', 3600),
|
||||
(new PredisCache())->withOption('ttl', 10800)
|
||||
]);
|
||||
```
|
||||
|
||||
The Chain cache implementation doesn't use any option. It uses the `Nop` packer
|
||||
by default.
|
||||
|
||||
Typically it's useful to specify a maximum `ttl` for each implementation. This
|
||||
means that the volatile memory only holds items that are used often.
|
||||
|
||||
The following actions propogate to all cache adapters in the chain
|
||||
|
||||
* `set`
|
||||
* `setMultiple`
|
||||
* `delete`
|
||||
* `deleteMultiple`
|
||||
* `clear`
|
||||
|
||||
For the following actions all nodes are tried in sequence
|
||||
|
||||
* `has`
|
||||
* `get`
|
||||
* `getMultiple`
|
82
msd/vendor/desarrolla2/cache/docs/implementations/file.md
vendored
Normal file
82
msd/vendor/desarrolla2/cache/docs/implementations/file.md
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
# File
|
||||
|
||||
Save the cache as file to on the filesystem.
|
||||
|
||||
You must pass a cache directory to the constructor.
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\File as FileCache;
|
||||
|
||||
$cache = new FileCache(sys_get_temp_dir() . '/cache');
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| name | type | default | |
|
||||
| ------------ | --------------------------------- | -------------- | ------------------------------------- |
|
||||
| ttl | int | null | Maximum time to live in seconds |
|
||||
| ttl-strategy | string ('embed', 'file', 'mtime') | "embed" | Strategy to store the TTL |
|
||||
| prefix | string | "" | Key prefix |
|
||||
| filename | string or callable | "%s.php.cache" | Filename as sprintf format |
|
||||
|
||||
#### TTL strategy option
|
||||
|
||||
The ttl strategy determines how the TTL is stored. Typical filesystems don't
|
||||
allow custom file properties, so we'll have to use one of these strategies:
|
||||
|
||||
| strategy | |
|
||||
| -------- | ----------------------------------------------- |
|
||||
| embed | Embed the TTL as first line of the file |
|
||||
| file | Create a TTL file in addition to the cache file |
|
||||
| mtime | Use [mtime][] + max ttl |
|
||||
|
||||
The 'mtime' strategy is not PSR-16 compliant, as the TTL passed to the `set()`
|
||||
method is ignored. Only the `ttl` option for is used on `get()` and `has()`.
|
||||
|
||||
[mtime]: https://www.unixtutorial.org/2008/04/atime-ctime-mtime-in-unix-filesystems/
|
||||
|
||||
#### Filename option
|
||||
|
||||
The `filename` will be parsed using `sprintf` where '%s' is substituted with
|
||||
the key. The default extension is automatically determined based on the
|
||||
packer.
|
||||
|
||||
Instead of a string, `filename` may also be set to a callable, like a callable
|
||||
object or closure. In that case the callable will be called to create a
|
||||
filename as
|
||||
|
||||
$filename = $callable($key);
|
||||
|
||||
##### BasicFilename
|
||||
|
||||
The library comes with invokable object as callable for the filename. The
|
||||
`BasicFilename` object works as described above.
|
||||
|
||||
##### TrieFilename
|
||||
|
||||
The `TrieFilename` object will create a prefix tree directory structure. This
|
||||
is useful where a lot of cache files would cause to many files in a directory.
|
||||
|
||||
Specify the `sprintf` format and the directory level to the constructor when
|
||||
creating a `TrieFilename` object.
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\File as FileCache;
|
||||
use Desarrolla2\Cache\File\TrieFilename;
|
||||
|
||||
$callback = new TrieFilename('%s.php.cache', 2);
|
||||
|
||||
$cache = (new FileCache(sys_get_temp_dir() . '/cache'))
|
||||
->withOption('filename', $callback);
|
||||
```
|
||||
|
||||
In this case, adding an item with key `foobar` would be create a file at
|
||||
|
||||
/tmp/cache/f/fo/foobar.php.cache
|
||||
|
||||
### Packer
|
||||
|
||||
By default the [`SerializePacker`](../packers/serialize.md) is used. The
|
||||
[`NopPacker`](../packers/nop.md) can be used if the values are strings.
|
||||
Other packers, like the [`JsonPacker`](../packers/json.md) are also
|
||||
useful with file cache.
|
28
msd/vendor/desarrolla2/cache/docs/implementations/memcached.md
vendored
Normal file
28
msd/vendor/desarrolla2/cache/docs/implementations/memcached.md
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
# Memcached
|
||||
|
||||
Store cache to [Memcached](https://memcached.org/). Memcached is a high
|
||||
performance distributed caching system.
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\Memcached as MemcachedCache;
|
||||
use Memcached;
|
||||
|
||||
$server = new Memcached();
|
||||
// configure it here
|
||||
|
||||
$cache = new MemcachedCache($server);
|
||||
```
|
||||
|
||||
This implementation uses the [memcached](https://php.net/memcached) php
|
||||
extension. The (alternative) memcache extension is not supported.
|
||||
|
||||
### Options
|
||||
|
||||
| name | type | default | |
|
||||
| --------- | ---- | ------- | ------------------------------------- |
|
||||
| ttl | int | null | Maximum time to live in seconds |
|
||||
| prefix | string | "" | Key prefix |
|
||||
|
||||
### Packer
|
||||
|
||||
By default the [`NopPacker`](../packers/nop.md) is used.
|
23
msd/vendor/desarrolla2/cache/docs/implementations/memory.md
vendored
Normal file
23
msd/vendor/desarrolla2/cache/docs/implementations/memory.md
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
# Memory
|
||||
|
||||
Store the cache in process memory _(in other words in an array)_. Cache Memory
|
||||
is removed when the PHP process exist. Also it is not shared between different
|
||||
processes.
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\Memory as MemoryCache;
|
||||
|
||||
$cache = new MemoryCache();
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| name | type | default | |
|
||||
| --------- | ---- | ------- | ------------------------------------- |
|
||||
| ttl | int | null | Maximum time to live in seconds |
|
||||
| limit | int | null | Maximum items in cache |
|
||||
| prefix | string | "" | Key prefix |
|
||||
|
||||
### Packer
|
||||
|
||||
By default the [`SerializePacker`](../packers/serialize.md) is used.
|
45
msd/vendor/desarrolla2/cache/docs/implementations/mongodb.md
vendored
Normal file
45
msd/vendor/desarrolla2/cache/docs/implementations/mongodb.md
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
# Mongo
|
||||
|
||||
Use it to store the cache in a Mongo database. Requires the mongodb extension
|
||||
and the [mongodb/mongodb](https://github.com/mongodb/mongo-php-library)
|
||||
library.
|
||||
|
||||
You must pass a `MongoDB\Collection` object to the cache constructor.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Desarrolla2\Cache\Mongo as MongoCache;
|
||||
use MongoDB\Client;
|
||||
|
||||
$client = new Client('mongodb://localhost:27017');
|
||||
$database = $client->selectDatabase('mycache');
|
||||
$collection = $database->selectCollection('cache');
|
||||
|
||||
$cache = new MongoCache($collection);
|
||||
```
|
||||
|
||||
MonoDB will always automatically create the database and collection if needed.
|
||||
|
||||
### Options
|
||||
|
||||
| name | type | default | |
|
||||
| --------- | ---- | ------- | ------------------------------------- |
|
||||
| initialize | bool | true | Enable auto-initialize |
|
||||
| ttl | int | null | Maximum time to live in seconds |
|
||||
| prefix | string | "" | Key prefix |
|
||||
|
||||
#### Initialize option
|
||||
|
||||
If `initialize` is enabled, the cache implementation will automatically create
|
||||
a [ttl index](https://docs.mongodb.com/manual/core/index-ttl/). In production
|
||||
it's better to disable auto-initialization and create the ttl index explicitly
|
||||
when setting up the database. This prevents a `createIndex()` call on each
|
||||
request.
|
||||
|
||||
### Packer
|
||||
|
||||
By default the [`MongoDBBinaryPacker`](../packers/mongodbbinary.md) is used. It
|
||||
serializes the data and stores it in a [Binary BSON variable](http://php.net/manual/en/class.mongodb-bson-binary.php).
|
||||
If the data is a UTF-8 string of simple array or stdClass object, it may be
|
||||
useful to use the [`NopPacker`](../packers/nop.md) instead.
|
47
msd/vendor/desarrolla2/cache/docs/implementations/mysqli.md
vendored
Normal file
47
msd/vendor/desarrolla2/cache/docs/implementations/mysqli.md
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
# Mysqli
|
||||
|
||||
Cache to a [MySQL database](https://www.mysql.com/) using the
|
||||
[mysqli](http://php.net/manual/en/book.mysqli.php) PHP extension.
|
||||
|
||||
You must pass a `mysqli` connection object to the constructor.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Desarrolla2\Cache\Mysqli as MysqliCache;
|
||||
|
||||
$db = new mysqli('localhost');
|
||||
$cache = new MysqliCache($db);
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| name | type | default | |
|
||||
| --------- | ---- | ------- | ------------------------------------- |
|
||||
| initialize | bool | true | Enable auto-initialize |
|
||||
| ttl | int | null | Maximum time to live in seconds |
|
||||
| prefix | string | "" | Key prefix |
|
||||
|
||||
#### Initialize option
|
||||
|
||||
If `initialize` is enabled, the cache implementation will automatically create
|
||||
a [scheduled event](https://dev.mysql.com/doc/refman/5.7/en/event-scheduler.html).
|
||||
|
||||
```
|
||||
DELIMITER ;;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cache` (`key` VARCHAR(255), `value` TEXT, `ttl` INT UNSIGNED, PRIMARY KEY (`key`));;
|
||||
|
||||
CREATE EVENT `apply_ttl_cache` ON SCHEDULE 1 HOUR
|
||||
DO BEGIN
|
||||
DELETE FROM `cache` WHERE `ttl` < NOW();
|
||||
END;;
|
||||
```
|
||||
|
||||
In production it's better to disable auto-initialization and create the event
|
||||
explicitly when setting up the database. This prevents a `CREATE TABLE` and
|
||||
`CREATE EVENT` query on each request.
|
||||
|
||||
### Packer
|
||||
|
||||
By default the [`SerializePacker`](../packers/serialize.md) is used.
|
13
msd/vendor/desarrolla2/cache/docs/implementations/notcache.md
vendored
Normal file
13
msd/vendor/desarrolla2/cache/docs/implementations/notcache.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# NotCache
|
||||
|
||||
A [Null object](https://sourcemaking.com/design_patterns/null_object) that
|
||||
correctly implements the PSR-16 interface, but does not actually cache
|
||||
anything.
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\NotCache;
|
||||
|
||||
$cache = new NotCache();
|
||||
```
|
||||
|
||||
It doesn't use any options or packers.
|
74
msd/vendor/desarrolla2/cache/docs/implementations/phpfile.md
vendored
Normal file
74
msd/vendor/desarrolla2/cache/docs/implementations/phpfile.md
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
# PhpFile
|
||||
|
||||
Save the cache as PHP script to on the filesystem using
|
||||
[`var_export`](http://php.net/manual/en/function.var-export.php) when storing
|
||||
cache and [`include`](http://php.net/manual/en/function.include.php) when
|
||||
loading cache.
|
||||
|
||||
The implementation leverages the PHP engine’s in-memory file caching (opcache)
|
||||
to cache application data in addition to code. This method is particularly fast
|
||||
in PHP7.2+ due to opcode cache optimizations.
|
||||
|
||||
PHP file caching should primarily be used for arrays and objects. There is no
|
||||
performance benefit over APCu for storing strings.
|
||||
|
||||
[read more][]
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\PhpFile as PhpFileCache;
|
||||
|
||||
$cache = new PhpFileCache();
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| name | type | default | |
|
||||
| --------- | ------------------ | -------------- | ------------------------------------- |
|
||||
| ttl | int | null | Maximum time to live in seconds |
|
||||
| prefix | string | "" | Key prefix |
|
||||
| filename | string or callable | "%s.php" | Filename as sprintf format |
|
||||
|
||||
#### Filename option
|
||||
|
||||
The `filename` will be parsed using `sprintf` where '%s' is substituted with
|
||||
the key.
|
||||
|
||||
Instead of a string, `filename` may also be set to a callable, like a callable
|
||||
object or closure. In that case the callable will be called to create a
|
||||
filename as
|
||||
|
||||
$filename = $callable($key);
|
||||
|
||||
##### BasicFilename
|
||||
|
||||
The library comes with invokable object as callable for the filename. The
|
||||
`BasicFilename` object works as described above.
|
||||
|
||||
##### TrieFilename
|
||||
|
||||
The `TrieFilename` object will create a prefix tree directory structure. This
|
||||
is useful where a lot of cache files would cause to many files in a directory.
|
||||
|
||||
Specify the `sprintf` format and the directory level to the constructor when
|
||||
creating a `TrieFilename` object.
|
||||
|
||||
``` php
|
||||
use Desarrolla2\Cache\File as FileCache;
|
||||
use Desarrolla2\Cache\File\TrieFilename;
|
||||
|
||||
$callback = new TrieFilename('%s.php', 2);
|
||||
|
||||
$cache = (new FileCache(sys_get_temp_dir() . '/cache'))
|
||||
->withOption('filename', $callback);
|
||||
```
|
||||
|
||||
In this case, adding an item with key `foobar` would be create a file at
|
||||
|
||||
/tmp/cache/f/fo/foobar.php
|
||||
|
||||
### Packer
|
||||
|
||||
By default the [`NopPacker`](../packers/nop.md) is used. Other packers should
|
||||
not be used.
|
||||
|
||||
[read more]: https://medium.com/@dylanwenzlau/500x-faster-caching-than-redis-memcache-apc-in-php-hhvm-dcd26e8447ad
|
31
msd/vendor/desarrolla2/cache/docs/implementations/predis.md
vendored
Normal file
31
msd/vendor/desarrolla2/cache/docs/implementations/predis.md
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
# Predis
|
||||
|
||||
Cache using a [redis server](https://redis.io/). Redis is an open source,
|
||||
in-memory data structure store, used as a database, cache and message broker.
|
||||
|
||||
You must provide a `Predis\Client` object to the constructor.
|
||||
|
||||
```php
|
||||
use Desarrolla2\Cache\Predis as PredisCache;
|
||||
use Predis\Client as PredisClient;
|
||||
|
||||
$client = new PredisClient('tcp://localhost:6379');
|
||||
$cache = new PredisCache($client);
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
Requires the [`predis`](https://github.com/nrk/predis/wiki) library.
|
||||
|
||||
composer require predis/predis
|
||||
|
||||
### Options
|
||||
|
||||
| name | type | default | |
|
||||
| --------- | ---- | ------- | ------------------------------------- |
|
||||
| ttl | int | null | Maximum time to live in seconds |
|
||||
| prefix | string | "" | Key prefix |
|
||||
|
||||
### Packer
|
||||
|
||||
By default the [`SerializePacker`](../packers/serialize.md) is used.
|
40
msd/vendor/desarrolla2/cache/docs/performance.md
vendored
Normal file
40
msd/vendor/desarrolla2/cache/docs/performance.md
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
# Performance test
|
||||
|
||||
Here are my performance tests, you can view the results ordered from faster to slower.
|
||||
|
||||
| Adapter | 10.000 set | 10.000 has | 10.000 get |
|
||||
| :-------------- | -----------: | -----------: | ---------: |
|
||||
| NoCache | 0.0637 | 0.0482 | 0.0488 |
|
||||
| Apcu | 0.0961 | 0.0556 | 0.0770 |
|
||||
| File | 0.6881 | 0.3426 | 0.3107 |
|
||||
| Mongo | 13.8144 | 30.0203 | 24.4214 |
|
||||
|
||||
|
||||
## how i run the test?
|
||||
|
||||
The test its the same for all Adapters and look like this.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
$timer = new Timer();
|
||||
for ($i = 1; $i <= 10000; $i++) {
|
||||
$cache->set(md5($i), md5($i), 3600);
|
||||
}
|
||||
$timer->mark('10.000 set');
|
||||
for ($i = 1; $i <= 10000; $i++) {
|
||||
$cache->has(md5($i));
|
||||
}
|
||||
$timer->mark('10.000 has');
|
||||
for ($i = 1; $i <= 10000; $i++) {
|
||||
$cache->get(md5($i));
|
||||
}
|
||||
$timer->mark('10.000 get');
|
||||
|
||||
```
|
||||
|
||||
if you want run the tests them execute.
|
||||
|
||||
``` sh
|
||||
php test/performance/AdapterName.php
|
||||
```
|
8
msd/vendor/desarrolla2/cache/phpcs.xml
vendored
Normal file
8
msd/vendor/desarrolla2/cache/phpcs.xml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="PSR">
|
||||
<!-- Include the whole PSR-1 standard -->
|
||||
<rule ref="PSR1"/>
|
||||
<!-- Include the whole PSR-2 standard -->
|
||||
<rule ref="PSR2"/>
|
||||
</ruleset>
|
||||
|
8
msd/vendor/desarrolla2/cache/phpstan.neon
vendored
Normal file
8
msd/vendor/desarrolla2/cache/phpstan.neon
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
parameters:
|
||||
level: 3
|
||||
paths:
|
||||
- src
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
ignoreErrors:
|
||||
- /^Variable property access/
|
||||
|
39
msd/vendor/desarrolla2/cache/phpunit.xml.dist
vendored
Normal file
39
msd/vendor/desarrolla2/cache/phpunit.xml.dist
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit
|
||||
bootstrap="./vendor/autoload.php"
|
||||
convertWarningsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertErrorsToExceptions="true"
|
||||
backupStaticAttributes="false"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Desarrolla2 Cache test suite">
|
||||
<directory suffix="Test.php">./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<php>
|
||||
<!--ini name="mysqli.default_host" value="localhost" /-->
|
||||
<!--ini name="mysqli.default_user" value="root" /-->
|
||||
<!--ini name="mysqli.default_pw" value=""/-->
|
||||
<const name="CACHE_TESTS_MYSQLI_DATABASE" value="cache_tests" />
|
||||
|
||||
<const name="CACHE_TESTS_MONGO_DSN" value="mongodb://localhost:27017" />
|
||||
<const name="CACHE_TESTS_MONGO_DATABASE" value="cache_tests" />
|
||||
|
||||
<const name="CACHE_TESTS_MEMCACHED_SERVER" value="localhost:11211" />
|
||||
|
||||
<const name="CACHE_TESTS_PREDIS_DSN" value="tcp://localhost:6379" />
|
||||
</php>
|
||||
</phpunit>
|
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');
|
||||
}
|
||||
}
|
93
msd/vendor/desarrolla2/cache/tests/AbstractCacheTest.php
vendored
Normal file
93
msd/vendor/desarrolla2/cache/tests/AbstractCacheTest.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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Cache\IntegrationTests\SimpleCacheTest;
|
||||
use Desarrolla2\Cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* AbstractCacheTest
|
||||
*/
|
||||
abstract class AbstractCacheTest extends SimpleCacheTest
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function dataProviderForOptions()
|
||||
{
|
||||
return [
|
||||
['ttl', 100],
|
||||
['prefix', 'test']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderForOptions
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function testWithOption($key, $value)
|
||||
{
|
||||
$cache = $this->cache->withOption($key, $value);
|
||||
$this->assertEquals($value, $cache->getOption($key));
|
||||
|
||||
// Check immutability
|
||||
$this->assertNotSame($this->cache, $cache);
|
||||
$this->assertNotEquals($value, $this->cache->getOption($key));
|
||||
}
|
||||
|
||||
public function testWithOptions()
|
||||
{
|
||||
$data = $this->dataProviderForOptions();
|
||||
$options = array_combine(array_column($data, 0), array_column($data, 1));
|
||||
|
||||
$cache = $this->cache->withOptions($options);
|
||||
|
||||
foreach ($options as $key => $value) {
|
||||
$this->assertEquals($value, $cache->getOption($key));
|
||||
}
|
||||
|
||||
// Check immutability
|
||||
$this->assertNotSame($this->cache, $cache);
|
||||
|
||||
foreach ($options as $key => $value) {
|
||||
$this->assertNotEquals($value, $this->cache->getOption($key));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function dataProviderForOptionsException()
|
||||
{
|
||||
return [
|
||||
['ttl', 0, InvalidArgumentException::class],
|
||||
['foo', 'bar', InvalidArgumentException::class]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderForOptionsException
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param string $expectedException
|
||||
*/
|
||||
public function testWithOptionException($key, $value, $expectedException)
|
||||
{
|
||||
$this->expectException($expectedException);
|
||||
$this->createSimpleCache()->withOption($key, $value);
|
||||
}
|
||||
}
|
44
msd/vendor/desarrolla2/cache/tests/ApcuCacheTest.php
vendored
Normal file
44
msd/vendor/desarrolla2/cache/tests/ApcuCacheTest.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Apcu as ApcuCache;
|
||||
|
||||
/**
|
||||
* ApcuCacheTest
|
||||
*/
|
||||
class ApcuCacheTest extends AbstractCacheTest
|
||||
{
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
// Required to check the TTL for new entries
|
||||
ini_set('apc.use_request_time', false);
|
||||
}
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
if (!extension_loaded('apcu')) {
|
||||
$this->markTestSkipped(
|
||||
'The APCu extension is not available.'
|
||||
);
|
||||
}
|
||||
if (!ini_get('apc.enable_cli')) {
|
||||
$this->markTestSkipped(
|
||||
'You need to enable apc.enable_cli'
|
||||
);
|
||||
}
|
||||
|
||||
return new ApcuCache();
|
||||
}
|
||||
}
|
216
msd/vendor/desarrolla2/cache/tests/ChainTest.php
vendored
Normal file
216
msd/vendor/desarrolla2/cache/tests/ChainTest.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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Chain as CacheChain;
|
||||
use Desarrolla2\Cache\Memory as MemoryCache;
|
||||
|
||||
/**
|
||||
* ChainTest
|
||||
*/
|
||||
class ChainTest extends AbstractCacheTest
|
||||
{
|
||||
public function createSimpleCache()
|
||||
{
|
||||
$adapters = [new MemoryCache()]; // For the general PSR-16 tests, we don't need more than 1 adapter
|
||||
|
||||
return new CacheChain($adapters);
|
||||
}
|
||||
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
// No need to clear cache, as the adapters don't persist between tests.
|
||||
}
|
||||
|
||||
|
||||
public function testChainSet()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('set')->with("foo", "bar", 300);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('set')->with("foo", "bar", 300);
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$cache->set("foo", "bar", 300);
|
||||
}
|
||||
|
||||
public function testChainSetMultiple()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('setMultiple')->with(["foo" => 1, "bar" => 2], 300);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('setMultiple')->with(["foo" => 1, "bar" => 2], 300);
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$cache->setMultiple(["foo" => 1, "bar" => 2], 300);
|
||||
}
|
||||
|
||||
|
||||
public function testChainGetFirst()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('get')->with("foo")->willReturn("bar");
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->never())->method('get');
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$this->assertEquals("bar", $cache->get("foo", 42));
|
||||
}
|
||||
|
||||
public function testChainGetSecond()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('get')->with("foo")->willReturn(null);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('get')->with("foo")->willReturn("car");
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$this->assertEquals("car", $cache->get("foo", 42));
|
||||
}
|
||||
|
||||
public function testChainGetNone()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('get')->with("foo")->willReturn(null);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('get')->with("foo")->willReturn(null);
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$this->assertEquals(42, $cache->get("foo", 42));
|
||||
}
|
||||
|
||||
|
||||
public function testChainGetMultipleFirst()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('getMultiple')->with(["foo", "bar"])
|
||||
->willReturn(["foo" => 1, "bar" => 2]);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->never())->method('getMultiple');
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$this->assertEquals(["foo" => 1, "bar" => 2], $cache->getMultiple(["foo", "bar"]));
|
||||
}
|
||||
|
||||
public function testChainGetMultipleMixed()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('getMultiple')
|
||||
->with($this->equalTo(["foo", "bar", "wux", "lot"]))
|
||||
->willReturn(["foo" => null, "bar" => 2, "wux" => null, "lot" => null]);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('getMultiple')
|
||||
->with($this->equalTo(["foo", "wux", "lot"]))
|
||||
->willReturn(["foo" => 11, "wux" => 15, "lot" => null]);
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$expected = ["foo" => 11, "bar" => 2, "wux" => 15, "lot" => 42];
|
||||
$this->assertEquals($expected, $cache->getMultiple(["foo", "bar", "wux", "lot"], 42));
|
||||
}
|
||||
|
||||
|
||||
public function testChainHasFirst()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('has')->with("foo")->willReturn(true);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->never())->method('has');
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$this->assertTrue($cache->has("foo"));
|
||||
}
|
||||
|
||||
public function testChainHasSecond()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('has')->with("foo")->willReturn(false);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('has')->with("foo")->willReturn(true);
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$this->assertTrue($cache->has("foo"));
|
||||
}
|
||||
|
||||
public function testChainHasNone()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('has')->with("foo")->willReturn(false);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('has')->with("foo")->willReturn(false);
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$this->assertFalse($cache->has("foo"));
|
||||
}
|
||||
|
||||
|
||||
public function testChainDelete()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('delete')->with("foo");
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('delete')->with("foo");
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$cache->delete("foo");
|
||||
}
|
||||
|
||||
public function testChainDeleteMultiple()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('deleteMultiple')->with(["foo", "bar"]);
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('deleteMultiple')->with(["foo", "bar"]);
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$cache->deleteMultiple(["foo", "bar"]);
|
||||
}
|
||||
|
||||
public function testChainClear()
|
||||
{
|
||||
$adapter1 = $this->createMock(MemoryCache::class);
|
||||
$adapter1->expects($this->once())->method('clear');
|
||||
|
||||
$adapter2 = $this->createMock(MemoryCache::class);
|
||||
$adapter2->expects($this->once())->method('clear');
|
||||
|
||||
$cache = new CacheChain([$adapter1, $adapter2]);
|
||||
|
||||
$cache->clear();
|
||||
}
|
||||
}
|
40
msd/vendor/desarrolla2/cache/tests/FileTest.php
vendored
Normal file
40
msd/vendor/desarrolla2/cache/tests/FileTest.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\File as FileCache;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
use org\bovigo\vfs\vfsStreamDirectory;
|
||||
|
||||
/**
|
||||
* FileTest
|
||||
*/
|
||||
class FileTest extends AbstractCacheTest
|
||||
{
|
||||
/**
|
||||
* @var vfsStreamDirectory
|
||||
*/
|
||||
private $root;
|
||||
|
||||
protected $skippedTests = [
|
||||
'testBasicUsageWithLongKey' => 'Only support keys up to 64 bytes'
|
||||
];
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
$this->root = vfsStream::setup('cache');
|
||||
|
||||
return new FileCache(vfsStream::url('cache'));
|
||||
}
|
||||
}
|
43
msd/vendor/desarrolla2/cache/tests/FileTrieTest.php
vendored
Normal file
43
msd/vendor/desarrolla2/cache/tests/FileTrieTest.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?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\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\File as FileCache;
|
||||
use Desarrolla2\Cache\File\TrieFilename;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
use org\bovigo\vfs\vfsStreamDirectory;
|
||||
|
||||
/**
|
||||
* FileTest with Trie structure
|
||||
*/
|
||||
class FileTrieTest extends AbstractCacheTest
|
||||
{
|
||||
/**
|
||||
* @var vfsStreamDirectory
|
||||
*/
|
||||
private $root;
|
||||
|
||||
protected $skippedTests = [
|
||||
'testBasicUsageWithLongKey' => 'Only support keys up to 64 bytes'
|
||||
];
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
$this->root = vfsStream::setup('cache');
|
||||
|
||||
return (new FileCache(vfsStream::url('cache')))
|
||||
->withOption('filename', new TrieFilename('%s.php.cache',4));
|
||||
}
|
||||
}
|
42
msd/vendor/desarrolla2/cache/tests/FileTtlFileTest.php
vendored
Normal file
42
msd/vendor/desarrolla2/cache/tests/FileTtlFileTest.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?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\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\File as FileCache;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
use org\bovigo\vfs\vfsStreamDirectory;
|
||||
|
||||
/**
|
||||
* FileTest
|
||||
*/
|
||||
class FileTtlFileTest extends AbstractCacheTest
|
||||
{
|
||||
/**
|
||||
* @var vfsStreamDirectory
|
||||
*/
|
||||
private $root;
|
||||
|
||||
protected $skippedTests = [
|
||||
'testBasicUsageWithLongKey' => 'Only support keys up to 64 bytes'
|
||||
];
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
$this->root = vfsStream::setup('cache');
|
||||
|
||||
return (new FileCache(vfsStream::url('cache')))
|
||||
->withOption('ttl-strategy', 'file');
|
||||
}
|
||||
}
|
47
msd/vendor/desarrolla2/cache/tests/MemcachedTest.php
vendored
Normal file
47
msd/vendor/desarrolla2/cache/tests/MemcachedTest.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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Memcached as MemcachedCache;
|
||||
use Memcached;
|
||||
|
||||
/**
|
||||
* MemcachedTest
|
||||
*/
|
||||
class MemcachedTest extends AbstractCacheTest
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testBasicUsageWithLongKey' => 'Only support keys up to 250 bytes'
|
||||
];
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
if (!extension_loaded('memcached') || !class_exists('\Memcached')) {
|
||||
$this->markTestSkipped(
|
||||
'The Memcached extension is not available.'
|
||||
);
|
||||
}
|
||||
|
||||
list($host, $port) = explode(':', CACHE_TESTS_MEMCACHED_SERVER) + [1 => 11211];
|
||||
|
||||
$adapter = new Memcached();
|
||||
$adapter->addServer($host, (int)$port);
|
||||
|
||||
if (!$adapter->flush()) {
|
||||
$this->markTestSkipped("Unable to flush Memcached; not running?");
|
||||
}
|
||||
|
||||
return new MemcachedCache($adapter);
|
||||
}
|
||||
}
|
44
msd/vendor/desarrolla2/cache/tests/MemoryTest.php
vendored
Normal file
44
msd/vendor/desarrolla2/cache/tests/MemoryTest.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Memory as MemoryCache;
|
||||
|
||||
/**
|
||||
* MemoryTest
|
||||
*/
|
||||
class MemoryTest extends AbstractCacheTest
|
||||
{
|
||||
public function createSimpleCache()
|
||||
{
|
||||
return new MemoryCache();
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
// No need to clear cache, as the adapters don't persist between tests.
|
||||
}
|
||||
|
||||
public function testExceededLimit()
|
||||
{
|
||||
$cache = $this->createSimpleCache()->withOption('limit', 1);
|
||||
|
||||
$cache->set('foo', 1);
|
||||
$this->assertTrue($cache->has('foo'));
|
||||
|
||||
$cache->set('bar', 1);
|
||||
$this->assertFalse($cache->has('foo'));
|
||||
$this->assertTrue($cache->has('bar'));
|
||||
}
|
||||
}
|
53
msd/vendor/desarrolla2/cache/tests/MongoDBTest.php
vendored
Normal file
53
msd/vendor/desarrolla2/cache/tests/MongoDBTest.php
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\MongoDB as MongoDBCache;
|
||||
use MongoDB\Client;
|
||||
|
||||
/**
|
||||
* MongoDBTest
|
||||
*/
|
||||
class MongoDBTest extends AbstractCacheTest
|
||||
{
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected static $client;
|
||||
|
||||
/**
|
||||
* Use one client per test, as the MongoDB extension leaves connections open
|
||||
*/
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
if (!extension_loaded('mongodb')) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$client = new Client(CACHE_TESTS_MONGO_DSN);
|
||||
self::$client->listDatabases(); // Fail if unable to connect
|
||||
}
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
if (!isset(self::$client)) {
|
||||
$this->markTestSkipped('The mongodb extension is not available');
|
||||
}
|
||||
|
||||
$collection = self::$client->selectCollection(CACHE_TESTS_MONGO_DATABASE, 'cache');
|
||||
|
||||
return (new MongoDBCache($collection))
|
||||
->withOption('initialize', false);
|
||||
}
|
||||
}
|
75
msd/vendor/desarrolla2/cache/tests/MysqliTest.php
vendored
Normal file
75
msd/vendor/desarrolla2/cache/tests/MysqliTest.php
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Mysqli as MysqliCache;
|
||||
|
||||
/**
|
||||
* MysqliTest
|
||||
*/
|
||||
class MysqliTest extends AbstractCacheTest
|
||||
{
|
||||
/**
|
||||
* @var \mysqli
|
||||
*/
|
||||
protected static $mysqli;
|
||||
|
||||
protected $skippedTests = [
|
||||
'testBasicUsageWithLongKey' => 'Only support keys up to 255 bytes'
|
||||
];
|
||||
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
if (class_exists('mysqli')) {
|
||||
static::$mysqli = new \mysqli(
|
||||
ini_get('mysqli.default_host') ?: 'localhost',
|
||||
ini_get('mysqli.default_user') ?: 'root'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function init(): void
|
||||
{
|
||||
if (!class_exists('mysqli')) {
|
||||
$this->markTestSkipped("mysqli extension not loaded");
|
||||
}
|
||||
|
||||
try {
|
||||
static::$mysqli->query('CREATE DATABASE IF NOT EXISTS `' . CACHE_TESTS_MYSQLI_DATABASE . '`');
|
||||
static::$mysqli->select_db(CACHE_TESTS_MYSQLI_DATABASE);
|
||||
|
||||
static::$mysqli->query("CREATE TABLE IF NOT EXISTS `cache` "
|
||||
."( `key` VARCHAR(255), `value` BLOB, `ttl` INT UNSIGNED, PRIMARY KEY (`key`) )");
|
||||
} catch (\Exception $e) {
|
||||
$this->markTestSkipped("skipping mysqli test; " . $e->getMessage());
|
||||
}
|
||||
|
||||
if (static::$mysqli->error) {
|
||||
$this->markTestSkipped(static::$mysqli->error);
|
||||
}
|
||||
}
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
$this->init();
|
||||
|
||||
return (new MysqliCache(static::$mysqli))
|
||||
->withOption('initialize', false);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
static::$mysqli->query('DROP DATABASE IF EXISTS `' . CACHE_TESTS_MYSQLI_DATABASE . '`');
|
||||
static::$mysqli->close();
|
||||
}
|
||||
}
|
88
msd/vendor/desarrolla2/cache/tests/NotCacheTest.php
vendored
Normal file
88
msd/vendor/desarrolla2/cache/tests/NotCacheTest.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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\NotCache as NotCache;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* NotCacheTest
|
||||
*/
|
||||
class NotCacheTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var \Desarrolla2\Cache\NotCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->cache = new NotCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function dataProvider()
|
||||
{
|
||||
return array(
|
||||
array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProvider
|
||||
*/
|
||||
public function testHas()
|
||||
{
|
||||
$this->cache->set('key', 'value');
|
||||
$this->assertFalse($this->cache->has('key'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProvider
|
||||
*/
|
||||
public function testGet()
|
||||
{
|
||||
$this->cache->set('key', 'value');
|
||||
$this->assertFalse($this->cache->get('key', false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProvider
|
||||
*/
|
||||
public function testSet()
|
||||
{
|
||||
$this->assertFalse($this->cache->set('key', 'value'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProvider
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
$this->assertTrue($this->cache->delete('key'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProvider
|
||||
*/
|
||||
public function testWithOption()
|
||||
{
|
||||
$cache = $this->cache->withOption('ttl', 3600);
|
||||
$this->assertSame(3600, $cache->getOption('ttl'));
|
||||
|
||||
$this->assertNotSame($this->cache, $cache);
|
||||
}
|
||||
}
|
40
msd/vendor/desarrolla2/cache/tests/PhpFileTest.php
vendored
Normal file
40
msd/vendor/desarrolla2/cache/tests/PhpFileTest.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\PhpFile as PhpFileCache;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
use org\bovigo\vfs\vfsStreamDirectory;
|
||||
|
||||
/**
|
||||
* FileTest with PhpPacker
|
||||
*/
|
||||
class PhpFileTest extends AbstractCacheTest
|
||||
{
|
||||
/**
|
||||
* @var vfsStreamDirectory
|
||||
*/
|
||||
private $root;
|
||||
|
||||
protected $skippedTests = [
|
||||
'testBasicUsageWithLongKey' => 'Only support keys up to 64 bytes'
|
||||
];
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
$this->root = vfsStream::setup('cache');
|
||||
|
||||
return new PhpFileCache(vfsStream::url('cache'));
|
||||
}
|
||||
}
|
52
msd/vendor/desarrolla2/cache/tests/PredisTest.php
vendored
Normal file
52
msd/vendor/desarrolla2/cache/tests/PredisTest.php
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
namespace Desarrolla2\Test\Cache;
|
||||
|
||||
use Desarrolla2\Cache\Predis as PredisCache;
|
||||
use Predis\Client;
|
||||
use Predis\Connection\ConnectionException;
|
||||
|
||||
/**
|
||||
* PredisTest
|
||||
*/
|
||||
class PredisTest extends AbstractCacheTest
|
||||
{
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
if (!class_exists('Predis\Client')) {
|
||||
$this->markTestSkipped('The predis library is not available');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->client = new Client(CACHE_TESTS_PREDIS_DSN, ['exceptions' => false]);
|
||||
$this->client->connect();
|
||||
} catch (ConnectionException $e) {
|
||||
$this->markTestSkipped($e->getMessage());
|
||||
}
|
||||
|
||||
return new PredisCache($this->client);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$this->client->disconnect();
|
||||
}
|
||||
}
|
21
msd/vendor/desarrolla2/cache/tests/performance/Apc.php
vendored
Normal file
21
msd/vendor/desarrolla2/cache/tests/performance/Apc.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
require_once __DIR__.'/../bootstrap.php';
|
||||
|
||||
use Desarrolla2\Cache\Cache;
|
||||
use Desarrolla2\Cache\Adapter\Apcu;
|
||||
|
||||
$cache = new Cache(new Apcu());
|
||||
|
||||
require_once __DIR__.'/common.php';
|
21
msd/vendor/desarrolla2/cache/tests/performance/File.php
vendored
Normal file
21
msd/vendor/desarrolla2/cache/tests/performance/File.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
require_once __DIR__.'/../bootstrap.php';
|
||||
|
||||
use Desarrolla2\Cache\Cache;
|
||||
use Desarrolla2\Cache\Adapter\File;
|
||||
|
||||
$cache = new Cache(new File('/tmp'));
|
||||
|
||||
require_once __DIR__.'/common.php';
|
21
msd/vendor/desarrolla2/cache/tests/performance/Mongo.php
vendored
Normal file
21
msd/vendor/desarrolla2/cache/tests/performance/Mongo.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
require_once __DIR__.'/../bootstrap.php';
|
||||
|
||||
use Desarrolla2\Cache\Cache;
|
||||
use Desarrolla2\Cache\Adapter\Mongo;
|
||||
|
||||
$cache = new Cache(new Mongo('mongodb://localhost:27017'));
|
||||
|
||||
require_once __DIR__.'/common.php';
|
21
msd/vendor/desarrolla2/cache/tests/performance/NoCache.php
vendored
Normal file
21
msd/vendor/desarrolla2/cache/tests/performance/NoCache.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
require_once __DIR__.'/../bootstrap.php';
|
||||
|
||||
use Desarrolla2\Cache\Cache;
|
||||
use Desarrolla2\Cache\Adapter\NotCache;
|
||||
|
||||
$cache = new Cache(new NotCache());
|
||||
|
||||
require_once __DIR__.'/common.php';
|
43
msd/vendor/desarrolla2/cache/tests/performance/common.php
vendored
Normal file
43
msd/vendor/desarrolla2/cache/tests/performance/common.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?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>
|
||||
*/
|
||||
|
||||
|
||||
//build test data outside of timing loop
|
||||
$data = [];
|
||||
for ($i = 1; $i <= 10000; $i++) {
|
||||
$data[$i] = md5($i);
|
||||
}
|
||||
|
||||
$timer = new \Desarrolla2\Timer\Timer(new \Desarrolla2\Timer\Formatter\Human());
|
||||
for ($i = 1; $i <= 10000; $i++) {
|
||||
$cache->set($data[$i], $data[$i], 3600);
|
||||
}
|
||||
$timer->mark('10.000 set');
|
||||
for ($i = 1; $i <= 10000; $i++) {
|
||||
$cache->has($data[$i]);
|
||||
}
|
||||
$timer->mark('10.000 has');
|
||||
for ($i = 1; $i <= 10000; $i++) {
|
||||
$cache->get($data[$i]);
|
||||
}
|
||||
$timer->mark('10.000 get');
|
||||
for ($i = 1; $i <= 10000; $i++) {
|
||||
$cache->has($data[$i]);
|
||||
$cache->get($data[$i]);
|
||||
}
|
||||
$timer->mark('10.000 has+get combos');
|
||||
|
||||
$benchmarks = $timer->getAll();
|
||||
foreach ($benchmarks as $benchmark) {
|
||||
ld($benchmark);
|
||||
}
|
Reference in New Issue
Block a user