Completed
Push — master ( 5f9d19...a4f802 )
by Nate
01:49
created

Cache::__invoke()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 82
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 82
ccs 0
cts 53
cp 0
rs 8.7769
c 0
b 0
f 0
cc 3
eloc 37
nc 3
nop 3
crap 12

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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