DonutRepository::refreshDonut()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 14
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 22
rs 9.7998
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\QueryRepository;
6
7
use BEAR\Resource\AbstractUri;
8
use BEAR\Resource\ResourceInterface;
9
use BEAR\Resource\ResourceObject;
10
use Override;
11
12
use function assert;
13
use function explode;
14
15
final class DonutRepository implements DonutRepositoryInterface
16
{
17
    public function __construct(
18
        private readonly QueryRepositoryInterface $queryRepository,
19
        private readonly HeaderSetter $headerSetter,
20
        private readonly ResourceStorageInterface $resourceStorage,
21
        private readonly ResourceInterface $resource,
22
        private readonly CdnCacheControlHeaderSetterInterface $cdnCacheControlHeaderSetter,
23
        private readonly RepositoryLoggerInterface $logger,
24
        private readonly DonutRendererInterface $renderer,
25
    ) {
26
    }
27
28
    #[Override]
29
    public function get(ResourceObject $ro): ResourceObject|null
30
    {
31
        $maybeState = $this->queryRepository->get($ro->uri);
32
        $this->logger->log('try-donut-view: uri:%s', $ro->uri);
33
        if ($maybeState instanceof ResourceState) {
34
            $this->logger->log('found-donut-view: uri:%s', $ro->uri);
35
            $ro->headers = $maybeState->headers;
36
            $ro->view = $maybeState->view;
37
38
            return $ro;
39
        }
40
41
        return $this->refreshDonut($ro);
42
    }
43
44
    /**
45
     * {@inheritDoc}
46
     */
47
    #[Override]
48
    public function putStatic(ResourceObject $ro, int|null $ttl = null, int|null $sMaxAge = null): ResourceObject
49
    {
50
        $this->logger->log('put-donut: uri:%s ttl:%s s-maxage:%d', (string) $ro->uri, $sMaxAge, $ttl);
51
        $keys = new SurrogateKeys($ro->uri);
52
        $keys->addTag($ro);
53
        $headerKeys = $this->getHeaderKeys($ro);
54
        $donut = ResourceDonut::create($ro, $this->renderer, $keys, $sMaxAge, true);
55
        $donut->render($ro, $this->renderer);
56
        $this->setHeaders($keys, $ro, $sMaxAge);
57
        // delete
58
        $this->resourceStorage->invalidateTags([(new UriTag())($ro->uri)]);
59
        // save content cache and donut
60
        $this->saveView($ro, $sMaxAge);
61
        $this->resourceStorage->saveDonut($ro->uri, $donut, $ttl, $headerKeys);
62
63
        return $ro;
64
    }
65
66
    /**
67
     * {@inheritDoc}
68
     */
69
    #[Override]
70
    public function putDonut(ResourceObject $ro, int|null $donutTtl): ResourceObject
71
    {
72
        $this->logger->log('put-donut: uri:%s ttl:%s', (string) $ro->uri, $donutTtl);
73
        $keys = new SurrogateKeys($ro->uri);
74
        $keyArrays = $this->getHeaderKeys($ro);
75
        $donut = ResourceDonut::create($ro, $this->renderer, $keys, $donutTtl, false);
76
        $donut->render($ro, $this->renderer);
77
        $keys->setSurrogateHeader($ro);
78
        // delete
79
        $this->resourceStorage->invalidateTags([(new UriTag())($ro->uri)]);
80
        // save donut
81
        $this->resourceStorage->saveDonut($ro->uri, $donut, $donutTtl, $keyArrays);
82
83
        return $ro;
84
    }
85
86
    /**
87
     * {@inheritDoc}
88
     */
89
    #[Override]
90
    public function purge(AbstractUri $uri): void
91
    {
92
        $this->queryRepository->purge($uri);
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98
    #[Override]
99
    public function invalidateTags(array $tags): void
100
    {
101
        $this->resourceStorage->invalidateTags($tags);
102
    }
103
104
    private function refreshDonut(ResourceObject $ro): ResourceObject|null
105
    {
106
        $donut = $this->resourceStorage->getDonut($ro->uri);
107
        $this->logger->log('try-donut uri:%s', (string) $ro->uri);
108
        if (! $donut instanceof ResourceDonut) {
109
            $this->logger->log('no-donut-found uri:%s', (string) $ro->uri);
110
111
            return null;
112
        }
113
114
        $this->logger->log('refresh-donut: uri:%s', $ro->uri);
115
        $donut->refresh($this->resource, $ro);
116
        if (! $donut->isCacheble) {
117
            return $ro;
118
        }
119
120
        ($this->headerSetter)($ro, $donut->ttl, null);
121
        $ro->headers[Header::ETAG] .= 'r'; // mark refreshed by resource static
122
        ($this->cdnCacheControlHeaderSetter)($ro, $donut->ttl);
123
        $this->saveView($ro, $donut->ttl);
124
125
        return $ro;
126
    }
127
128
    private function saveView(ResourceObject $ro, int|null $ttl): bool
129
    {
130
        assert(isset($ro->headers[Header::ETAG]));
131
        $surrogateKeys = $ro->headers[Header::SURROGATE_KEY] ?? '';
132
        $this->resourceStorage->saveEtag($ro->uri, $ro->headers[Header::ETAG], $surrogateKeys, $ttl);
133
134
        return $this->resourceStorage->saveDonutView($ro, $ttl);
135
    }
136
137
    private function setHeaders(SurrogateKeys $keys, ResourceObject $ro, int|null $sMaxAge): void
138
    {
139
        $keys->setSurrogateHeader($ro);
140
        ($this->cdnCacheControlHeaderSetter)($ro, $sMaxAge);
141
        ($this->headerSetter)($ro, 0, null);
142
    }
143
144
    /** @return list<string> */
0 ignored issues
show
Bug introduced by
The type BEAR\QueryRepository\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
145
    public function getHeaderKeys(ResourceObject $ro): array
146
    {
147
        return isset($ro->headers[Header::SURROGATE_KEY]) ? explode(' ', $ro->headers[Header::SURROGATE_KEY]) : [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return IssetNode ? explo...RROGATE_KEY]) : array() returns the type array|string[] which is incompatible with the documented return type BEAR\QueryRepository\list.
Loading history...
148
    }
149
}
150