Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a046b58

Browse filesBrowse files
[Cache] Symfony PSR-6 implementation
1 parent a4f3baa commit a046b58
Copy full SHA for a046b58

13 files changed

+678
-0
lines changed

‎composer.json

Copy file name to clipboardExpand all lines: composer.json
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"replace": {
3131
"symfony/asset": "self.version",
3232
"symfony/browser-kit": "self.version",
33+
"symfony/cache": "self.version",
3334
"symfony/class-loader": "self.version",
3435
"symfony/config": "self.version",
3536
"symfony/console": "self.version",
@@ -74,6 +75,7 @@
7475
"symfony/yaml": "self.version"
7576
},
7677
"require-dev": {
78+
"doctrine/cache": "~1.6",
7779
"doctrine/data-fixtures": "1.0.*",
7880
"doctrine/dbal": "~2.4",
7981
"doctrine/orm": "~2.4,>=2.4.5",
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
phpunit.xml
3+
vendor/
+227Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Adapter;
13+
14+
use Psr\Cache\CacheItemInterface;
15+
use Psr\Cache\CacheItemPoolInterface;
16+
use Symfony\Component\Cache\CacheItem;
17+
use Symfony\Component\Cache\Exception\InvalidArgumentException;
18+
19+
/**
20+
* @author Nicolas Grekas <p@tchwork.com>
21+
*/
22+
abstract class AbstractAdapter implements CacheItemPoolInterface
23+
{
24+
private $namespace;
25+
private $deferred = array();
26+
private $createCacheItem;
27+
private $mergeByLifetime;
28+
29+
protected function __construct($namespace = '', $defaultLifetime = 0)
30+
{
31+
$this->namespace = $namespace;
32+
$this->createCacheItem = \Closure::bind(
33+
function ($key, $value, $isHit) use ($defaultLifetime) {
34+
$item = new CacheItem();
35+
$item->key = $key;
36+
$item->value = $value;
37+
$item->isHit = $isHit;
38+
$item->defaultLifetime = $defaultLifetime;
39+
40+
return $item;
41+
},
42+
$this,
43+
CacheItem::class
44+
);
45+
$this->mergeByLifetime = \Closure::bind(
46+
function ($deferred, $namespace) {
47+
$byLifetime = array();
48+
49+
foreach ($deferred as $key => $item) {
50+
if (0 <= $item->lifetime) {
51+
$byLifetime[$item->lifetime][$namespace.$key] = $item->value;
52+
}
53+
}
54+
55+
return $byLifetime;
56+
},
57+
$this,
58+
CacheItem::class
59+
);
60+
}
61+
62+
/**
63+
* Fetches several cache items.
64+
*
65+
* @param array $ids The cache identifiers to fetch.
66+
*
67+
* @return array The corresponding values found in the cache.
68+
*/
69+
abstract protected function doFetch(array $ids);
70+
71+
/**
72+
* Persists several cache items immediately.
73+
*
74+
* @param array $values The values to cache, indexed by their cache identifier.
75+
* @param int $lifetime The lifetime of the cached values, 0 for persisting until manual cleaning.
76+
*
77+
* @return array|bool The identifiers that failed to be cached or a boolean stating if caching succeeded or not.
78+
*/
79+
abstract protected function doSave(array $values, $lifetime);
80+
81+
/**
82+
* {@inheritdoc}
83+
*/
84+
public function getItem($key)
85+
{
86+
$id = $this->getId($key);
87+
88+
if ($this->deferred) {
89+
$this->commit();
90+
}
91+
if (isset($this->deferred[$key])) {
92+
return $this->deferred[$key];
93+
}
94+
95+
$f = $this->createCacheItem;
96+
$isHit = false;
97+
$value = null;
98+
99+
foreach ($this->doFetch(array($id)) as $value) {
100+
$isHit = true;
101+
}
102+
103+
return $f($key, $value, $isHit);
104+
}
105+
106+
/**
107+
* {@inheritdoc}
108+
*/
109+
public function getItems(array $keys = array())
110+
{
111+
if ($this->deferred) {
112+
$this->commit();
113+
}
114+
$f = $this->createCacheItem;
115+
$ids = array();
116+
$items = array();
117+
118+
foreach ($keys as $key) {
119+
$id = $this->getId($key);
120+
121+
if (isset($this->deferred[$key])) {
122+
$items[$key] = $this->deferred[$key];
123+
} else {
124+
$ids[$key] = $id;
125+
}
126+
}
127+
128+
$values = $this->doFetch($ids);
129+
130+
foreach ($ids as $key => $id) {
131+
$isHit = isset($values[$id]);
132+
$items[$key] = $f($key, $isHit ? $values[$id] : null, $isHit);
133+
}
134+
135+
return $items;
136+
}
137+
138+
/**
139+
* {@inheritdoc}
140+
*/
141+
public function deleteItems(array $keys)
142+
{
143+
$ok = true;
144+
145+
foreach ($keys as $key) {
146+
$ok = $this->deleteItem($key) && $ok;
147+
unset($this->deferred[$key]);
148+
}
149+
150+
return $ok;
151+
}
152+
153+
/**
154+
* {@inheritdoc}
155+
*/
156+
public function save(CacheItemInterface $item)
157+
{
158+
if (!$item instanceof CacheItem) {
159+
return false;
160+
}
161+
$key = $item->getKey();
162+
$this->deferred[$key] = $item;
163+
$this->commit();
164+
165+
return !isset($this->deferred[$key]);
166+
}
167+
168+
/**
169+
* {@inheritdoc}
170+
*/
171+
public function saveDeferred(CacheItemInterface $item)
172+
{
173+
if (!$item instanceof CacheItem) {
174+
return false;
175+
}
176+
$this->deferred[$item->getKey()] = clone $item;
177+
178+
return true;
179+
}
180+
181+
/**
182+
* {@inheritdoc}
183+
*/
184+
public function commit()
185+
{
186+
$f = $this->mergeByLifetime;
187+
$ko = array();
188+
$namespaceLen = strlen($this->namespace);
189+
190+
foreach ($f($this->deferred, $this->namespace) as $lifetime => $values) {
191+
if (true === $ok = $this->doSave($values, $lifetime)) {
192+
continue;
193+
}
194+
if (false === $ok) {
195+
$ok = array_keys($values);
196+
}
197+
foreach ($ok as $failedId) {
198+
$key = substr($failedId, $namespaceLen);
199+
$ko[$key] = $this->deferred[$key];
200+
}
201+
}
202+
203+
return !$this->deferred = $ko;
204+
}
205+
206+
public function __destruct()
207+
{
208+
if ($this->deferred) {
209+
$this->commit();
210+
}
211+
}
212+
213+
protected function getId($key)
214+
{
215+
if (!is_string($key)) {
216+
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', is_object($key) ? get_class($key) : gettype($key)));
217+
}
218+
if (!isset($key[0])) {
219+
throw new InvalidArgumentException('Cache key length must be greater than zero');
220+
}
221+
if (isset($key[strcspn($key, '{}()/\@')])) {
222+
throw new InvalidArgumentException('Cache key contains reserved characters {}()/\@');
223+
}
224+
225+
return $this->namespace.$key;
226+
}
227+
}
+68Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Adapter;
13+
14+
use Symfony\Component\Cache\Exception\CacheException;
15+
16+
/**
17+
* @author Nicolas Grekas <p@tchwork.com>
18+
*/
19+
class ApcuAdapter extends AbstractAdapter
20+
{
21+
public function __construct($namespace = '', $defaultLifetime = 0)
22+
{
23+
if (!function_exists('apcu_fetch')) {
24+
throw new CacheException('APCu is not installed');
25+
}
26+
parent::__construct($namespace, $defaultLifetime);
27+
}
28+
29+
/**
30+
* {@inheritdoc}
31+
*/
32+
public function hasItem($key)
33+
{
34+
return apcu_exists($this->getId($key));
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function clear()
41+
{
42+
return apcu_clear_cache();
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
public function deleteItem($key)
49+
{
50+
return apcu_delete($id = $this->getId($key)) || !apcu_exists($id);
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*/
56+
protected function doFetch(array $ids)
57+
{
58+
return apcu_fetch($ids);
59+
}
60+
61+
/**
62+
* {@inheritdoc}
63+
*/
64+
protected function doSave(array $values, $lifetime)
65+
{
66+
return apcu_store($values, null, $lifetime);
67+
}
68+
}
+68Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Adapter;
13+
14+
use Doctrine\Common\Cache\CacheProvider;
15+
16+
/**
17+
* @author Nicolas Grekas <p@tchwork.com>
18+
*/
19+
class DoctrineAdapter extends AbstractAdapter
20+
{
21+
private $provider;
22+
23+
public function __construct(CacheProvider $provider, $defaultLifetime = 0)
24+
{
25+
parent::__construct('', $defaultLifetime);
26+
$this->provider = $provider;
27+
}
28+
29+
/**
30+
* {@inheritdoc}
31+
*/
32+
public function hasItem($key)
33+
{
34+
return $this->provider->contains($this->getId($key));
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function clear()
41+
{
42+
return $this->provider->flushAll();
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
public function deleteItem($key)
49+
{
50+
return $this->provider->delete($this->getId($key));
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*/
56+
protected function doFetch(array $ids)
57+
{
58+
return $this->provider->fetchMultiple($ids);
59+
}
60+
61+
/**
62+
* {@inheritdoc}
63+
*/
64+
protected function doSave(array $values, $lifetime)
65+
{
66+
return $this->provider->saveMultiple($values, $lifetime);
67+
}
68+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.