Skip to content

Commit

Permalink
Merge pull request #99 from koriym/refactor
Browse files Browse the repository at this point in the history
Bump phpstan to 1.0.2
  • Loading branch information
koriym committed Nov 4, 2021
2 parents b4c47dc + a43170b commit 3a06bdd
Show file tree
Hide file tree
Showing 45 changed files with 279 additions and 217 deletions.
18 changes: 18 additions & 0 deletions .scrutinizer.yml
@@ -0,0 +1,18 @@
filter:
paths: ["src/*"]

tools:
php_sim: true
php_pdepend: true
php_analyzer: true
build:
nodes:
analysis:
tests:
override:
- php-scrutinizer-run --enable-security-analysis
environment:
redis: true
php:
pecl_extensions:
- redis
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -6,7 +6,7 @@

[CQRS](http://martinfowler.com/bliki/CQRS.html) inspired **BEAR.QueryRepository** segregates reads and writes into two separate repository.

Documentation is available at [BEAR.Sunday resource manual](http://bearsunday.github.io/manuals/1.0/en/resource.html).
Documentation is available at [BEAR.Sunday cache manual](http://bearsunday.github.io/manuals/1.0/ja/cache.html).


## Demo
Expand Down
Binary file removed dump.rdb
Binary file not shown.
16 changes: 11 additions & 5 deletions phpcs.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<ruleset
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="bearcs"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Ray.Aop coding standard"
xsi:noNamespaceSchemaLocation="./vendor-bin/tools/vendor/squizlabs/php_codesniffer/phpcs.xsd">

<arg name="basepath" value="."/>
<arg name="extensions" value="php"/>
Expand Down Expand Up @@ -41,11 +41,8 @@
<!-- /Base -->
<!-- Option -->
<exclude name="SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed"/>
<!-- attribute -->
<exclude name="Squiz.WhiteSpace.FunctionSpacing.Before"/>
<!-- /Option -->
<!-- Exclude Fake files form Doctrine CS -->
<exclude-pattern>*/tests/Fake/*</exclude-pattern>
</rule>

<!-- Additional Rules -->
Expand All @@ -58,6 +55,15 @@
</property>
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Commenting.DocCommentSpacing">
<properties>
<property name="annotationsGroups" type="array">
<element value="@param, @psalm-param, @phpstan-param"/>
<element value="@return, @psalm-return, @phpstan-return"/>
<element value="@throws"/>
</property>
</properties>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint">
<include-pattern>tests/*</include-pattern>
</rule>
Expand Down
6 changes: 4 additions & 2 deletions phpstan.neon
Expand Up @@ -14,11 +14,13 @@ parameters:
paths:
- src
- tests
excludes_analyse:
excludePaths:
- */tests/tmp/*
- */tests/Fake/*
- */src/StorageRedisCacheProvider.php*
ignoreErrors:
-
message: '#but return statement is missing#'
path: tests/ResourceRepositoryTest.php
path: tests/ResourceRepositoryTest.php
stubFiles:
- tests/stubs/Injector.phpstub
68 changes: 68 additions & 0 deletions src/AbstractDonutCacheInterceptor.php
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace BEAR\QueryRepository;

use BEAR\Resource\ResourceObject;
use Ray\Aop\MethodInterceptor;
use Ray\Aop\MethodInvocation;
use Throwable;

use function assert;
use function get_class;
use function sprintf;
use function trigger_error;

use const E_USER_WARNING;

abstract class AbstractDonutCacheInterceptor implements MethodInterceptor
{
protected const IS_ENTIRE_CONTENT_CACHEABLE = false;

/** @var DonutRepositoryInterface */
private $donutRepository;

public function __construct(DonutRepositoryInterface $donutRepository)
{
$this->donutRepository = $donutRepository;
}

/**
* {@inheritdoc}
*/
final public function invoke(MethodInvocation $invocation)
{
$ro = $invocation->getThis();
assert($ro instanceof ResourceObject);
try {
$maybeRo = $this->donutRepository->get($ro);
if ($maybeRo instanceof ResourceObject) {
return $maybeRo;
}
} catch (Throwable $e) { // @codeCoverageIgnoreStart
// when cache server is down
$this->triggerWarning($e);

return $invocation->proceed(); // @codeCoverageIgnoreStartEnd
}

/** @var ResourceObject $ro */
$ro = $invocation->proceed();
if (isset($ro->headers[Header::ETAG])) {
return $ro; // donut created in ResourceObject
}

return static::IS_ENTIRE_CONTENT_CACHEABLE ?
$this->donutRepository->putStatic($ro, null, null) :
$this->donutRepository->putDonut($ro, null);
}

/**
* @codeCoverageIgnore
*/
private function triggerWarning(Throwable $e): void
{
trigger_error(sprintf('%s: %s in %s:%s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), E_USER_WARNING);
}
}
6 changes: 3 additions & 3 deletions src/CacheDependency.php
Expand Up @@ -23,12 +23,12 @@ public function depends(ResourceObject $from, ResourceObject $to): void
{
assert(! isset($from->headers[Header::SURROGATE_KEY]));

$cacheDepedencyTags = ($this->uriTag)($to->uri);
$cacheDependencyTags = ($this->uriTag)($to->uri);
if (isset($to->headers[Header::SURROGATE_KEY])) {
$cacheDepedencyTags .= sprintf(' %s', $to->headers[Header::SURROGATE_KEY]);
$cacheDependencyTags .= sprintf(' %s', $to->headers[Header::SURROGATE_KEY]);
unset($to->headers[Header::SURROGATE_KEY]);
}

$from->headers[Header::SURROGATE_KEY] = $cacheDepedencyTags;
$from->headers[Header::SURROGATE_KEY] = $cacheDependencyTags;
}
}
2 changes: 1 addition & 1 deletion src/CacheInterceptor.php
Expand Up @@ -17,7 +17,7 @@

use const E_USER_WARNING;

class CacheInterceptor implements MethodInterceptor
final class CacheInterceptor implements MethodInterceptor
{
/** @var QueryRepositoryInterface */
private $repository;
Expand Down
4 changes: 2 additions & 2 deletions src/CacheVersionModule.php
Expand Up @@ -7,7 +7,7 @@
use Ray\Di\AbstractModule;
use Ray\PsrCacheModule\CacheNamespaceModule;

class CacheVersionModule extends AbstractModule
final class CacheVersionModule extends AbstractModule
{
/** @var string */
private $version;
Expand All @@ -21,7 +21,7 @@ public function __construct(string $cacheVersion, ?AbstractModule $module = null
/**
* {@inheritdoc}
*/
protected function configure()
protected function configure(): void
{
$this->install(new CacheNamespaceModule($this->version));
}
Expand Down
4 changes: 2 additions & 2 deletions src/CacheableModule.php
Expand Up @@ -12,12 +12,12 @@
use BEAR\Sunday\Extension\Transfer\HttpCacheInterface;
use Ray\Di\AbstractModule;

class CacheableModule extends AbstractModule
final class CacheableModule extends AbstractModule
{
/**
* {@inheritdoc}
*/
protected function configure()
protected function configure(): void
{
$this->bind(HttpCacheInterface::class)->to(HttpCache::class);
$this->bind()->annotatedWith(Commands::class)->toProvider(CommandsProvider::class);
Expand Down
4 changes: 2 additions & 2 deletions src/Cdn/AkamaiModule.php
Expand Up @@ -12,12 +12,12 @@
* @see https://www.akamai.com/blog/news/targeted-cache-control for Akamai-Cache-Control
* @see https://techdocs.akamai.com/purge-cache/reference/api for purge API
*/
class AkamaiModule extends AbstractModule
final class AkamaiModule extends AbstractModule
{
/**
* {@inheritdoc}
*/
protected function configure()
protected function configure(): void
{
$this->bind(CdnCacheControlHeaderSetterInterface::class)->to(AkamaiCacheControlHeaderSetter::class);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Cdn/FastlyModule.php
Expand Up @@ -7,12 +7,12 @@
use BEAR\QueryRepository\CdnCacheControlHeaderSetterInterface;
use Ray\Di\AbstractModule;

class FastlyModule extends AbstractModule
final class FastlyModule extends AbstractModule
{
/**
* {@inheritdoc}
*/
protected function configure()
protected function configure(): void
{
$this->bind(CdnCacheControlHeaderSetterInterface::class)->to(FastlyCacheControlHeaderSetter::class);
}
Expand Down
13 changes: 9 additions & 4 deletions src/CliHttpCache.php
Expand Up @@ -74,14 +74,19 @@ private function getServerKey(string $key): string
*/
private function getEtag(array $server): ?string
{
$hasRequestHeaderInCli = isset($server['argc']) && $server['argc'] === 4 && isset($server['argv'][3]);
/** @psalm-suppress MixedAssignment */
$arg3 = $server['argv'][3] ?? ''; // @phpstan-ignore-line
assert(is_string($arg3));
$hasRequestHeaderInCli = isset($server['argc']) && $server['argc'] === 4 && $arg3;
if ($hasRequestHeaderInCli) {
/** @psalm-suppress MixedArrayAccess */
$server = $this->getServer((string) $server['argv'][3]);
$server = $this->getServer($arg3);
}

$hasValidEtag = isset($server[Header::HTTP_IF_NONE_MATCH]) && is_string($server[Header::HTTP_IF_NONE_MATCH]);
if (isset($server[Header::HTTP_IF_NONE_MATCH]) && is_string($server[Header::HTTP_IF_NONE_MATCH])) {
return $server[Header::HTTP_IF_NONE_MATCH];
}

return $hasValidEtag ? $server[Header::HTTP_IF_NONE_MATCH] : null;
return null;
}
}
2 changes: 1 addition & 1 deletion src/CommandInterceptor.php
Expand Up @@ -13,7 +13,7 @@

use function get_class;

class CommandInterceptor implements MethodInterceptor
final class CommandInterceptor implements MethodInterceptor
{
/** @var CommandInterface[] */
private $commands = [];
Expand Down
2 changes: 1 addition & 1 deletion src/CommandsProvider.php
Expand Up @@ -7,7 +7,7 @@
use BEAR\Resource\ResourceInterface;
use Ray\Di\ProviderInterface;

class CommandsProvider implements ProviderInterface
final class CommandsProvider implements ProviderInterface
{
/** @var QueryRepositoryInterface */
private $repository;
Expand Down
2 changes: 1 addition & 1 deletion src/DevEtagModule.php
Expand Up @@ -6,7 +6,7 @@

use Ray\Di\AbstractModule;

class DevEtagModule extends AbstractModule
final class DevEtagModule extends AbstractModule
{
/**
* {@inheritdoc}
Expand Down
63 changes: 2 additions & 61 deletions src/DonutCacheInterceptor.php
Expand Up @@ -4,66 +4,7 @@

namespace BEAR\QueryRepository;

use BEAR\Resource\ResourceObject;
use Ray\Aop\MethodInterceptor;
use Ray\Aop\MethodInvocation;
use Throwable;

use function assert;
use function get_class;
use function sprintf;
use function trigger_error;

use const E_USER_WARNING;

class DonutCacheInterceptor implements MethodInterceptor
final class DonutCacheInterceptor extends AbstractDonutCacheInterceptor
{
private const IS_ENTIRE_CONTENT_CACHEABLE = false;

/** @var DonutRepositoryInterface */
private $donutRepository;


public function __construct(DonutRepositoryInterface $donutRepository)
{
$this->donutRepository = $donutRepository;
}

/**
* {@inheritdoc}
*/
public function invoke(MethodInvocation $invocation)
{
$ro = $invocation->getThis();
assert($ro instanceof ResourceObject);
try {
$maybeRo = $this->donutRepository->get($ro);
if ($maybeRo instanceof ResourceObject) {
return $maybeRo;
}
} catch (Throwable $e) { // @codeCoverageIgnoreStart
// when cache server is down
$this->triggerWarning($e);

return $invocation->proceed(); // @codeCoverageIgnoreStartEnd
}

/** @var ResourceObject $ro */
$ro = $invocation->proceed();
if (isset($ro->headers[Header::ETAG])) {
return $ro; // donut created in ResourceObject
}

return static::IS_ENTIRE_CONTENT_CACHEABLE ?
$this->donutRepository->putStatic($ro, null, null) :
$this->donutRepository->putDonut($ro, null);
}

/**
* @codeCoverageIgnore
*/
private function triggerWarning(Throwable $e): void
{
trigger_error(sprintf('%s: %s in %s:%s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), E_USER_WARNING);
}
protected const IS_ENTIRE_CONTENT_CACHEABLE = false;
}
4 changes: 2 additions & 2 deletions src/DonutCacheModule.php
Expand Up @@ -10,12 +10,12 @@
use Ray\Di\AbstractModule;
use Ray\Di\Scope;

class DonutCacheModule extends AbstractModule
final class DonutCacheModule extends AbstractModule
{
/**
* {@inheritdoc}
*/
protected function configure()
protected function configure(): void
{
$this->bind(HeaderSetter::class);
$this->bind(CdnCacheControlHeaderSetterInterface::class)->to(CdnCacheControlHeaderSetter::class);
Expand Down
2 changes: 1 addition & 1 deletion src/DonutCacheableResponseInterceptor.php
Expand Up @@ -4,7 +4,7 @@

namespace BEAR\QueryRepository;

final class DonutCacheableResponseInterceptor extends DonutCacheInterceptor
final class DonutCacheableResponseInterceptor extends AbstractDonutCacheInterceptor
{
protected const IS_ENTIRE_CONTENT_CACHEABLE = true;
}
2 changes: 1 addition & 1 deletion src/DonutCommandInterceptor.php
Expand Up @@ -18,7 +18,7 @@
use function is_callable;
use function sprintf;

class DonutCommandInterceptor implements MethodInterceptor
final class DonutCommandInterceptor implements MethodInterceptor
{
/** @var DonutRepositoryInterface */
private $repository;
Expand Down

0 comments on commit 3a06bdd

Please sign in to comment.