Completed
Push — master ( fa7c53...535778 )
by Matze
04:38
created

Cache::handleCached()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 16
ccs 5
cts 5
cp 1
rs 9.4285
cc 1
eloc 9
nc 1
nop 1
crap 1
1
<?php
2
3
namespace BrainExe\Core\Middleware;
4
5
use BrainExe\Annotations\Annotations\Inject;
6
use BrainExe\Core\Annotations\Middleware;
7
use BrainExe\Core\Traits\CacheTrait;
8
use BrainExe\Core\Traits\LoggerTrait;
9
use DateTime;
10
use Doctrine\Common\Cache\CacheProvider;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\Routing\Route;
14
15
/**
16
 * @todo use X-Cache / X-Validate
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...
17
 * @todo 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...
18
 * @Middleware("Middleware.Cache")
19
 */
20
class Cache extends AbstractMiddleware
21
{
22
    use CacheTrait;
23
    use LoggerTrait;
24
25
    const DEFAULT_TTL = 60;
26
    const PREFIX = 'cache:';
27
28
    /**
29
     * @var string
30
     */
31
    private $cacheKey;
32
33
    /**
34
     * @var boolean
35
     */
36
    private $enabled;
37
38
    /**
39
     * @Inject("%cache.enabled%")
40
     * @param bool $cacheEnabled
41 3
     */
42
    public function __construct($cacheEnabled)
43 3
    {
44 3
        $this->enabled = $cacheEnabled;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49 3
     */
50
    public function processRequest(Request $request, Route $route)
51 3
    {
52 1
        if (!$this->enabled || !$route->getOption('cache') || !$request->isMethod('GET')) {
53
            return null;
54
        }
55 2
56
        $this->cacheKey = $this->generateCacheKey($request);
57 2
58
        $cache = $this->getCache();
59 2
60 1
        if ($cache->contains($this->cacheKey)) {
61
            return $this->handleCached($cache);
62
        }
63 1
64
        return null;
65
    }
66
67
    /**
68
     * {@inheritdoc}
69 2
     */
70
    public function processResponse(Request $request, Response $response)
71 2
    {
72 1
        if (!$this->cacheKey) {
73
            return null;
74
        }
75 1
76 1
        if (!$response->isOk()) {
77
            return;
78
        }
79 1
80
        $cache = $this->getCache();
81 1
82
        $this->debug(sprintf('save into cache: %s', $this->cacheKey));
83 1
84 1
        $cache->save($this->cacheKey, $response, $this->getTTL());
85 1
        $this->cacheKey = null;
86
    }
87
88
    /**
89
     * @param Request $request
90
     * @return string
91 2
     */
92
    private function generateCacheKey(Request $request)
93 2
    {
94
        return self::PREFIX . $request->getRequestUri();
95
    }
96
97
    /**
98
     * @param CacheProvider$cache
99
     * @return Response
100 1
     */
101
    private function handleCached(CacheProvider $cache)
102 1
    {
103
        $this->debug(sprintf('fetch from cache: %s', $this->cacheKey));
104
105 1
        /** @var Response $response */
106 1
        $response       = $cache->fetch($this->cacheKey);
107
        $this->cacheKey = null;
108 1
109
        $ttl = $this->getTTL();
110 1
111
        $response->headers->set('X-Cache', 'hit');
112
        $response->setMaxAge($ttl);
113
        $response->setExpires(new DateTime(sprintf('+%d seconds', $ttl)));
114
115
        return $response;
116
    }
117
118
    /**
119
     * @return int
120
     */
121
    private function getTTL()
122
    {
123
        return self::DEFAULT_TTL;
124
    }
125
}
126