Skip to content

Commit

Permalink
Merge pull request #100 from koriym/php8.1-serializable
Browse files Browse the repository at this point in the history
 Fix PHP 8.1 deprecation warnings with unserializable symfony cache component support
  • Loading branch information
koriym committed Nov 6, 2021
2 parents 3a06bdd + 22b6678 commit cc30df2
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 63 deletions.
8 changes: 4 additions & 4 deletions composer.json
Expand Up @@ -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"
},
Expand Down Expand Up @@ -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"]
Expand Down
1 change: 1 addition & 0 deletions phpcs.xml
Expand Up @@ -38,6 +38,7 @@
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint"/>
<exclude name="SlevomatCodingStandard.PHP.RequireExplicitAssertion.RequiredExplicitAssertion"/>
<exclude name="SlevomatCodingStandard.Classes.DisallowLateStaticBindingForConstants.DisallowedLateStaticBindingForConstant"/>
<exclude name="SlevomatCodingStandard.Classes.SuperfluousTraitNaming.SuperfluousSuffix"/>
<!-- /Base -->
<!-- Option -->
<exclude name="SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed"/>
Expand Down
30 changes: 30 additions & 0 deletions src/Php73BcSerializableTrait.php
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace BEAR\QueryRepository;

use function serialize;
use function unserialize;

trait Php73BcSerializableTrait
{
/**
* {@inheritDoc}
*/
final public function serialize()
{
return serialize($this->__serialize());
}

/**
* @psalm-suppress all
*
* {@inheritDoc}
*/
final public function unserialize($serializedData)
{
$array = unserialize($serializedData);
$this->__unserialize($array); // @phpstan-ignore-line
}
}
11 changes: 9 additions & 2 deletions src/ResourceStorage.php
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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
*/
Expand Down Expand Up @@ -57,6 +60,9 @@ final class ResourceStorage implements ResourceStorageInterface
/** @var ResourceStorageSaver */
private $saver;

/** @var float */
private $knownTagTtl;

/**
* @Shared("pool")
* @EtagPool("etagPool")
Expand All @@ -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);
Expand Down
69 changes: 69 additions & 0 deletions src/ResourceStorageCacheableTrait.php
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace BEAR\QueryRepository;

use BEAR\RepositoryModule\Annotation\EtagPool;
use Psr\Cache\CacheItemPoolInterface;
use Ray\Di\Di\Inject;
use Ray\Di\InjectorInterface;
use Ray\PsrCacheModule\Annotation\Shared;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;

use function assert;

trait ResourceStorageCacheableTrait
{
use Php73BcSerializableTrait;

/**
* @var ?InjectorInterface
* @psalm-suppress PropertyNotSetInConstructor
*/
protected $injector;

/**
* @Inject
*/
#[Inject]
final public function setInjector(InjectorInterface $injector): void
{
$this->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']);
}
}
47 changes: 0 additions & 47 deletions src/SerializableTagAwareAdapter.php

This file was deleted.

2 changes: 1 addition & 1 deletion tests/Fake/fake-app/src/Resource/App/Value.php
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion tests/Fake/fake-app/src/Resource/App/View.php
Expand Up @@ -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;
Expand Down
24 changes: 24 additions & 0 deletions tests/QueryRepositoryTest.php
Expand Up @@ -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;
Expand All @@ -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
{
Expand Down Expand Up @@ -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);
}
}
8 changes: 0 additions & 8 deletions tests/ResourceRepositoryTest.php
Expand Up @@ -14,8 +14,6 @@

use function array_change_key_case;
use function assert;
use function serialize;
use function unserialize;

use const CASE_LOWER;

Expand Down Expand Up @@ -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);
}
}

0 comments on commit cc30df2

Please sign in to comment.