Skip to content

Commit 7daa763

Browse files
committed
Initial commit
0 parents  commit 7daa763

20 files changed

Lines changed: 776 additions & 0 deletions

.gitattributes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.php diff=php
2+
3+
/build export-ignore
4+
/Tests export-ignore
5+
/phpunit.* export-ignore
6+
/*.yml export-ignore

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
build
2+
vendor
3+
.DS_Store
4+
.idea
5+
composer.lock
6+
phpunit.phar
7+
*.yml
8+
.env
9+
!.travis.yml

CacheItem.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace Koded\Caching;
4+
5+
use Psr\Cache\CacheItemInterface;
6+
7+
8+
abstract class CacheItem implements CacheItemInterface
9+
{
10+
/** @var mixed */
11+
protected $value;
12+
13+
/** @var Cache */
14+
protected $client;
15+
16+
/** @var string */
17+
private $key;
18+
19+
/** @var int Unix timestamp for expiration time */
20+
private $expiresAt;
21+
22+
public function __construct(Cache $client, string $key)
23+
{
24+
$this->key = $key;
25+
$this->client = $client;
26+
}
27+
28+
public function __destruct()
29+
{
30+
unset($this->client);
31+
}
32+
33+
public function getKey(): string
34+
{
35+
return $this->key;
36+
}
37+
38+
public function get()
39+
{
40+
return $this->isHit() ? $this->value : null;
41+
}
42+
43+
public function isHit(): bool
44+
{
45+
return $this->client->has($this->key);
46+
}
47+
48+
public function set($value)
49+
{
50+
$this->value = $value;
51+
52+
return $this;
53+
}
54+
55+
public function expiresAt($expiration)
56+
{
57+
$this->expiresAt = $expiration;
58+
59+
return $this;
60+
}
61+
62+
public function expiresAfter($time)
63+
{
64+
if (null === $time && null !== $global = $this->client->getTtl()) {
65+
$this->expiresAt = time() + cache_ttl($global);
66+
67+
return $this;
68+
}
69+
70+
$seconds = cache_ttl($time);
71+
$this->expiresAt = $seconds ? time() + $seconds : null;
72+
73+
return $this;
74+
}
75+
76+
/**
77+
* Returns expiration time for the cache item.
78+
* This method is not part of the PSR-6.
79+
*
80+
* @return int|null|\DateInterval|\DateTimeInterface
81+
*/
82+
public function ttl()
83+
{
84+
return $this->expiresAt;
85+
}
86+
}

CacheItemPool.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
namespace Koded\Caching;
4+
5+
use Exception;
6+
use Koded\Caching\Client\CacheClientFactory;
7+
use Psr\Cache\{CacheItemInterface, CacheItemPoolInterface};
8+
use Psr\SimpleCache\CacheInterface;
9+
10+
11+
abstract class CacheItemPool implements CacheItemPoolInterface
12+
{
13+
/** @var CacheInterface */
14+
protected $client;
15+
16+
/** @var CacheItemInterface[] */
17+
private $deferred = [];
18+
19+
abstract public function __construct(CacheClientFactory $factory, string $client);
20+
21+
public function __destruct()
22+
{
23+
unset($this->client);
24+
}
25+
26+
public function getItems(array $keys = []): array
27+
{
28+
$collection = [];
29+
foreach ($keys as $key) {
30+
$collection[$key] = $this->getItem($key);
31+
}
32+
33+
return $collection;
34+
}
35+
36+
public function getItem($key): CacheItemInterface
37+
{
38+
if (isset($this->deferred[$key])) {
39+
return $this->deferred[$key];
40+
}
41+
42+
try {
43+
return (new class($this->client, $key) extends CacheItem
44+
{
45+
})->set($this->client->get($key));
46+
47+
} catch (Exception $e) {
48+
throw ExtendedCacheException::from($e);
49+
}
50+
}
51+
52+
public function hasItem($key): bool
53+
{
54+
try {
55+
return $this->client->has($key);
56+
} catch (Exception $e) {
57+
throw ExtendedCacheException::from($e);
58+
}
59+
}
60+
61+
public function clear(): bool
62+
{
63+
if ($this->client->clear()) {
64+
$this->deferred = [];
65+
return true;
66+
}
67+
68+
return false;
69+
}
70+
71+
public function deleteItems(array $keys): bool
72+
{
73+
$deleted = 0;
74+
foreach ($keys as $key) {
75+
$this->deleteItem($key) && ++$deleted;
76+
}
77+
78+
return count($keys) === $deleted;
79+
}
80+
81+
public function deleteItem($key): bool
82+
{
83+
try {
84+
if ($this->client->delete($key)) {
85+
unset($this->deferred[$key]);
86+
return true;
87+
}
88+
89+
return false;
90+
91+
} catch (Exception $e) {
92+
throw ExtendedCacheException::from($e);
93+
}
94+
}
95+
96+
public function saveDeferred(CacheItemInterface $item): bool
97+
{
98+
$this->deferred[$item->getKey()] = $item;
99+
100+
return true;
101+
}
102+
103+
public function commit(): bool
104+
{
105+
foreach ($this->deferred as $key => $item) {
106+
if (true === $this->save($item)) {
107+
unset($this->deferred[$key]);
108+
}
109+
}
110+
111+
return empty($this->deferred);
112+
}
113+
114+
public function save(CacheItemInterface $item): bool
115+
{
116+
/** @var CacheItem $item */
117+
$value = (function() {
118+
return $this->value;
119+
})->bindTo($item, $item);
120+
121+
return $this->client->set($item->getKey(), $value(), cache_ttl($item->ttl()));
122+
}
123+
}

