Completed
Pull Request — 1.x (#55)
by Akihito
11:32 queued 10:17
created

ResourceStorage   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 2
dl 0
loc 132
ccs 52
cts 52
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A hasEtag() 0 4 1
A updateEtag() 0 12 1
A deleteEtag() 0 7 1
A get() 0 6 1
A delete() 0 7 1
A saveValue() 0 8 1
A saveView() 0 8 1
A evaluateBody() 0 13 4
A getVaryUri() 0 16 4
1
<?php
2
/**
3
 * This file is part of the BEAR.QueryRepository package.
4
 *
5
 * @license http://opensource.org/licenses/MIT MIT
6
 */
7
namespace BEAR\QueryRepository;
8
9
use BEAR\RepositoryModule\Annotation\Storage;
10
use BEAR\Resource\AbstractUri;
11
use BEAR\Resource\RequestInterface;
12
use BEAR\Resource\ResourceObject;
13
use Doctrine\Common\Cache\CacheProvider;
14
15
final class ResourceStorage implements ResourceStorageInterface
16
{
17
    const ETAG_TABLE = 'etag-table-';
18
19
    const ETAG_VAL = 'etag-val-';
20
21
    /**
22
     * @var CacheProvider
23
     */
24
    private $cache;
25
26
    /**
27
     * @Storage
28
     */
29 27
    public function __construct(CacheProvider $cache)
30
    {
31 27
        $this->cache = $cache;
32 27
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37 3
    public function hasEtag(string $etag) : bool
38
    {
39 3
        return $this->cache->contains(self::ETAG_VAL . $etag);
40
    }
41
42
    /**
43
     * Update ETag
44
     */
45 24
    public function updateEtag(ResourceObject $ro)
46
    {
47 24
        $varyUri = $this->getVaryUri($ro->uri);
48 24
        $etag = self::ETAG_VAL . $ro->headers['ETag'];
49 24
        $uri = self::ETAG_TABLE . $varyUri;
50
        // delete old ETag
51 24
        $this->deleteEtag($ro->uri);
52
        // save ETag uri
53 24
        $this->cache->save($uri, $etag);
54
        // save ETag value
55 24
        $this->cache->save($etag, $uri);
56 24
    }
57
58
    /**
59
     * Delete etag in etag repository
60
     *
61
     * @param AbstractUri $uri
62
     */
63 24
    public function deleteEtag(AbstractUri $uri)
64
    {
65 24
        $uri = self::ETAG_TABLE . $this->getVaryUri($uri); // invalidate etag
66 24
        $oldEtagKey = $this->cache->fetch($uri);
67
68 24
        $this->cache->delete($oldEtagKey);
69 24
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74 22
    public function get(AbstractUri $uri)
75
    {
76 22
        $uri = $this->getVaryUri($uri);
77
78 22
        return $this->cache->fetch($uri);
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84 12
    public function delete(AbstractUri $uri) : bool
85
    {
86 12
        $this->deleteEtag($uri);
87 12
        $uri = $this->getVaryUri($uri);
88
89 12
        return $this->cache->delete($uri);
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95 21
    public function saveValue(ResourceObject $ro, int $lifeTime)
96
    {
97 21
        $body = $this->evaluateBody($ro->body);
98 21
        $uri = $this->getVaryUri($ro->uri);
99 21
        $val = [$ro->uri, $ro->code, $ro->headers, $body, null];
100
101 21
        return $this->cache->save($uri, $val, $lifeTime);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 2
    public function saveView(ResourceObject $ro, int $lifeTime)
108
    {
109 2
        $body = $this->evaluateBody($ro->body);
110 2
        $uri = $this->getVaryUri($ro->uri);
111 2
        $val = [$ro->uri, $ro->code, $ro->headers, $body, $ro->view];
112
113 2
        return $this->cache->save($uri, $val, $lifeTime);
114
    }
115
116 23
    private function evaluateBody($body)
117
    {
118 23
        if (! \is_array($body)) {
119 6
            return $body;
120
        }
121 17
        foreach ($body as &$item) {
122 17
            if ($item instanceof RequestInterface) {
123 17
                $item = ($item)();
124
            }
125
        }
126
127 17
        return $body;
128
    }
129
130 24
    private function getVaryUri(AbstractUri $uri) : string
131
    {
132 24
        if (! isset($_SERVER['X_VARY'])) {
133 15
            return (string) $uri;
134
        }
135 10
        $varys = \explode(',', $_SERVER['X_VARY']);
136 10
        $varyId = '';
137 10
        foreach ($varys as $vary) {
138 10
            $phpVaryKey = \sprintf('X_%s', \strtoupper($vary));
139 10
            if (isset($_SERVER[$phpVaryKey])) {
140 10
                $varyId .= $_SERVER[$phpVaryKey];
141
            }
142
        }
143
144 10
        return (string) $uri . $varyId;
145
    }
146
}
147