Cache::getCacheKey()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipbox/cache/blob/master/LICENSE
6
 * @link       https://github.com/flipbox/cache
7
 */
8
9
namespace Flipbox\Cache\Middleware;
10
11
use Flipbox\Cache\Exceptions\InvalidCachePoolException;
12
use Flipbox\Http\Stream\Factory as StreamFactory;
13
use Flipbox\Relay\Middleware\AbstractMiddleware;
14
use Psr\Cache\CacheItemPoolInterface;
15
use Psr\Http\Message\RequestInterface;
16
use Psr\Http\Message\ResponseInterface;
17
use Stash\Interfaces\ItemInterface;
18
19
/**
20
 * @author Flipbox Factory <[email protected]>
21
 * @since 2.0.0
22
 */
23
class Cache extends AbstractMiddleware
24
{
25
26
    /**
27
     * @var CacheItemPoolInterface The connection
28
     */
29
    public $pool;
30
31
    /**
32
     * @inheritdoc
33
     */
34
    public function init()
35
    {
36
        // Parent
37
        parent::init();
38
39
        // Ensure we have a valid pool
40
        if (!$this->pool instanceof CacheItemPoolInterface) {
41
            throw new InvalidCachePoolException(
42
                sprintf(
43
                    "The class '%s' requires a cache pool that is an instance of '%s'",
44
                    get_class($this),
45
                    'Psr\Cache\CacheItemPoolInterface'
46
                )
47
            );
48
        }
49
    }
50
51
    /**
52
     * @inheritdoc
53
     */
54
    public function __invoke(
55
        RequestInterface $request,
56
        ResponseInterface $response,
57
        callable $next = null
58
    ): ResponseInterface {
59
        // Do parent (logging)
60
        parent::__invoke($request, $response);
61
62
        // Create a cache key
63
        $key = $this->getCacheKey($request);
64
65
        /** @var ItemInterface $item */
66
        $item = $this->pool->getItem($key);
67
68
        // If it's cached
69
        if ($item->isHit()) {
70
            $this->info(
71
                "Item found in Cache",
72
                [
73
                    'key' => $key,
74
                    'expires' => $item->getExpiration()
75
                ]
76
            );
77
78
            // Add response body
79
            $response = $response->withBody(
80
                StreamFactory::create($item->get())
81
            );
82
83
            return $response;
84
        } else {
85
            $this->info(
86
                "Item not found in Cache",
87
                [
88
                    'key' => $key
89
                ]
90
            );
91
        }
92
93
        // Lock item
94
        $item->lock();
95
96
        /** @var ResponseInterface $response */
97
        $response = $next($request, $response);
98
99
        // Only cache successful responses
100
        if ($this->isResponseSuccessful($response)) {
101
            // Set cache contents
102
            $item->set($response->getBody()->getContents());
103
104
            // Save cache item
105
            $this->pool->save($item);
106
107
            $this->info(
108
                "Save item to Cache",
109
                [
110
                    'key' => $key,
111
                    'expires' => $item->getExpiration()
112
                ]
113
            );
114
        } else {
115
            $this->info(
116
                "Did not save to cache because request was unsuccessful.",
117
                [
118
                    'key' => $key,
119
                    'statusCode' => $response->getStatusCode()
120
                ]
121
            );
122
        }
123
124
        return $response;
125
    }
126
127
    /**
128
     * Returns the id used to cache a request.
129
     *
130
     * @param RequestInterface $request
131
     *
132
     * @return string
133
     */
134
    private function getCacheKey(RequestInterface $request): string
135
    {
136
        return $request->getMethod() . md5((string)$request->getUri());
137
    }
138
}
139