diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index aa14250c..1a6e7335 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -9,4 +9,4 @@ jobs: cs: uses: ray-di/.github/.github/workflows/coding-standards.yml@v1 with: - php_version: 8.1 + php_version: 8.3 diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index d2d40406..cb281b49 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -24,8 +24,6 @@ jobs: options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3 strategy: matrix: - php-version: - - 8.0 dependencies: [highest, lowest] os: [ubuntu-latest] include: @@ -34,10 +32,16 @@ jobs: - php-version: 8.1 os: macos-latest - php-version: 8.2 - dependencies: lowest-ignore + dependencies: lowest os: ubuntu-latest - php-version: 8.2 - dependencies: highest-ignore + dependencies: highest + os: ubuntu-latest + - php-version: 8.3 + dependencies: highest + os: ubuntu-latest + - php-version: 8.3 + dependencies: lowest os: ubuntu-latest steps: - name: Checkout diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 19eda0c1..77301974 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -9,5 +9,5 @@ jobs: sa: uses: ray-di/.github/.github/workflows/static-analysis.yml@v1 with: - php_version: 8.1 + php_version: 8.3 has_crc_config: true diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 078f64a8..163a238b 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -6,6 +6,7 @@ tools: php_pdepend: true php_analyzer: true build: + image: default-bionic nodes: analysis: tests: @@ -14,5 +15,6 @@ build: environment: redis: true php: + version: 8.2 pecl_extensions: - redis diff --git a/composer.json b/composer.json index 8640b9b4..34cd6f8c 100644 --- a/composer.json +++ b/composer.json @@ -9,13 +9,13 @@ } ], "require": { - "php": "^8.0", + "php": "^8.1", "bear/fastly-module": "^0.1.1", "bear/resource": "^1.16.1", "bear/sunday": "^1.5", "doctrine/annotations": "^1.8 || ^2.0", "doctrine/cache": "^1.12 || ^2.0", - "mobiledetect/mobiledetectlib": "^2.8 || ^3.74", + "mobiledetect/mobiledetectlib": "^3.74", "psr/cache": "^1.0 || ^2.0 || ^3.0", "ray/aop": "^2.10", "ray/di": "^2.13.1", @@ -33,7 +33,6 @@ "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^9.5.28", "psalm/plugin-phpunit": "^0.18.4", - "psr/log": "^1.1", "ray/object-visual-grapher": "^1.0", "ray/rector-ray": "^1.0", "rector/rector": "^0.14.8", @@ -81,7 +80,7 @@ "coverage": ["php -dzend_extension=xdebug.so -dxdebug.mode=coverage ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage"], "pcov": ["php -dextension=pcov.so -d pcov.enabled=1 ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage --coverage-clover=coverage.xml"], "cs": ["./vendor/bin/phpcs"], - "cs-fix": ["./vendor/bin/phpcbf src tests"], + "cs-fix": ["./vendor/bin/phpcbf src src-annotation tests"], "clean": ["./vendor/bin/phpstan clear-result-cache", "./vendor/bin/psalm --clear-cache", "rm -rf tests/tmp/*.php"], "sa": ["./vendor/bin/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"], diff --git a/phpcs.xml b/phpcs.xml index 03b8bc04..cffad3f1 100755 --- a/phpcs.xml +++ b/phpcs.xml @@ -16,6 +16,7 @@ src + src-annotation tests */tests/tmp/* @@ -25,7 +26,6 @@ */src/*Interface.php - */src/Abstract*.php */src/ResourceObject.php */tests/SurrogateKeysTest.php diff --git a/psalm.xml b/psalm.xml index e1c8ce11..11988020 100644 --- a/psalm.xml +++ b/psalm.xml @@ -5,6 +5,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config https://psalm.dev/schema/config" + findUnusedBaselineEntry="true" + findUnusedCode="false" > diff --git a/rector.php b/rector.php index c0fced81..65fe6cd0 100644 --- a/rector.php +++ b/rector.php @@ -10,6 +10,7 @@ return static function (RectorConfig $rectorConfig): void { $rectorConfig->paths([ __DIR__ . '/src', + __DIR__ . '/src-annotation', __DIR__ . '/tests/*/*Test.php', ]); @@ -18,6 +19,6 @@ $rectorConfig->rule(AnnotationBindingRector::class); // define sets of rules $rectorConfig->sets([ - LevelSetList::UP_TO_PHP_80, + LevelSetList::UP_TO_PHP_81, ]); }; diff --git a/src-annotation/AbstractCacheControl.php b/src-annotation/AbstractCacheControl.php index 3b66538d..7571ba73 100644 --- a/src-annotation/AbstractCacheControl.php +++ b/src-annotation/AbstractCacheControl.php @@ -4,9 +4,9 @@ namespace BEAR\RepositoryModule\Annotation; -use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation; +use Stringable; -abstract class AbstractCacheControl +abstract class AbstractCacheControl implements Stringable { - abstract function __toString(); + abstract function __toString(): string; } diff --git a/src-annotation/AbstractCommand.php b/src-annotation/AbstractCommand.php index edd19484..d9f081b7 100644 --- a/src-annotation/AbstractCommand.php +++ b/src-annotation/AbstractCommand.php @@ -4,17 +4,10 @@ namespace BEAR\RepositoryModule\Annotation; -use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation; - -abstract class AbstractCommand implements NamedArgumentConstructorAnnotation +abstract class AbstractCommand { - /** - * @var string - */ - public $uri = false; - - public function __construct(string $uri) - { - $this->uri = $uri; + public function __construct( + public string $uri, + ) { } } diff --git a/src-annotation/CacheEngine.php b/src-annotation/CacheEngine.php index 54a80c4c..de6b18cf 100644 --- a/src-annotation/CacheEngine.php +++ b/src-annotation/CacheEngine.php @@ -5,24 +5,21 @@ namespace BEAR\RepositoryModule\Annotation; use Attribute; -use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation; +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; use Ray\Di\Di\Qualifier; /** * @Annotation * @Target("METHOD") * @Qualifier() + * @NamedArgumentConstructor() */ -#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_PROPERTY), Qualifier] -final class CacheEngine implements NamedArgumentConstructorAnnotation +#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_PROPERTY)] +#[Qualifier] +final class CacheEngine { - /** - * @var string - */ - public $value; - - public function __construct(string $value) - { - $this->value = $value; + public function __construct( + public string $value, + ) { } } diff --git a/src-annotation/Cacheable.php b/src-annotation/Cacheable.php index 8c7c4bfc..c74e3f71 100644 --- a/src-annotation/Cacheable.php +++ b/src-annotation/Cacheable.php @@ -5,57 +5,28 @@ namespace BEAR\RepositoryModule\Annotation; use Attribute; - use BEAR\QueryRepository\CacheInterceptor; -use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation; -use function is_string; +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; /** * @Annotation * @Target("CLASS") - * * @see CacheInterceptor + * @NamedArgumentConstructor() */ #[Attribute(Attribute::TARGET_CLASS)] -final class Cacheable implements NamedArgumentConstructorAnnotation +final class Cacheable { - /** - * @var 'short'|'medium'|'long'|'never' - * @Enum({"short", "medium", "long", "never"}) - */ - public $expiry; - - /** - * @var int - */ - public $expirySecond; - - /** - * @var string - */ - public $expiryAt; - - /** - * @var bool - */ - public $update; - - /** - * @var 'value'|'view' - * @Enum({"value", "view"}) - */ - public $type; - /** * @param 'short'|'medium'|'long'|'never' $expiry * @param 'value'|'view' $type */ - public function __construct(string $expiry = 'never', int $expirySecond = 0, string $expiryAt = '', bool $update = false, string $type = 'value') - { - $this->expiry = $expiry; - $this->expirySecond = $expirySecond; - $this->expiryAt = $expiryAt; - $this->update = $update; - $this->type = $type; + public function __construct( + public string $expiry = 'never', + public int $expirySecond = 0, + public string $expiryAt = '', + public bool $update = false, + public string $type = 'value', + ) { } } diff --git a/src-annotation/CacheableResponse.php b/src-annotation/CacheableResponse.php index f3f109c9..39055a02 100644 --- a/src-annotation/CacheableResponse.php +++ b/src-annotation/CacheableResponse.php @@ -12,12 +12,11 @@ /** * @Annotation * @Target({"METHOD","CLASS"}) - * * @see DonutCacheModule * @see DonutCacheableResponseInterceptor * @see DonutCommandInterceptor */ -#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_CLASS)] +#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)] final class CacheableResponse { } diff --git a/src-annotation/Commands.php b/src-annotation/Commands.php index ca75c4cd..7dabad70 100644 --- a/src-annotation/Commands.php +++ b/src-annotation/Commands.php @@ -12,7 +12,8 @@ * @Target("METHOD") * @Qualifier */ -#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_PARAMETER) , Qualifier] +#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_PARAMETER)] +#[Qualifier] final class Commands { } diff --git a/src-annotation/DonutCache.php b/src-annotation/DonutCache.php index b7c7a783..2571e0a2 100644 --- a/src-annotation/DonutCache.php +++ b/src-annotation/DonutCache.php @@ -11,12 +11,11 @@ /** * @Annotation * @Target({"METHOD","CLASS"}) - * * @see DonutCacheModule * @see DonutCacheInterceptor * @see DonutCommandInterceptor */ -#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_CLASS)] +#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)] final class DonutCache { } diff --git a/src-annotation/EtagPool.php b/src-annotation/EtagPool.php index ddf0deff..53a28600 100644 --- a/src-annotation/EtagPool.php +++ b/src-annotation/EtagPool.php @@ -13,14 +13,12 @@ * @Qualifier * @NamedArgumentConstructor */ -#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_METHOD), Qualifier] +#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_METHOD)] +#[Qualifier] final class EtagPool { - /** @var string */ - public $value; - - public function __construct(string $value = '') - { - $this->value = $value; + public function __construct( + public string $value = '', + ) { } } diff --git a/src-annotation/HttpCache.php b/src-annotation/HttpCache.php index e489a144..a692c648 100644 --- a/src-annotation/HttpCache.php +++ b/src-annotation/HttpCache.php @@ -6,7 +6,10 @@ use Attribute; use BEAR\QueryRepository\HttpCacheInterceptor; -use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation; +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; + +use function implode; +use function sprintf; /** * HTTP Cache Control @@ -15,120 +18,88 @@ * * @Annotation * @Target("CLASS") - * {@inheritdoc} + * @NamedArgumentConstructor() * + * {@inheritdoc} * @see HttpCacheInterceptor */ #[Attribute(Attribute::TARGET_CLASS)] -final class HttpCache extends AbstractCacheControl implements NamedArgumentConstructorAnnotation +final class HttpCache extends AbstractCacheControl { - /** - * Is private cache - * - * true: Indicates that the response is intended for a single user and must not be stored by a shared cache. A private cache may store the response. - * false: Indicates that the response may be cached by any cache. - * - * @var bool - */ - public $isPrivate = false; - - /** - * No cache without validation - * - * Forces caches to submit the request to the origin server for validation before releasing a cached copy. - * This is *not* no-cache flag. - * - * @var bool - */ - public $noCache = false; - - /** - * No Store - * - * The cache should not store anything about the client request or server response. - * - * @var bool - */ - public $noStore = false; - - /** - * Must revalidate when cache is expired - * - * The cache must verify the status of the stale resources before using it and expired ones should not be used. - * - * @var bool - */ - public $mustRevalidate = false; - - /** - * Max time - * - * Specifies the maximum amount of time a resource will be considered fresh. Contrary to Expires, this directive is relative to the time of the request. - * - * @var int - */ - public $maxAge; - - /** - * Shared cache max time - * - * Takes precedence over max-age or the Expires header, but it only applies to shared caches (e.g., proxies) and is ignored by a private cache. - * - * @var int - */ - public $sMaxAge; - - /** - * Resource body index of Etag - * - * @var array - */ - public $etag = []; - - /** - * @param array $etag - */ + /** @param array $etag */ public function __construct( - bool $isPrivate = false, - bool $noCache = false, - bool $noStore = false, - bool $mustRevalidate = false, - int $maxAge = 0, - int $sMaxAge = 0, - array $etag = [] - ) - { - $this->isPrivate = $isPrivate; - $this->noCache = $noCache; - $this->noStore = $noStore; - $this->mustRevalidate = $mustRevalidate; - $this->maxAge = $maxAge; - $this->sMaxAge = $sMaxAge; - $this->etag = $etag; + /** + * Is private cache + * + * true: Indicates that the response is intended for a single user and must not be stored by a shared cache. A private cache may store the response. + * false: Indicates that the response may be cached by any cache. + */ + public bool $isPrivate = false, + /** + * No cache without validation + * + * Forces caches to submit the request to the origin server for validation before releasing a cached copy. + * This is *not* no-cache flag. + */ + public bool $noCache = false, + /** + * No Store + * + * The cache should not store anything about the client request or server response. + */ + public bool $noStore = false, + /** + * Must revalidate when cache is expired + * + * The cache must verify the status of the stale resources before using it and expired ones should not be used. + */ + public bool $mustRevalidate = false, + /** + * Max time + * + * Specifies the maximum amount of time a resource will be considered fresh. Contrary to Expires, this directive is relative to the time of the request. + */ + public int $maxAge = 0, + /** + * Shared cache max time + * + * Takes precedence over max-age or the Expires header, but it only applies to shared caches (e.g., proxies) and is ignored by a private cache. + */ + public int $sMaxAge = 0, + /** + * Resource body index of Etag + */ + public array $etag = [], + ) { } - public function __toString() + public function __toString(): string { $control = []; if ($this->isPrivate) { $control[] = 'private'; } + if ($this->noCache) { $control[] = 'no-cache'; } + if ($this->noStore) { $control[] = 'no-store'; } + if ($this->mustRevalidate) { $control[] = 'must-revalidate'; } + if ($this->maxAge) { - $control[] = \sprintf('max-age=%d', $this->maxAge); + $control[] = sprintf('max-age=%d', $this->maxAge); } + if ($this->sMaxAge) { - $control[] = \sprintf('s-maxage=%d', $this->sMaxAge); + $control[] = sprintf('s-maxage=%d', $this->sMaxAge); } - return \implode(', ', $control); + return implode(', ', $control); } } diff --git a/src-annotation/KnownTagTtl.php b/src-annotation/KnownTagTtl.php index 5079be57..4c279758 100644 --- a/src-annotation/KnownTagTtl.php +++ b/src-annotation/KnownTagTtl.php @@ -13,14 +13,12 @@ * @Qualifier * @NamedArgumentConstructor */ -#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_METHOD), Qualifier] +#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_METHOD)] +#[Qualifier] final class KnownTagTtl { - /** @var string */ - public $value; - - public function __construct(string $value = '') - { - $this->value = $value; + public function __construct( + public string $value = '', + ) { } } diff --git a/src-annotation/Memcache.php b/src-annotation/Memcache.php index ab62bf80..edf7187f 100644 --- a/src-annotation/Memcache.php +++ b/src-annotation/Memcache.php @@ -5,24 +5,21 @@ namespace BEAR\RepositoryModule\Annotation; use Attribute; -use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation; +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; use Ray\Di\Di\Qualifier; /** * @Annotation * @Target("METHOD") * @Qualifier() + * @NamedArgumentConstructor() */ -#[Attribute(Attribute::TARGET_METHOD), Qualifier] -final class Memcache implements NamedArgumentConstructorAnnotation +#[Attribute(Attribute::TARGET_METHOD)] +#[Qualifier] +final class Memcache { - /** - * @var string - */ - public $value; - - public function __construct(string $value) - { - $this->value = $value; + public function __construct( + public string $value, + ) { } } diff --git a/src-annotation/NoHttpCache.php b/src-annotation/NoHttpCache.php index 971bb5a1..dde82d56 100644 --- a/src-annotation/NoHttpCache.php +++ b/src-annotation/NoHttpCache.php @@ -14,16 +14,12 @@ * * @Annotation * @Target("CLASS") - * * @see HttpCacheInterceptor */ #[Attribute(Attribute::TARGET_CLASS)] final class NoHttpCache extends AbstractCacheControl { - /** - * @return string - */ - public function __toString() + public function __toString(): string { return 'private, no-store, no-cache, must-revalidate'; } diff --git a/src-annotation/Purge.php b/src-annotation/Purge.php index 334d30ef..2dae7d7b 100644 --- a/src-annotation/Purge.php +++ b/src-annotation/Purge.php @@ -5,11 +5,12 @@ namespace BEAR\RepositoryModule\Annotation; use Attribute; +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; /** * @Annotation * @Target("METHOD") - * + * @NamedArgumentConstructor() * @see RefreshInterceptor */ #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] diff --git a/src-annotation/Redis.php b/src-annotation/Redis.php index 024744a0..47a27e40 100644 --- a/src-annotation/Redis.php +++ b/src-annotation/Redis.php @@ -5,18 +5,21 @@ namespace BEAR\RepositoryModule\Annotation; use Attribute; +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; use Ray\Di\Di\Qualifier; /** * @Annotation * @Target("METHOD") * @Qualifier() + * @NamedArgumentConstructor() */ -#[Attribute(Attribute::TARGET_METHOD), Qualifier] +#[Attribute(Attribute::TARGET_METHOD)] +#[Qualifier] final class Redis { - /** - * @var string - */ - public $value; + public function __construct( + public string $value, + ) { + } } diff --git a/src-annotation/Refresh.php b/src-annotation/Refresh.php index 4d32d65b..4a1500ef 100644 --- a/src-annotation/Refresh.php +++ b/src-annotation/Refresh.php @@ -6,11 +6,12 @@ use Attribute; use BEAR\QueryRepository\RefreshInterceptor; +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; /** * @Annotation * @Target("METHOD") - * + * @NamedArgumentConstructor() * @see RefreshInterceptor */ #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] diff --git a/src-annotation/RefreshCache.php b/src-annotation/RefreshCache.php index d7edb979..d9a6a756 100644 --- a/src-annotation/RefreshCache.php +++ b/src-annotation/RefreshCache.php @@ -10,7 +10,6 @@ /** * @Annotation * @Target("METHOD") - * * @see DonutCommandInterceptor */ #[Attribute(Attribute::TARGET_METHOD)] diff --git a/src/AbstractDonutCacheInterceptor.php b/src/AbstractDonutCacheInterceptor.php index 4366cbe6..b30e2bdc 100644 --- a/src/AbstractDonutCacheInterceptor.php +++ b/src/AbstractDonutCacheInterceptor.php @@ -23,7 +23,7 @@ abstract class AbstractDonutCacheInterceptor implements MethodInterceptor protected const IS_ENTIRE_CONTENT_CACHEABLE = false; public function __construct( - private DonutRepositoryInterface $donutRepository, + private readonly DonutRepositoryInterface $donutRepository, ) { } diff --git a/src/CacheDependency.php b/src/CacheDependency.php index fda280af..d758bff4 100644 --- a/src/CacheDependency.php +++ b/src/CacheDependency.php @@ -12,7 +12,7 @@ final class CacheDependency implements CacheDependencyInterface { public function __construct( - private UriTagInterface $uriTag, + private readonly UriTagInterface $uriTag, ) { } diff --git a/src/CacheInterceptor.php b/src/CacheInterceptor.php index 84206758..843d360c 100644 --- a/src/CacheInterceptor.php +++ b/src/CacheInterceptor.php @@ -19,7 +19,7 @@ final class CacheInterceptor implements MethodInterceptor { public function __construct( - private QueryRepositoryInterface $repository, + private readonly QueryRepositoryInterface $repository, ) { } diff --git a/src/CacheVersionModule.php b/src/CacheVersionModule.php index ed67cc7e..31f4439d 100644 --- a/src/CacheVersionModule.php +++ b/src/CacheVersionModule.php @@ -17,7 +17,7 @@ final class CacheVersionModule extends AbstractModule { public function __construct( - private string $version, + private readonly string $version, AbstractModule|null $module = null, ) { parent::__construct($module); diff --git a/src/Cdn/FastlyCachePurger.php b/src/Cdn/FastlyCachePurger.php index 06538772..072f2e3e 100644 --- a/src/Cdn/FastlyCachePurger.php +++ b/src/Cdn/FastlyCachePurger.php @@ -9,7 +9,7 @@ final class FastlyCachePurger implements PurgerInterface { - public function __construct(private FastlyCachePurgerInterface $fastlyCachePurger) + public function __construct(private readonly FastlyCachePurgerInterface $fastlyCachePurger) { } diff --git a/src/Cdn/FastlyModule.php b/src/Cdn/FastlyModule.php index 4ab13c73..f729733d 100644 --- a/src/Cdn/FastlyModule.php +++ b/src/Cdn/FastlyModule.php @@ -12,8 +12,8 @@ final class FastlyModule extends AbstractModule { public function __construct( - private string $fastlyApiKey, - private string $fastlyServiceId, + private readonly string $fastlyApiKey, + private readonly string $fastlyServiceId, AbstractModule|null $module = null, ) { parent::__construct($module); diff --git a/src/CliHttpCache.php b/src/CliHttpCache.php index b1be5e2b..ae2ced27 100644 --- a/src/CliHttpCache.php +++ b/src/CliHttpCache.php @@ -18,7 +18,7 @@ final class CliHttpCache implements HttpCacheInterface { public function __construct( - private ResourceStorageInterface $storage, + private readonly ResourceStorageInterface $storage, ) { } diff --git a/src/CommandInterceptor.php b/src/CommandInterceptor.php index f998c9ad..69f3e913 100644 --- a/src/CommandInterceptor.php +++ b/src/CommandInterceptor.php @@ -16,7 +16,7 @@ final class CommandInterceptor implements MethodInterceptor /** @param CommandInterface[] $commands */ public function __construct( #[Commands] - private array $commands, + private readonly array $commands, ) { } diff --git a/src/CommandsProvider.php b/src/CommandsProvider.php index 66cd22c7..5659d33b 100644 --- a/src/CommandsProvider.php +++ b/src/CommandsProvider.php @@ -11,8 +11,8 @@ final class CommandsProvider implements ProviderInterface { public function __construct( - private QueryRepositoryInterface $repository, - private ResourceInterface $resource, + private readonly QueryRepositoryInterface $repository, + private readonly ResourceInterface $resource, ) { } diff --git a/src/DevEtagSetter.php b/src/DevEtagSetter.php index fa7e8451..e26fb5d5 100644 --- a/src/DevEtagSetter.php +++ b/src/DevEtagSetter.php @@ -17,7 +17,7 @@ final class DevEtagSetter implements EtagSetterInterface { public function __construct( - private CacheDependencyInterface $cacheDeperency, + private readonly CacheDependencyInterface $cacheDeperency, ) { } diff --git a/src/DonutCommandInterceptor.php b/src/DonutCommandInterceptor.php index fca47dc4..9043792f 100644 --- a/src/DonutCommandInterceptor.php +++ b/src/DonutCommandInterceptor.php @@ -22,8 +22,8 @@ final class DonutCommandInterceptor implements MethodInterceptor { public function __construct( - private DonutRepositoryInterface $repository, - private MatchQueryInterface $matchQuery + private readonly DonutRepositoryInterface $repository, + private readonly MatchQueryInterface $matchQuery ){ } diff --git a/src/DonutRepository.php b/src/DonutRepository.php index 165a7ede..d20c4ed5 100644 --- a/src/DonutRepository.php +++ b/src/DonutRepository.php @@ -14,13 +14,13 @@ final class DonutRepository implements DonutRepositoryInterface { public function __construct( - private QueryRepositoryInterface $queryRepository, - private HeaderSetter $headerSetter, - private ResourceStorageInterface $resourceStorage, - private ResourceInterface $resource, - private CdnCacheControlHeaderSetterInterface $cdnCacheControlHeaderSetter, - private RepositoryLoggerInterface $logger, - private DonutRendererInterface $renderer, + private readonly QueryRepositoryInterface $queryRepository, + private readonly HeaderSetter $headerSetter, + private readonly ResourceStorageInterface $resourceStorage, + private readonly ResourceInterface $resource, + private readonly CdnCacheControlHeaderSetterInterface $cdnCacheControlHeaderSetter, + private readonly RepositoryLoggerInterface $logger, + private readonly DonutRendererInterface $renderer, ) { } diff --git a/src/DonutRequest.php b/src/DonutRequest.php index 5949589f..7ecdac09 100644 --- a/src/DonutRequest.php +++ b/src/DonutRequest.php @@ -12,9 +12,9 @@ final class DonutRequest implements Stringable { public function __construct( - private AbstractRequest $request, - private DonutRendererInterface $donutStorage, - private SurrogateKeys $etags, + private readonly AbstractRequest $request, + private readonly DonutRendererInterface $donutStorage, + private readonly SurrogateKeys $etags, ) { } diff --git a/src/EtagSetter.php b/src/EtagSetter.php index 8c9cc930..7cf3ab57 100644 --- a/src/EtagSetter.php +++ b/src/EtagSetter.php @@ -19,7 +19,7 @@ final class EtagSetter implements EtagSetterInterface { public function __construct( - private CacheDependencyInterface $cacheDeperency, + private readonly CacheDependencyInterface $cacheDeperency, ) { } diff --git a/src/Expiry.php b/src/Expiry.php index 3d880dc0..8386f48c 100644 --- a/src/Expiry.php +++ b/src/Expiry.php @@ -7,7 +7,7 @@ final class Expiry { /** @var array */ - private array $time; + private readonly array $time; public function __construct(int $short = 60, int $medium = 3600, int $long = 86400, int $never = 31_536_000) { diff --git a/src/HeaderSetter.php b/src/HeaderSetter.php index 5ef514df..1826d616 100644 --- a/src/HeaderSetter.php +++ b/src/HeaderSetter.php @@ -14,7 +14,7 @@ final class HeaderSetter { public function __construct( - private EtagSetterInterface $etagSetter, + private readonly EtagSetterInterface $etagSetter, ) { } diff --git a/src/HttpCache.php b/src/HttpCache.php index b96fadfb..ee61e01b 100644 --- a/src/HttpCache.php +++ b/src/HttpCache.php @@ -13,7 +13,7 @@ final class HttpCache implements HttpCacheInterface, DeprecatedHttpCacheInterface { public function __construct( - private ResourceStorageInterface $storage, + private readonly ResourceStorageInterface $storage, ) { } @@ -32,6 +32,8 @@ public function isNotModified(array $server): bool */ public function transfer() { + // @codeCoverageIgnoreStart http_response_code(304); + // @codeCoverageIgnoreEnd } } diff --git a/src/MobileEtagSetter.php b/src/MobileEtagSetter.php index e1be4a8e..f94c3174 100644 --- a/src/MobileEtagSetter.php +++ b/src/MobileEtagSetter.php @@ -6,7 +6,7 @@ use BEAR\RepositoryModule\Annotation\HttpCache; use BEAR\Resource\ResourceObject; -use Mobile_Detect; +use Detection\MobileDetect; use function crc32; use function gmdate; @@ -30,7 +30,7 @@ public function __invoke(ResourceObject $ro, int|null $time = null, HttpCache|nu */ private function getDevice(): string { - $detect = new Mobile_Detect(); + $detect = new MobileDetect(); return $detect->isMobile() && ! $detect->isTablet() ? 'mobile' : 'pc'; } diff --git a/src/QueryRepository.php b/src/QueryRepository.php index 973a5918..03896659 100644 --- a/src/QueryRepository.php +++ b/src/QueryRepository.php @@ -20,11 +20,11 @@ final class QueryRepository implements QueryRepositoryInterface { public function __construct( - private RepositoryLoggerInterface $logger, - private HeaderSetter $headerSetter, - private ResourceStorageInterface $storage, - private Reader $reader, - private Expiry $expiry, + private readonly RepositoryLoggerInterface $logger, + private readonly HeaderSetter $headerSetter, + private readonly ResourceStorageInterface $storage, + private readonly Reader $reader, + private readonly Expiry $expiry, ) { } diff --git a/src/RefreshAnnotatedCommand.php b/src/RefreshAnnotatedCommand.php index 7063bd66..3895a3bb 100644 --- a/src/RefreshAnnotatedCommand.php +++ b/src/RefreshAnnotatedCommand.php @@ -18,8 +18,8 @@ final class RefreshAnnotatedCommand implements CommandInterface { public function __construct( - private QueryRepositoryInterface $repository, - private ResourceInterface $resource, + private readonly QueryRepositoryInterface $repository, + private readonly ResourceInterface $resource, ) { } diff --git a/src/RefreshInterceptor.php b/src/RefreshInterceptor.php index 9699e684..38421ce7 100644 --- a/src/RefreshInterceptor.php +++ b/src/RefreshInterceptor.php @@ -13,7 +13,7 @@ final class RefreshInterceptor implements MethodInterceptor { public function __construct( - private RefreshAnnotatedCommand $command, + private readonly RefreshAnnotatedCommand $command, ) { } diff --git a/src/RefreshSameCommand.php b/src/RefreshSameCommand.php index b80d2072..7a2a2ce3 100644 --- a/src/RefreshSameCommand.php +++ b/src/RefreshSameCommand.php @@ -14,8 +14,8 @@ final class RefreshSameCommand implements CommandInterface { public function __construct( - private QueryRepositoryInterface $repository, - private MatchQueryInterface $matchQuery + private readonly QueryRepositoryInterface $repository, + private readonly MatchQueryInterface $matchQuery ){ } diff --git a/src/ResourceDonut.php b/src/ResourceDonut.php index f095b841..c20e8d47 100644 --- a/src/ResourceDonut.php +++ b/src/ResourceDonut.php @@ -24,8 +24,8 @@ final class ResourceDonut /** @param array $headers */ public function __construct( - private string $template, - private array $headers, + private readonly string $template, + private readonly array $headers, /** @readonly */ public int|null $ttl, /** @readonly */ diff --git a/src/StorageExpiryModule.php b/src/StorageExpiryModule.php index b4698968..14b01431 100644 --- a/src/StorageExpiryModule.php +++ b/src/StorageExpiryModule.php @@ -9,9 +9,9 @@ final class StorageExpiryModule extends AbstractModule { public function __construct( - private int $short, - private int $medium, - private int $long, + private readonly int $short, + private readonly int $medium, + private readonly int $long, AbstractModule|null $module = null, ) { parent::__construct($module); diff --git a/src/StorageMemcachedModule.php b/src/StorageMemcachedModule.php index af837325..4dc7d0d5 100644 --- a/src/StorageMemcachedModule.php +++ b/src/StorageMemcachedModule.php @@ -15,7 +15,7 @@ final class StorageMemcachedModule extends AbstractModule { /** @param string $servers 'mem1.domain.com:11211:33,mem2.domain.com:11211:67' {host}:{port}:{weight} */ public function __construct( - private string $servers, + private readonly string $servers, AbstractModule|null $module = null, ) { parent::__construct($module); diff --git a/src/StorageRedisMemcachedModule.php b/src/StorageRedisMemcachedModule.php index 21a285bf..3330b7a1 100644 --- a/src/StorageRedisMemcachedModule.php +++ b/src/StorageRedisMemcachedModule.php @@ -23,11 +23,11 @@ final class StorageRedisMemcachedModule extends AbstractModule { /** @var list> */ - private array $memcacheServer; + private readonly array $memcacheServer; /** @param string $redisServer 'localhost:6379' {host}:{port} */ public function __construct( - private string $redisServer, + private readonly string $redisServer, string $memcacheServer, AbstractModule|null $module = null, ) { diff --git a/src/StorageRedisModule.php b/src/StorageRedisModule.php index 54c45c1f..1bedb226 100644 --- a/src/StorageRedisModule.php +++ b/src/StorageRedisModule.php @@ -26,7 +26,7 @@ final class StorageRedisModule extends AbstractModule { /** @param string $server 'localhost:6379' {host}:{port} */ public function __construct( - private string $server, + private readonly string $server, AbstractModule|null $module = null, ) { parent::__construct($module); diff --git a/src/SurrogateKeys.php b/src/SurrogateKeys.php index dad4177a..eff2dbcd 100644 --- a/src/SurrogateKeys.php +++ b/src/SurrogateKeys.php @@ -20,7 +20,7 @@ final class SurrogateKeys { /** @var list */ private array $surrogateKeys; - private UriTagInterface $uriTag; + private readonly UriTagInterface $uriTag; public function __construct(AbstractUri $uri) { diff --git a/test-deprecated/StorageApcModuleTest.php b/tests-deprecated/StorageApcModuleTest.php similarity index 100% rename from test-deprecated/StorageApcModuleTest.php rename to tests-deprecated/StorageApcModuleTest.php diff --git a/tests/DonutCommandInterceptorTest.php b/tests/DonutCommandInterceptorTest.php index b2a47528..97dc3e40 100644 --- a/tests/DonutCommandInterceptorTest.php +++ b/tests/DonutCommandInterceptorTest.php @@ -11,7 +11,6 @@ use PHPUnit\Framework\TestCase; use Ray\Di\Injector; -use function array_key_exists; use function array_map; use function assert; use function dirname; @@ -82,10 +81,9 @@ public function testCommandInterceptorRefreshOnErrorCode(): void public function testCacheableResponse(): void { $ro = $this->resource->get('page://self/html/blog-posting-cache?id=0'); - assert(property_exists($ro, 'bindings')); - assert(array_key_exists('onGet', $ro->bindings)); - $interceptors = array_map(static fn (object $object): string => $object::class, $ro->bindings['onGet']); + $interceptors = array_map(static fn (object $object): string => $object::class, $ro->bindings['onGet']); // @phpstan-ignore-line $this->assertContains(DonutCacheInterceptor::class, $interceptors); + assert(property_exists($ro, 'bindings')); assert(isset($ro->bindings['onGet'][0])); assert(isset($ro->bindings['onDelete'][0])); $this->assertInstanceOf(DonutCacheInterceptor::class, $ro->bindings['onDelete'][0]); diff --git a/tests/DonutRequestTest.php b/tests/DonutRequestTest.php index 6386934c..547fb9bc 100644 --- a/tests/DonutRequestTest.php +++ b/tests/DonutRequestTest.php @@ -5,18 +5,19 @@ namespace BEAR\QueryRepository; use BEAR\Resource\AbstractRequest; +use BEAR\Resource\Resource; use BEAR\Resource\ResourceInterface; use BEAR\Resource\Uri; use Madapaja\TwigModule\TwigModule; use PHPUnit\Framework\TestCase; use Ray\Di\Injector; +use function assert; use function dirname; class DonutRequestTest extends TestCase { private AbstractRequest $request; - private ResourceInterface $resource; protected function setUp(): void { @@ -25,9 +26,10 @@ protected function setUp(): void $path = dirname(__DIR__) . '/tests/Fake/fake-app/var/templates'; $module->override(new TwigModule([$path])); $injector = new Injector($module, $_ENV['TMP_DIR']); - $this->resource = $injector->getInstance(ResourceInterface::class); - /** @var AbstractRequest $request */ - $request = $this->resource->get->uri('page://self/html/comment'); + /** @var Resource $resource */ + $resource = $injector->getInstance(ResourceInterface::class); + $request = $resource->get->uri('page://self/html/comment'); + assert($request instanceof AbstractRequest); $this->request = $request; parent::setUp(); diff --git a/tests/Fake/FakeMobileEtagSetter.php b/tests/Fake/FakeMobileEtagSetter.php index f76b9c77..495e1859 100644 --- a/tests/Fake/FakeMobileEtagSetter.php +++ b/tests/Fake/FakeMobileEtagSetter.php @@ -8,6 +8,7 @@ use BEAR\RepositoryModule\Annotation\HttpCache; use BEAR\Resource\ResourceObject; +use Detection\MobileDetect; class FakeMobileEtagSetter implements EtagSetterInterface { @@ -27,7 +28,7 @@ public function __invoke(ResourceObject $ro, int $time = null, HttpCache $httpCa private function getDevice() { - $detect = new \Mobile_Detect; + $detect = new MobileDetect(); return $detect->isMobile() && ! $detect->isTablet() ? 'mobile' : 'pc'; } diff --git a/tests/HttpCacheTest.php b/tests/HttpCacheTest.php index 3da5c41b..de679d12 100644 --- a/tests/HttpCacheTest.php +++ b/tests/HttpCacheTest.php @@ -11,7 +11,6 @@ use Symfony\Component\Cache\Adapter\ArrayAdapter; use function assert; -use function http_response_code; class HttpCacheTest extends TestCase { @@ -45,17 +44,6 @@ public function testCliHttpCacheTransfer(CliHttpCache $httpCache): void $httpCache->transfer(); } - /** - * @depends testisNotModifiedTrue - * @covers \BEAR\QueryRepository\HttpCache::transfer - */ - public function testHttpCacheTransfer(): void - { - $httpCache = new HttpCache(new ResourceStorage(new RepositoryLogger(), new NullPurger(), new UriTag(), new ArrayAdapter())); - $httpCache->transfer(); - $this->assertSame(304, http_response_code()); - } - /** @depends testisNotModifiedTrue */ public function testHeaderSetInCli(): void {