CachePoolFactory.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Koded\Caching;
4+
5+
use Koded\Caching\Client\CacheClientFactory;
6+
use Koded\Caching\Configuration\ConfigFactory;
7+
use Psr\Cache\CacheItemPoolInterface;
8+
9+
/**
10+
* CachePoolFactory creates a new instance of CacheItemPoolInterface classes.
11+
*
12+
* Production ready:
13+
*
14+
* - Redis with redis extension
15+
* - Redis with Predis library
16+
* - Memcached
17+
*
18+
* Additional for development:
19+
* - File
20+
* - Memory (for testing)
21+
* - Null
22+
*/
23+
class CachePoolFactory
24+
{
25+
26+
public static function new(string $client, array $parameters = []): CacheItemPoolInterface
27+
{
28+
$factory = new CacheClientFactory(new ConfigFactory($parameters));
29+
30+
return new class($factory, strtolower($client)) extends CacheItemPool
31+
{
32+
public function __construct(CacheClientFactory $factory, string $client)
33+
{
34+
$this->client = $factory->build($client);
35+
}
36+
};
37+
}
38+
}

ExtendedCacheException.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Koded\Caching;
4+
5+
use Exception;
6+
use Psr\Cache\InvalidArgumentException;
7+
8+
class ExtendedCacheException extends \RuntimeException implements InvalidArgumentException
9+
{
10+
11+
public static function from(Exception $e)
12+
{
13+
return new self($e->getMessage(), $e->getCode(), $e);
14+
}
15+
}

LICENSE

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
BSD 3-Clause License
2+
3+
Koded - Extended Caching Library
4+
Copyright (c) 2018, Mihail Binev
5+
All rights reserved.
6+
7+
Redistribution and use in source and binary forms, with or without
8+
modification, are permitted provided that the following conditions are met:
9+
10+
* Redistributions of source code must retain the above copyright notice, this
11+
list of conditions and the following disclaimer.
12+
13+
* Redistributions in binary form must reproduce the above copyright notice,
14+
this list of conditions and the following disclaimer in the documentation
15+
and/or other materials provided with the distribution.
16+
17+
* Neither the name of the copyright holder nor the names of its
18+
contributors may be used to endorse or promote products derived from
19+
this software without specific prior written permission.
20+
21+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
Koded - Extended Caching Library
2+
================================
3+
4+
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg)](https://php.net/)
5+
[![Build Status](https://scrutinizer-ci.com/g/kodedphp/cache-extended/badges/build.png?b=master)](https://scrutinizer-ci.com/g/kodedphp/cache-extended/build-status/master)
6+
[![Code Coverage](https://scrutinizer-ci.com/g/kodedphp/cache-extended/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/kodedphp/cache-extended/?branch=master)
7+
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/kodedphp/cache-extended/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/kodedphp/cache-extended/?branch=master)
8+
[![Latest Stable Version](https://img.shields.io/packagist/v/koded/cache-extended.svg)](https://packagist.org/packages/koded/cache-extended)
9+
[![Software license](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](LICENSE)
10+
11+
A PSR-6 caching library for PHP 7 using several caching technologies.
12+
13+
14+
Requirements
15+
------------
16+
17+
> The library is not tested on any Windows OS and may not work as expected there.
18+
19+
- PHP 7.1 or higher
20+
21+
22+
Usage
23+
-----
24+
25+
- create an instance of `CacheItemPoolInterface` with desired caching technology
26+
- manipulate the cache items with the `pool` instance
27+
28+
29+
```php
30+
$pool = CachePoolFactory::new('redis');
31+
32+
$item = $pool->getItem('fubar');
33+
$item->set('some value');
34+
$item->expiresAfter(new \DateTime('+3 days'));
35+
36+
$pool->save();
37+
```
38+
39+
NOTE: The `CachePoolFactory` accepts specific parameters for the underlying caching technology.
40+
41+
This library uses the [Koded Simple Cache][koded-cache-simple]. Please see the README in that repository.
42+
43+
44+
45+
[koded-cache-simple]: https://github.com/kodedphp/cache-simple

0 commit comments

Comments
 (0)