Completed
Pull Request — 1.x (#55)
by Akihito
20:51
created

ResourceStorage::evaluateBody()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 4
nc 4
nop 1
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
    public function __construct(CacheProvider $cache)
30
    {
31
        $this->cache = $cache;
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function hasEtag(string $etag) : bool
38
    {
39
        return $this->cache->contains(self::ETAG_VAL . $etag);
40
    }
41
42
    /**
43
     * Update ETag
44
     */
45
    public function updateEtag(ResourceObject $ro)
46
    {
47
        $varyUri = $this->getVaryUri($ro->uri);
48
        $etag = self::ETAG_VAL . $ro->headers['ETag'];
49
        $uri = self::ETAG_TABLE . $varyUri;
50
        // delete old ETag
51
        $this->deleteEtag($ro->uri);
52
        // save ETag uri
53
        $this->cache->save($uri, $etag);
54
        // save ETag value
55
        $this->cache->save($etag, $uri);
56
    }
57
58
    /**
59
     * Delete etag in etag repository
60
     *
61
     * @param AbstractUri $uri
62
     */
63
    public function deleteEtag(AbstractUri $uri)
64
    {
65
        $uri = self::ETAG_TABLE . $this->getVaryUri($uri); // invalidate etag
66
        $oldEtagKey = $this->cache->fetch($uri);
67
68
        $this->cache->delete($oldEtagKey);
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function get(AbstractUri $uri)
75
    {
76
        $uri = $this->getVaryUri($uri);
77
78
        return $this->cache->fetch($uri);
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    public function delete(AbstractUri $uri) : bool
85
    {
86
        $this->deleteEtag($uri);
87
        $uri = $this->getVaryUri($uri);
88
89
        return $this->cache->delete($uri);
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    public function saveValue(ResourceObject $ro, int $lifeTime)
96
    {
97
        $body = $this->evaluateBody($ro->body);
98
        $uri = $this->getVaryUri($ro->uri);
99
        $val = [$ro->uri, $ro->code, $ro->headers, $body, null];
100
101
        return $this->cache->save($uri, $val, $lifeTime);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function saveView(ResourceObject $ro, int $lifeTime)
108
    {
109
        $body = $this->evaluateBody($ro->body);
110
        $uri = $this->getVaryUri($ro->uri);
111
        $val = [$ro->uri, $ro->code, $ro->headers, $body, $ro->view];
112
113
        return $this->cache->save($uri, $val, $lifeTime);
114
    }
115
116
    private function evaluateBody($body)
117
    {
118
        if (! \is_array($body)) {
119
            return $body;
120
        }
121
        foreach ($body as &$item) {
122
            if ($item instanceof RequestInterface) {
123
                $item = ($item)();
124
            }
125
        }
126
127
        return $body;
128
    }
129
130
    private function getVaryUri(AbstractUri $uri) : string
131
    {
132
        if (! isset($_SERVER['X_VARY'])) {
133
            return (string) $uri;
134
        }
135
        $varys = \explode(',', $_SERVER['X_VARY']);
136
        $varyId = '';
137
        foreach ($varys as $vary) {
138
            $phpVaryKey = \sprintf('X_%s', \strtoupper($vary));
139
            if (isset($_SERVER[$phpVaryKey])) {
140
                $varyId .= $_SERVER[$phpVaryKey];
141
            }
142
        }
143
144
        return (string) $uri . $varyId;
145
    }
146
}
147