Completed
Push — master ( 12bc5d...f69768 )
by Oscar
58:41
created

Cache::__invoke()   C

Complexity

Conditions 9
Paths 25

Size

Total Lines 50
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
c 4
b 1
f 0
dl 0
loc 50
rs 6
cc 9
eloc 24
nc 25
nop 3
1
<?php
2
3
namespace Psr7Middlewares\Middleware;
4
5
use Psr7Middlewares\Middleware;
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 = CacheControl::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
79
            foreach ($headers as $name => $header) {
80
                $response = $response->withHeader($name, $header);
81
            }
82
83
            $lastModified = $response->getHeaderLine('Last-Modified');
0 ignored issues
show
Unused Code introduced by
$lastModified is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
84
            $modifiedSince = $request->getHeaderLine('If-Modified-Since');
0 ignored issues
show
Unused Code introduced by
$modifiedSince is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
85
86
            if ($this->cacheUtil->isNotModified($request, $response)) {
87
                return $response->withStatus(304);
88
            }
89
90
            $this->cache->deleteItem($key);
91
        }
92
93
        $response = $next($request, $response);
94
95
        //Add cache-control header
96
        if ($this->cacheControl && !$response->hasHeader('Cache-Control')) {
97
            $response = $this->cacheUtil->withCacheControl($response, $this->cacheControl);
98
        }
99
100
        //Add Last-Modified header
101
        if (!$response->hasHeader('Last-Modified')) {
102
            $response = $this->cacheUtil->withLastModified($response, time());
103
        }
104
105
        //Save in the cache
106
        if ($this->cacheUtil->isCacheable($response)) {
107
            $item->set($response->getHeaders());
108
109
            $time = $this->cacheUtil->getLifetime($response);
110
111
            if ($time) {
112
                $item->expiresAt(time() + $time);
0 ignored issues
show
Documentation introduced by
time() + $time is of type integer|double, but the function expects a object<DateTimeInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
113
            }
114
115
            $this->cache->save($item);
116
        }
117
118
        return $response;
119
    }
120
121
    /**
122
     * Returns the id used to cache a request.
123
     *
124
     * @param RequestInterface $request
125
     *
126
     * @return string
127
     */
128
    private function getCacheKey(RequestInterface $request)
129
    {
130
        return $request->getMethod().md5((string) $request->getUri());
131
    }
132
}
133