44
55namespace OpenClassrooms \ServiceProxy \Handler \Impl \Cache ;
66
7- use Doctrine \Common \Cache \Psr6 \CacheItem ;
8- use OpenClassrooms \DoctrineCacheExtension \CacheProviderDecorator ;
97use OpenClassrooms \ServiceProxy \Handler \Contract \CacheHandler ;
108use OpenClassrooms \ServiceProxy \Handler \Impl \ConfigurableHandler ;
119use Psr \Cache \CacheItemInterface ;
10+ use Psr \Cache \CacheItemPoolInterface ;
1211use Symfony \Component \Cache \Adapter \ArrayAdapter ;
1312
1413/**
@@ -18,11 +17,11 @@ final class DoctrineCacheHandler implements CacheHandler
1817{
1918 use ConfigurableHandler;
2019
21- private CacheProviderDecorator $ cacheProvider ;
20+ private CacheItemPoolInterface $ pool ;
2221
23- public function __construct (? CacheProviderDecorator $ cacheProvider = null , ?string $ name = null )
22+ public function __construct (CacheItemPoolInterface $ pool = null , ?string $ name = null )
2423 {
25- $ this ->cacheProvider = $ cacheProvider ?? new CacheProviderDecorator ( new ArrayAdapter (storeSerialized: false ) );
24+ $ this ->pool = $ pool ?? new ArrayAdapter (storeSerialized: false );
2625 $ this ->name = $ name ;
2726 }
2827
@@ -31,26 +30,56 @@ public function fetch(string $poolName, string $id): CacheItemInterface
3130 $ tags = explode ('| ' , $ id );
3231 $ id = array_shift ($ tags );
3332
34- $ value = $ this ->cacheProvider ->fetchWithNamespace ($ id , $ tags [0 ] ?? null );
35-
36- return new CacheItem ($ id , $ value , $ value !== false );
33+ return $ this ->fetchWithNamespace ($ id , $ tags [0 ] ?? null );
3734 }
3835
39- public function save (string $ poolName , string $ id , $ data , ? int $ lifeTime = null , array $ tags = [] ): void
36+ private function fetchWithNamespace (string $ id , string $ namespaceId = null ): CacheItemInterface
4037 {
41- $ this ->cacheProvider ->saveWithNamespace ($ id , $ data , $ tags [0 ] ?? null , $ lifeTime );
38+ if (null !== $ namespaceId ) {
39+ $ namespace = $ this ->doFetch ($ namespaceId );
40+
41+ if ($ namespace ->isHit ()) {
42+ $ id = $ namespace ->get ().$ id ;
43+ }
44+ }
45+
46+ return $ this ->doFetch ($ id );
4247 }
4348
44- public function contains (string $ poolName , string $ id ): bool
49+ public function save (string $ poolName , string $ id, $ data , ? int $ lifeTime = null , array $ tags = [] ): void
4550 {
46- return $ this ->cacheProvider ->contains ($ id );
51+ $ namespaceId = $ tags [0 ] ?? null ;
52+
53+ if (null !== $ namespaceId ) {
54+ $ namespace = $ this ->doFetch ($ namespaceId );
55+ if (! $ namespace ->isHit ()) {
56+ $ namespace ->set ($ namespaceId .'_ ' .rand (0 , 1000000 ))
57+ // 7 days as no expiration can prevent cache eviction forever (like redis)
58+ ->expiresAfter (7 * 24 * 60 * 60 );
59+
60+ $ this ->pool ->save ($ namespace );
61+ }
62+ $ id = $ namespace ->get ().$ id ;
63+ }
64+
65+ $ item = $ this ->doFetch ($ id );
66+
67+ $ item ->set ($ data )
68+ ->expiresAfter ($ lifeTime ?? 3600 );
69+
70+ $ this ->pool ->save ($ item );
4771 }
4872
4973 public function invalidateTags (string $ poolName , array $ tags ): void
5074 {
5175 throw new \BadMethodCallException ('Cache provider does not support tags invalidation ' );
5276 }
5377
78+ private function doFetch (string $ id ): CacheItemInterface
79+ {
80+ return $ this ->pool ->getItem (rawurlencode ($ id ));
81+ }
82+
5483 public function getName (): string
5584 {
5685 return $ this ->name ?? 'doctrine_array ' ;
0 commit comments