diff --git a/src/Tracing/Cache/TraceableCacheAdapterForV3WithNamespace.php b/src/Tracing/Cache/TraceableCacheAdapterForV3WithNamespace.php new file mode 100644 index 00000000..7b53c286 --- /dev/null +++ b/src/Tracing/Cache/TraceableCacheAdapterForV3WithNamespace.php @@ -0,0 +1,64 @@ + + */ + use TraceableCacheAdapterTrait; + + /** + * @param HubInterface $hub The current hub + * @param AdapterInterface $decoratedAdapter The decorated cache adapter + */ + public function __construct(HubInterface $hub, AdapterInterface $decoratedAdapter) + { + $this->hub = $hub; + $this->decoratedAdapter = $decoratedAdapter; + } + + /** + * {@inheritdoc} + * + * @param mixed[] $metadata + */ + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed + { + return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { + if (!$this->decoratedAdapter instanceof CacheInterface) { + throw new \BadMethodCallException(\sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); + } + + return $this->decoratedAdapter->get($key, $callback, $beta, $metadata); + }, $key); + } + + public function withSubNamespace(string $namespace): static + { + if (!$this->decoratedAdapter instanceof NamespacedPoolInterface) { + throw new \BadMethodCallException(\sprintf('The %s::withSubNamespace() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, NamespacedPoolInterface::class)); + } + + $clone = clone $this; + $clone->decoratedAdapter = $this->decoratedAdapter->withSubNamespace($namespace); + + return $clone; + } +} diff --git a/src/aliases.php b/src/aliases.php index 92272bef..e0433bcb 100644 --- a/src/aliases.php +++ b/src/aliases.php @@ -9,6 +9,7 @@ use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapter; use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV2; use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV3; +use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV3WithNamespace; use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapter; use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapterForV2; use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapterForV3; @@ -38,12 +39,17 @@ use Symfony\Component\Cache\DoctrineProvider; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\Response\StreamableInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; if (interface_exists(AdapterInterface::class)) { if (!class_exists(DoctrineProvider::class, false) && version_compare(\PHP_VERSION, '8.0.0', '>=')) { if (!class_exists(TraceableCacheAdapter::class, false)) { - class_alias(TraceableCacheAdapterForV3::class, TraceableCacheAdapter::class); + if (interface_exists(NamespacedPoolInterface::class)) { + class_alias(TraceableCacheAdapterForV3WithNamespace::class, TraceableCacheAdapter::class); + } else { + class_alias(TraceableCacheAdapterForV3::class, TraceableCacheAdapter::class); + } } if (!class_exists(TraceableTagAwareCacheAdapter::class, false)) { diff --git a/tests/Tracing/Cache/TraceableCacheAdapterTest.php b/tests/Tracing/Cache/TraceableCacheAdapterTest.php index 1536adfd..5e5b9c29 100644 --- a/tests/Tracing/Cache/TraceableCacheAdapterTest.php +++ b/tests/Tracing/Cache/TraceableCacheAdapterTest.php @@ -6,6 +6,7 @@ use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapter; use Symfony\Component\Cache\Adapter\AdapterInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; /** * @phpstan-extends AbstractTraceableCacheAdapterTest @@ -27,4 +28,16 @@ protected static function getAdapterClassFqcn(): string { return AdapterInterface::class; } + + public function testNamespacePoolImplementation(): void + { + if (!interface_exists(NamespacedPoolInterface::class)) { + $this->markTestSkipped('NamespacedPoolInterface does not exists.'); + } + + $decoratedAdapter = $this->createMock(static::getAdapterClassFqcn()); + $adapter = $this->createCacheAdapter($decoratedAdapter); + + static::assertInstanceOf(NamespacedPoolInterface::class, $adapter); + } }