AbstractDonutCacheInterceptor::invoke()   A
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 16
c 2
b 0
f 0
nc 5
nop 1
dl 0
loc 27
rs 9.1111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\QueryRepository;
6
7
use BEAR\Resource\Code;
8
use BEAR\Resource\ResourceObject;
9
use Override;
10
use Ray\Aop\MethodInterceptor;
11
use Ray\Aop\MethodInvocation;
12
use Throwable;
13
14
use function assert;
15
use function sprintf;
16
use function trigger_error;
17
18
use const E_USER_WARNING;
19
20
abstract class AbstractDonutCacheInterceptor implements MethodInterceptor
21
{
22
    // @phpcs:ignore SlevomatCodingStandard.TypeHints.UselessConstantTypeHint.UselessDocComment
23
    /** @var bool */
24
    protected const IS_ENTIRE_CONTENT_CACHEABLE = false;
25
26
    public function __construct(
27
        private readonly DonutRepositoryInterface $donutRepository,
28
    ) {
29
    }
30
31
    /**
32
     * {@inheritDoc}
33
     */
34
    #[Override]
35
    final public function invoke(MethodInvocation $invocation)
36
    {
37
        $ro = $invocation->getThis();
38
        assert($ro instanceof ResourceObject);
39
        try {
40
            $maybeRo = $this->donutRepository->get($ro);
41
            if ($maybeRo instanceof ResourceObject) {
42
                return $maybeRo;
43
            }
44
        } catch (Throwable $e) { // @codeCoverageIgnoreStart
45
            // when cache server is down
46
            $this->triggerWarning($e);
47
48
            return $invocation->proceed(); // @codeCoverageIgnoreEnd
49
        }
50
51
        /** @var ResourceObject $ro */
52
        $ro = $invocation->proceed();
53
        // donut created in ResourceObject
54
        if (isset($ro->headers[Header::ETAG]) || $ro->code >= Code::BAD_REQUEST) {
55
            return $ro;
56
        }
57
58
        return static::IS_ENTIRE_CONTENT_CACHEABLE ? // phpcs:ignore - not "self"
59
            $this->donutRepository->putStatic($ro, null, null) :
60
            $this->donutRepository->putDonut($ro, null);
61
    }
62
63
    /** @codeCoverageIgnore */
64
    private function triggerWarning(Throwable $e): void
65
    {
66
        trigger_error(sprintf('%s: %s in %s:%s', $e::class, $e->getMessage(), $e->getFile(), $e->getLine()), E_USER_WARNING);
67
    }
68
}
69