Completed
Pull Request — master (#205)
by
unknown
05:09
created

SsiCache   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 8
dl 0
loc 152
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\CacheBundle\Adapter;
15
16
use Sonata\Cache\CacheAdapterInterface;
17
use Sonata\Cache\CacheElement;
18
use Sonata\Cache\CacheElementInterface;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
22
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
23
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
24
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
25
use Symfony\Component\Routing\RouterInterface;
26
27
/**
28
 * Not really a cache as it, depends on the reverse proxy feature.
29
 */
30
class SsiCache implements CacheAdapterInterface
31
{
32
    protected $router;
33
34
    protected $servers;
35
36
    protected $resolver;
37
38
    protected $token;
39
40
    /**
41
     * @var ArgumentResolverInterface
42
     */
43
    private $argumentResolver;
44
45
    public function __construct(
46
        string $token,
47
        RouterInterface $router,
48
        ControllerResolverInterface $resolver,
49
        ArgumentResolverInterface $argumentResolver
50
    ) {
51
        $this->token = $token;
52
        $this->router = $router;
53
        $this->resolver = $resolver;
54
        $this->argumentResolver = $argumentResolver;
55
    }
56
57
    public function flushAll(): bool
58
    {
59
        return true; // nothing to flush
60
    }
61
62
    public function flush(array $keys = []): bool
63
    {
64
        return true; // still nothing to flush ...
65
    }
66
67
    public function has(array $keys): bool
68
    {
69
        return true;
70
    }
71
72
    /**
73
     * @throws \RuntimeException
74
     */
75
    public function get(array $keys): CacheElementInterface
76
    {
77
        if (!isset($keys['controller'])) {
78
            throw new \RuntimeException('Please define a controller key');
79
        }
80
81
        if (!isset($keys['parameters'])) {
82
            throw new \RuntimeException('Please define a parameters key');
83
        }
84
85
        $content = sprintf('<!--# include virtual="%s" -->', $this->getUrl($keys));
86
87
        return new CacheElement($keys, new Response($content));
88
    }
89
90
    public function set(
91
        array $keys,
92
        $data,
93
        int $ttl = CacheElement::DAY,
94
        array $contextualKeys = []
95
    ): CacheElementInterface {
96
        return new CacheElement($keys, $data, $ttl, $contextualKeys);
97
    }
98
99
    /**
100
     * @throws AccessDeniedHttpException
101
     *
102
     * @return mixed
103
     */
104
    public function cacheAction(Request $request)
105
    {
106
        $parameters = $request->get('parameters', []);
107
108
        if ($request->get('token') != $this->computeHash($parameters)) {
109
            throw new AccessDeniedHttpException('Invalid token');
110
        }
111
112
        $subRequest = Request::create('', 'get', $parameters, $request->cookies->all(), [], $request->server->all());
113
114
        $controller = $this->resolver->getController($subRequest);
115
116
        $subRequest->attributes->add(['_controller' => $parameters['controller']]);
117
        $subRequest->attributes->add($parameters['parameters']);
118
119
        $arguments = $this->argumentResolver->getArguments($subRequest, $controller)
120
121
        return call_user_func_array($controller, $arguments);
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_RETURN
Loading history...
122
    }
123
124
    public function isContextual(): bool
125
    {
126
        return true;
127
    }
128
129
    protected function getUrl(array $keys): ?string
130
    {
131
        $parameters = [
132
            'token' => $this->computeHash($keys),
133
            'parameters' => $keys,
134
        ];
135
136
        return $this->router->generate('sonata_cache_ssi', $parameters, UrlGeneratorInterface::ABSOLUTE_PATH);
137
    }
138
139
    protected function computeHash(array $keys): string
140
    {
141
        ksort($keys);
142
143
        return hash('sha256', $this->token.serialize($keys));
144
    }
145
}
146