Cache::getCacheKey()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Psr7Middlewares\Middleware;
4
5
use Micheh\Cache\Header\RequestCacheControl;
6
use Psr\Http\Message\RequestInterface;
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Cache\CacheItemPoolInterface;
9
use Micheh\Cache\CacheUtil;
10
use Micheh\Cache\Header\CacheControl;
11
12
/**
13
 * Middleware to cache the response using Cache-Control and other directives.
14
 */
15
class Cache
16
{
17
    /**
18
     * @var CacheItemPoolInterface The cache implementation used
19
     */
20
    private $cache;
21
22
    /**
23
     * @var CacheUtil
24
     */
25
    private $cacheUtil;
26
27
    /**
28
     * @var CacheControl
29
     */
30
    private $cacheControl;
31
32
    /**
33
     * Set the psr-6 cache pool.
34
     *
35
     * @param CacheItemPoolInterface $cache
36
     */
37
    public function __construct(CacheItemPoolInterface $cache)
38
    {
39
        $this->cache = $cache;
40
        $this->cacheUtil = new CacheUtil();
41
    }
42
43
    /**
44
     * Set a cache-control header to all responses.
45
     *
46
     * @param string|CacheControl $cacheControl
47
     *
48
     * @return self
49
     */
50
    public function cacheControl($cacheControl)
51
    {
52
        if (!($cacheControl instanceof CacheControl)) {
53
            $cacheControl = RequestCacheControl::fromString($cacheControl);
54
        }
55
56
        $this->cacheControl = $cacheControl;
57
58
        return $this;
59
    }
60
61
    /**
62
     * Execute the middleware.
63
     *
64
     * @param RequestInterface  $request
65
     * @param ResponseInterface $response
66
     * @param callable          $next
67
     *
68
     * @return ResponseInterface
69
     */
70
    public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next)
71
    {
72
        $key = $this->getCacheKey($request);
73
        $item = $this->cache->getItem($key);
74
75
        //If it's cached
76
        if ($item->isHit()) {
77
            $headers = $item->get();
78
            $cachedResponse = $response->withStatus(304);
79
80
            foreach ($headers as $name => $header) {
81
                $cachedResponse = $cachedResponse->withHeader($name, $header);
82
            }
83
84
            if ($this->cacheUtil->isNotModified($request, $cachedResponse)) {
85
                return $cachedResponse;
86
            }
87
88
            $this->cache->deleteItem($key);
89
        }
90
91
        $response = $next($request, $response);
92
93
        //Add cache-control header
94
        if ($this->cacheControl && !$response->hasHeader('Cache-Control')) {
95
            $response = $this->cacheUtil->withCacheControl($response, $this->cacheControl);
96
        }
97
98
        //Add Last-Modified header
99
        if (!$response->hasHeader('Last-Modified')) {
100
            $response = $this->cacheUtil->withLastModified($response, time());
101
        }
102
103
        //Save in the cache
104
        if ($this->cacheUtil->isCacheable($response)) {
105
            $item->set($response->getHeaders());
106
            $item->expiresAfter($this->cacheUtil->getLifetime($response));
107
108
            $this->cache->save($item);
109
        }
110
111
        return $response;
112
    }
113
114
    /**
115
     * Returns the id used to cache a request.
116
     *
117
     * @param RequestInterface $request
118
     *
119
     * @return string
120
     */
121
    private function getCacheKey(RequestInterface $request)
122
    {
123
        return $request->getMethod().md5((string) $request->getUri());
124
    }
125
}
126