1 | <?php |
||
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); |
||
|
|||
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 |