17
17
use Symfony \Component \Cache \ResettableInterface ;
18
18
use Symfony \Component \Cache \Traits \AbstractAdapterTrait ;
19
19
use Symfony \Component \Cache \Traits \ContractsTrait ;
20
+ use Symfony \Contracts \Cache \NamespacedPoolInterface ;
20
21
use Symfony \Contracts \Cache \TagAwareCacheInterface ;
21
22
22
23
/**
30
31
*
31
32
* @internal
32
33
*/
33
- abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, LoggerAwareInterface, ResettableInterface
34
+ abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, AdapterInterface, NamespacedPoolInterface, LoggerAwareInterface, ResettableInterface
34
35
{
35
36
use AbstractAdapterTrait;
36
37
use ContractsTrait;
37
38
39
+ /**
40
+ * @internal
41
+ */
42
+ protected const NS_SEPARATOR = ': ' ;
43
+
38
44
private const TAGS_PREFIX = "\1tags \1" ;
39
45
40
46
protected function __construct (string $ namespace = '' , int $ defaultLifetime = 0 )
41
47
{
42
- $ this ->namespace = '' === $ namespace ? '' : CacheItem::validateKey ($ namespace ).': ' ;
48
+ if ('' !== $ namespace ) {
49
+ if (str_contains ($ namespace , static ::NS_SEPARATOR )) {
50
+ if (str_contains ($ namespace , static ::NS_SEPARATOR .static ::NS_SEPARATOR )) {
51
+ throw new InvalidArgumentException (\sprintf ('Cache namespace "%s" contains empty sub-namespace. ' , $ namespace ));
52
+ }
53
+ $ namespace = str_replace (static ::NS_SEPARATOR , '' , $ namespace );
54
+ }
55
+ $ this ->namespace = CacheItem::validateKey ($ namespace ).static ::NS_SEPARATOR ;
56
+ }
57
+ $ this ->rootNamespace = $ this ->namespace ;
58
+
43
59
$ this ->defaultLifetime = $ defaultLifetime ;
44
60
if (null !== $ this ->maxIdLength && \strlen ($ namespace ) > $ this ->maxIdLength - 24 ) {
45
61
throw new InvalidArgumentException (\sprintf ('Namespace must be %d chars max, %d given ("%s"). ' , $ this ->maxIdLength - 24 , \strlen ($ namespace ), $ namespace ));
@@ -70,7 +86,7 @@ static function ($key, $value, $isHit) {
70
86
CacheItem::class
71
87
);
72
88
self ::$ mergeByLifetime ??= \Closure::bind (
73
- static function ($ deferred , &$ expiredIds , $ getId , $ tagPrefix , $ defaultLifetime ) {
89
+ static function ($ deferred , &$ expiredIds , $ getId , $ tagPrefix , $ defaultLifetime, $ rootNamespace ) {
74
90
$ byLifetime = [];
75
91
$ now = microtime (true );
76
92
$ expiredIds = [];
@@ -102,10 +118,10 @@ static function ($deferred, &$expiredIds, $getId, $tagPrefix, $defaultLifetime)
102
118
$ value ['tag-operations ' ] = ['add ' => [], 'remove ' => []];
103
119
$ oldTags = $ item ->metadata [CacheItem::METADATA_TAGS ] ?? [];
104
120
foreach (array_diff_key ($ value ['tags ' ], $ oldTags ) as $ addedTag ) {
105
- $ value ['tag-operations ' ]['add ' ][] = $ getId ($ tagPrefix .$ addedTag );
121
+ $ value ['tag-operations ' ]['add ' ][] = $ getId ($ tagPrefix .$ addedTag, $ rootNamespace );
106
122
}
107
123
foreach (array_diff_key ($ oldTags , $ value ['tags ' ]) as $ removedTag ) {
108
- $ value ['tag-operations ' ]['remove ' ][] = $ getId ($ tagPrefix .$ removedTag );
124
+ $ value ['tag-operations ' ]['remove ' ][] = $ getId ($ tagPrefix .$ removedTag, $ rootNamespace );
109
125
}
110
126
$ value ['tags ' ] = array_keys ($ value ['tags ' ]);
111
127
@@ -168,7 +184,7 @@ protected function doDeleteYieldTags(array $ids): iterable
168
184
public function commit (): bool
169
185
{
170
186
$ ok = true ;
171
- $ byLifetime = (self ::$ mergeByLifetime )($ this ->deferred , $ expiredIds , $ this ->getId (...), self ::TAGS_PREFIX , $ this ->defaultLifetime );
187
+ $ byLifetime = (self ::$ mergeByLifetime )($ this ->deferred , $ expiredIds , $ this ->getId (...), self ::TAGS_PREFIX , $ this ->defaultLifetime , $ this -> rootNamespace );
172
188
$ retry = $ this ->deferred = [];
173
189
174
190
if ($ expiredIds ) {
@@ -195,7 +211,7 @@ public function commit(): bool
195
211
$ v = $ values [$ id ];
196
212
$ type = get_debug_type ($ v );
197
213
$ message = \sprintf ('Failed to save key "{key}" of type %s%s ' , $ type , $ e instanceof \Exception ? ': ' .$ e ->getMessage () : '. ' );
198
- CacheItem::log ($ this ->logger , $ message , ['key ' => substr ($ id , \strlen ($ this ->namespace )), 'exception ' => $ e instanceof \Exception ? $ e : null , 'cache-adapter ' => get_debug_type ($ this )]);
214
+ CacheItem::log ($ this ->logger , $ message , ['key ' => substr ($ id , \strlen ($ this ->rootNamespace )), 'exception ' => $ e instanceof \Exception ? $ e : null , 'cache-adapter ' => get_debug_type ($ this )]);
199
215
}
200
216
} else {
201
217
foreach ($ values as $ id => $ v ) {
@@ -219,7 +235,7 @@ public function commit(): bool
219
235
$ ok = false ;
220
236
$ type = get_debug_type ($ v );
221
237
$ message = \sprintf ('Failed to save key "{key}" of type %s%s ' , $ type , $ e instanceof \Exception ? ': ' .$ e ->getMessage () : '. ' );
222
- CacheItem::log ($ this ->logger , $ message , ['key ' => substr ($ id , \strlen ($ this ->namespace )), 'exception ' => $ e instanceof \Exception ? $ e : null , 'cache-adapter ' => get_debug_type ($ this )]);
238
+ CacheItem::log ($ this ->logger , $ message , ['key ' => substr ($ id , \strlen ($ this ->rootNamespace )), 'exception ' => $ e instanceof \Exception ? $ e : null , 'cache-adapter ' => get_debug_type ($ this )]);
223
239
}
224
240
}
225
241
@@ -244,7 +260,7 @@ public function deleteItems(array $keys): bool
244
260
try {
245
261
foreach ($ this ->doDeleteYieldTags (array_values ($ ids )) as $ id => $ tags ) {
246
262
foreach ($ tags as $ tag ) {
247
- $ tagData [$ this ->getId (self ::TAGS_PREFIX .$ tag )][] = $ id ;
263
+ $ tagData [$ this ->getId (self ::TAGS_PREFIX .$ tag, $ this -> rootNamespace )][] = $ id ;
248
264
}
249
265
}
250
266
} catch (\Exception ) {
@@ -283,7 +299,7 @@ public function invalidateTags(array $tags): bool
283
299
284
300
$ tagIds = [];
285
301
foreach (array_unique ($ tags ) as $ tag ) {
286
- $ tagIds [] = $ this ->getId (self ::TAGS_PREFIX .$ tag );
302
+ $ tagIds [] = $ this ->getId (self ::TAGS_PREFIX .$ tag, $ this -> rootNamespace );
287
303
}
288
304
289
305
try {
0 commit comments