Completed
Push — master ( bd1454...5f9d19 )
by Nate
01:46
created

Cache::__invoke()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 74
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 74
ccs 0
cts 45
cp 0
rs 9.0335
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
                'key' => $key,
76
                'expires' => $item->getExpiration()->getTimestamp()
77
            ]);
78
79
            // Add response body
80
            $response = $response->withBody(
81
                StreamFactory::create($item->get())
82
            );
83
84
            return $response;
85
        } else {
86
            // Log
87
            $this->info(
88
                "Item not found in Cache. [key: {key}]", [
89
                'key' => $key
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
            /** @var StreamInterface $body */
102
            $body = $response->getBody();
103
104
            // Set cache contents
105
            $item->set($body->getContents());
106
107
            // Save cache item
108
            $this->pool->save($item);
109
110
            // Rewind stream
111
            $body->rewind();
112
113
            // Log
114
            $this->info(
115
                "Save item to Cache. [key: {key}, expires: {expires}]", [
116
                'key' => $key,
117
                'expires' => $item->getExpiration()->getTimestamp()
118
            ]);
119
        } else {
120
            // Log
121
            $this->info(
122
                "Did not save to cache because request was unsuccessful.", [
123
                'key' => $key,
124
                'statusCode' => $response->getStatusCode()
125
            ]);
126
        }
127
128
        return $response;
129
    }
130
131
    /**
132
     * Returns the id used to cache a request.
133
     *
134
     * @param RequestInterface $request
135
     *
136
     * @return string
137
     */
138
    private function getCacheKey(RequestInterface $request): string
139
    {
140
        return $request->getMethod() . md5((string)$request->getUri());
141
    }
142
}
143