diff --git a/composer.json b/composer.json
index 89f4d9f6..29d8e654 100644
--- a/composer.json
+++ b/composer.json
@@ -10,15 +10,15 @@
],
"require": {
"php": "^7.2 || ^8.0",
- "bear/resource": "^1.15",
+ "bear/resource": "^1.16.1",
"bear/sunday": "^1.5",
"doctrine/annotations": "^1.8",
"doctrine/cache": "^2.0",
"mobiledetect/mobiledetectlib": "^2.8",
"psr/cache": "^1.0",
"ray/aop": "^2.10",
- "ray/di": "^2.12",
- "ray/psr-cache-module": "^1.0",
+ "ray/di": "^2.13.1",
+ "ray/psr-cache-module": "1.1",
"symfony/cache": "^v5.3",
"symfony/cache-contracts": "^2.4"
},
@@ -72,7 +72,7 @@
"cs": ["./vendor/bin/phpcs"],
"cs-fix": ["./vendor/bin/phpcbf src tests"],
"clean": ["./vendor/bin/phpstan clear-result-cache", "./vendor/bin/psalm --clear-cache", "rm -rf tests/tmp/*.php"],
- "sa": ["./vendor/bin/phpstan analyse -c phpstan.neon", "psalm --show-info=true"],
+ "sa": ["psalm --show-info=true", "./vendor/bin/phpstan analyse -c phpstan.neon"],
"metrics": ["./vendor/bin/phpmetrics --report-html=build/metrics --exclude=Exception --junit=build/junit.xml src"],
"phpmd": ["./vendor/bin/phpmd --exclude src/Annotation src text ./phpmd.xml"],
"build": ["@cs", "@sa", "@pcov", "@metrics"]
diff --git a/phpcs.xml b/phpcs.xml
index 7305bb57..dd74c95d 100755
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -38,6 +38,7 @@
+
diff --git a/src/Php73BcSerializableTrait.php b/src/Php73BcSerializableTrait.php
new file mode 100644
index 00000000..b6d59f95
--- /dev/null
+++ b/src/Php73BcSerializableTrait.php
@@ -0,0 +1,30 @@
+__serialize());
+ }
+
+ /**
+ * @psalm-suppress all
+ *
+ * {@inheritDoc}
+ */
+ final public function unserialize($serializedData)
+ {
+ $array = unserialize($serializedData);
+ $this->__unserialize($array); // @phpstan-ignore-line
+ }
+}
diff --git a/src/ResourceStorage.php b/src/ResourceStorage.php
index 80438863..bdaed086 100644
--- a/src/ResourceStorage.php
+++ b/src/ResourceStorage.php
@@ -4,7 +4,6 @@
namespace BEAR\QueryRepository;
-use BEAR\QueryRepository\SerializableTagAwareAdapter as TagAwareAdapter;
use BEAR\RepositoryModule\Annotation\EtagPool;
use BEAR\RepositoryModule\Annotation\KnownTagTtl;
use BEAR\Resource\AbstractUri;
@@ -13,8 +12,10 @@
use Doctrine\Common\Cache\CacheProvider;
use Psr\Cache\CacheItemPoolInterface;
use Ray\PsrCacheModule\Annotation\Shared;
+use Serializable;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
+use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Contracts\Cache\ItemInterface;
use function array_merge;
@@ -27,8 +28,10 @@
use function sprintf;
use function strtoupper;
-final class ResourceStorage implements ResourceStorageInterface
+final class ResourceStorage implements ResourceStorageInterface, Serializable
{
+ use ResourceStorageCacheableTrait;
+
/**
* Resource object cache prefix
*/
@@ -57,6 +60,9 @@ final class ResourceStorage implements ResourceStorageInterface
/** @var ResourceStorageSaver */
private $saver;
+ /** @var float */
+ private $knownTagTtl;
+
/**
* @Shared("pool")
* @EtagPool("etagPool")
@@ -82,6 +88,7 @@ public function __construct(
return;
}
+ $this->knownTagTtl = $knownTagTtl;
assert($pool instanceof AdapterInterface);
$etagPool = $etagPool instanceof AdapterInterface ? $etagPool : $pool;
$this->roPool = new TagAwareAdapter($pool, $etagPool, $knownTagTtl);
diff --git a/src/ResourceStorageCacheableTrait.php b/src/ResourceStorageCacheableTrait.php
new file mode 100644
index 00000000..d81ad933
--- /dev/null
+++ b/src/ResourceStorageCacheableTrait.php
@@ -0,0 +1,69 @@
+injector = $injector;
+ }
+
+ /**
+ * @return array{logger: RepositoryLoggerInterface, purger: PurgerInterface, uriTag: UriTagInterface, saver: ResourceStorageSaver, knownTagTtl: float, injector: InjectorInterface}
+ */
+ final public function __serialize(): array
+ {
+ assert($this->injector instanceof InjectorInterface);
+
+ return [
+ 'logger' => $this->logger,
+ 'purger' => $this->purger,
+ 'uriTag' => $this->uriTag,
+ 'saver' => $this->saver,
+ 'knownTagTtl' => $this->knownTagTtl,
+ 'injector' => $this->injector,
+ ];
+ }
+
+ /**
+ * @param array{logger: RepositoryLoggerInterface, purger: PurgerInterface, uriTag: UriTagInterface, saver: ResourceStorageSaver, knownTagTtl: float, injector: InjectorInterface} $data
+ */
+ final public function __unserialize(array $data): void
+ {
+ $this->logger = $data['logger'];
+ $this->purger = $data['purger'];
+ $this->uriTag = $data['uriTag'];
+ $this->saver = $data['saver'];
+ $pool = $data['injector']->getInstance(CacheItemPoolInterface::class, Shared::class);
+ $etagPool = $data['injector']->getInstance(CacheItemPoolInterface::class, EtagPool::class);
+ assert($pool instanceof AdapterInterface);
+ assert($etagPool instanceof AdapterInterface);
+ $this->roPool = new TagAwareAdapter($pool, $etagPool, $data['knownTagTtl']);
+ $this->etagPool = new TagAwareAdapter($etagPool, $etagPool, $data['knownTagTtl']);
+ }
+}
diff --git a/src/SerializableTagAwareAdapter.php b/src/SerializableTagAwareAdapter.php
deleted file mode 100644
index b7f92bb4..00000000
--- a/src/SerializableTagAwareAdapter.php
+++ /dev/null
@@ -1,47 +0,0 @@
- */
- private $args;
-
- public function __construct(AdapterInterface $itemsPool, ?AdapterInterface $tagsPool = null, float $knownTagVersionsTtl = 0.15)
- {
- $this->args = func_get_args();
- parent::__construct($itemsPool, $tagsPool, $knownTagVersionsTtl);
- }
-
- /**
- * @inheritDoc
- */
- public function serialize()
- {
- return serialize($this->args);
- }
-
- /**
- * @param string $data
- *
- * @inheritDoc
- */
- public function unserialize($data)
- {
- call_user_func_array([$this, '__construct'], unserialize($data)); // @phpstan-ignore-line
- }
-}
diff --git a/tests/Fake/fake-app/src/Resource/App/Value.php b/tests/Fake/fake-app/src/Resource/App/Value.php
index e12970c7..b0184d47 100644
--- a/tests/Fake/fake-app/src/Resource/App/Value.php
+++ b/tests/Fake/fake-app/src/Resource/App/Value.php
@@ -17,7 +17,7 @@ class Value extends ResourceObject
{
public static $i = 1;
- public function toString()
+ public function toString(): string
{
if ($this->view) {
return $this->view;
diff --git a/tests/Fake/fake-app/src/Resource/App/View.php b/tests/Fake/fake-app/src/Resource/App/View.php
index 2bffff98..a2c3835e 100644
--- a/tests/Fake/fake-app/src/Resource/App/View.php
+++ b/tests/Fake/fake-app/src/Resource/App/View.php
@@ -17,7 +17,7 @@ class View extends ResourceObject
{
public static $i = 1;
- public function toString()
+ public function toString(): string
{
if ($this->view) {
return $this->view;
diff --git a/tests/QueryRepositoryTest.php b/tests/QueryRepositoryTest.php
index 323236d6..47189650 100644
--- a/tests/QueryRepositoryTest.php
+++ b/tests/QueryRepositoryTest.php
@@ -4,11 +4,15 @@
namespace BEAR\QueryRepository;
+use BEAR\QueryRepository\QueryRepository as Repository;
+use BEAR\RepositoryModule\Annotation\EtagPool;
use BEAR\Resource\Module\ResourceModule;
use BEAR\Resource\ResourceInterface;
use BEAR\Resource\ResourceObject;
use BEAR\Resource\Uri;
use BEAR\Sunday\Extension\Transfer\HttpCacheInterface;
+use Doctrine\Common\Annotations\AnnotationReader;
+use Doctrine\Common\Annotations\Reader;
use FakeVendor\HelloWorld\Resource\App\NullView;
use FakeVendor\HelloWorld\Resource\App\User\Profile;
use FakeVendor\HelloWorld\Resource\Page\None;
@@ -17,9 +21,12 @@
use Ray\Di\AbstractModule;
use Ray\Di\Injector;
use Ray\PsrCacheModule\Annotation\Shared;
+use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use function assert;
use function is_array;
+use function serialize;
+use function unserialize;
class QueryRepositoryTest extends TestCase
{
@@ -186,4 +193,21 @@ public function testRenderView(): void
$this->repository->put($ro);
$this->assertIsString($ro->view);
}
+
+ public function testSerializable(): void
+ {
+ $namespace = 'FakeVendor\HelloWorld';
+ $module = new QueryRepositoryModule();
+ $module->override(new class extends AbstractModule{
+ protected function configure()
+ {
+ $this->bind(CacheItemPoolInterface::class)->annotatedWith(Shared::class)->to(FilesystemAdapter::class);
+ $this->bind(CacheItemPoolInterface::class)->annotatedWith(EtagPool::class)->to(FilesystemAdapter::class);
+ $this->bind(Reader::class)->to(AnnotationReader::class);
+ }
+ });
+ $repository = (new Injector($module))->getInstance(QueryRepositoryInterface::class);
+ $unserilizedRepository = unserialize(serialize($repository));
+ $this->assertInstanceOf(Repository::class, $unserilizedRepository);
+ }
}
diff --git a/tests/ResourceRepositoryTest.php b/tests/ResourceRepositoryTest.php
index ed966131..a9d6c667 100644
--- a/tests/ResourceRepositoryTest.php
+++ b/tests/ResourceRepositoryTest.php
@@ -14,8 +14,6 @@
use function array_change_key_case;
use function assert;
-use function serialize;
-use function unserialize;
use const CASE_LOWER;
@@ -121,10 +119,4 @@ protected function doGetStats()
);
$this->assertInstanceOf(Repository::class, $repository);
}
-
- public function testSerializable(): void
- {
- $repository = unserialize(serialize($this->repository));
- $this->assertInstanceOf(Repository::class, $repository);
- }
}