Completed
Push — master ( 3f1d1d...0341ae )
by Matze
05:15
created

Cache::processRequest()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 11
cts 11
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 11
nc 3
nop 2
crap 4
1
<?php
2
3
namespace BrainExe\Core\Middleware;
4
5
use BrainExe\Core\Annotations\Middleware;
6
use BrainExe\Core\Traits\CacheTrait;
7
use BrainExe\Core\Traits\LoggerTrait;
8
use DateTime;
9
use Symfony\Component\Cache\Adapter\AdapterInterface;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\Routing\Route;
13
14
/**
15
 * @todo X-Invalidate
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
16
 * @Middleware("Middleware.Cache")
17
 */
18
class Cache extends AbstractMiddleware
19
{
20
    use CacheTrait;
21
    use LoggerTrait;
22
23
    const DEFAULT_TTL = 60;
24
    const PREFIX = 'cache:';
25
26
    /**
27
     * {@inheritdoc}
28
     */
29 3
    public function processRequest(Request $request, Route $route)
30
    {
31 3
        if (!$route->hasOption('cache') || !$request->isMethod('GET')) {
32 1
            return null;
33
        }
34
35 2
        $cacheKey = $this->generateCacheKey($request);
36
37 2
        $ttl   = $route->getOption('cache');
38 2
        $cache = $this->getCache();
39 2
        if ($cache->hasItem($cacheKey)) {
40 1
            return $this->handleCached($cache, $cacheKey, $ttl);
41
        }
42
43
        // enable cache for current request. Store response later in given key
44 1
        $request->attributes->set('_cacheKey', $cacheKey);
45 1
        $request->attributes->set('_cacheTTL', $ttl);
46
47 1
        return null;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 2
    public function processResponse(Request $request, Response $response)
54
    {
55 2
        if (!$response->isOk()) {
56 1
            return;
57
        }
58
59 2
        $cacheKey = $request->attributes->get('_cacheKey');
60 2
        $ttl      = $request->attributes->get('_cacheTTL');
61 2
        if (empty($cacheKey)) {
62 1
            return;
63
        }
64
65 1
        $cache = $this->getCache();
66
67 1
        $this->info(sprintf('miss: save into cache: %s', $cacheKey), [
68 1
            'application' => 'cache',
69 1
            'type'        => 'miss',
70 1
            'cacheKey'    => $cacheKey,
71 1
            'ttl'         => $ttl,
72
        ]);
73
74 1
        $item = $cache->getItem($cacheKey);
75 1
        $item->set($response);
76 1
        $item->expiresAfter($ttl);
77 1
        $cache->save($item);
78
79 1
        $response->headers->set('X-Cache', 'miss');
80 1
        $response->setMaxAge($ttl);
81 1
        $response->setExpires(new DateTime(sprintf('+%d seconds', $ttl)));
82 1
    }
83
84
    /**
85
     * @param AdapterInterface $cache
86
     * @param string $cacheKey
87
     * @param int $ttl
88
     * @return Response
89
     */
90 1
    private function handleCached(AdapterInterface $cache, string $cacheKey, int $ttl) : Response
91
    {
92 1
        $this->info(sprintf('hit: fetch from cache: %s', $cacheKey), [
93 1
            'application' => 'cache',
94 1
            'type'        => 'hit',
95 1
            'cacheKey'    => $cacheKey,
96 1
            'ttl'         => $ttl,
97
        ]);
98
99
        /** @var Response $response */
100 1
        $response = $cache->getItem($cacheKey)->get();
101
102 1
        $response->headers->set('X-Cache', 'hit');
103 1
        $response->setMaxAge($ttl);
104 1
        $response->setExpires(new DateTime(sprintf('+%d seconds', $ttl)));
105
106 1
        return $response;
107
    }
108
109
    /**
110
     * @param Request $request
111
     * @return string
112
     */
113 2
    private function generateCacheKey(Request $request) : string
114
    {
115 2
        return self::PREFIX . $request->getRequestUri();
116
    }
117
}
118