Completed
Push — 2.x-dev-kit ( 6f250c )
by
unknown
02:44
created

SsiCache   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 5
Bugs 2 Features 1
Metric Value
wmc 13
c 5
b 2
f 1
lcom 1
cbo 7
dl 0
loc 133
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A flushAll() 0 4 1
A flush() 0 4 1
A has() 0 4 1
A set() 0 4 1
A __construct() 0 6 1
A get() 0 14 3
A cacheAction() 0 20 2
A isContextual() 0 4 1
A getUrl() 0 9 1
A computeHash() 0 6 1
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\CacheBundle\Adapter;
13
14
use Sonata\Cache\CacheAdapterInterface;
15
use Sonata\Cache\CacheElement;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpFoundation\Response;
18
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
19
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
20
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
21
use Symfony\Component\Routing\RouterInterface;
22
23
/**
24
 * Not really a cache as it, depends on the reverse proxy feature.
25
 */
26
class SsiCache implements CacheAdapterInterface
27
{
28
    protected $router;
29
30
    protected $servers;
31
32
    protected $resolver;
33
34
    protected $token;
35
36
    /**
37
     * @param string                      $token
38
     * @param RouterInterface             $router
39
     * @param ControllerResolverInterface $resolver
40
     */
41
    public function __construct($token, RouterInterface $router, ControllerResolverInterface $resolver = null)
42
    {
43
        $this->token = $token;
44
        $this->router = $router;
45
        $this->resolver = $resolver;
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     */
51
    public function flushAll()
52
    {
53
        return true; // nothing to flush
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function flush(array $keys = array())
60
    {
61
        return true; // still nothing to flush ...
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function has(array $keys)
68
    {
69
        return true;
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function get(array $keys)
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
    /**
91
     * {@inheritdoc}
92
     */
93
    public function set(array $keys, $data, $ttl = CacheElement::DAY, array $contextualKeys = array())
94
    {
95
        return new CacheElement($keys, $data, $ttl, $contextualKeys);
96
    }
97
98
    /**
99
     * @param Request $request
100
     *
101
     * @return mixed
102
     */
103
    public function cacheAction(Request $request)
104
    {
105
        $parameters = $request->get('parameters', array());
106
107
        if ($request->get('token') != $this->computeHash($parameters)) {
108
            throw new AccessDeniedHttpException('Invalid token');
109
        }
110
111
        $subRequest = Request::create('', 'get', $parameters, $request->cookies->all(), array(), $request->server->all());
112
113
        $controller = $this->resolver->getController($subRequest);
114
115
        $subRequest->attributes->add(array('_controller' => $parameters['controller']));
116
        $subRequest->attributes->add($parameters['parameters']);
117
118
        $arguments = $this->resolver->getArguments($subRequest, $controller);
119
120
        // call controller
121
        return call_user_func_array($controller, $arguments);
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function isContextual()
128
    {
129
        return true;
130
    }
131
132
    /**
133
     * @param array $keys
134
     *
135
     * @return string
136
     */
137
    protected function getUrl(array $keys)
138
    {
139
        $parameters = array(
140
            'token' => $this->computeHash($keys),
141
            'parameters' => $keys,
142
        );
143
144
        return $this->router->generate('sonata_cache_ssi', $parameters, UrlGeneratorInterface::ABSOLUTE_PATH);
145
    }
146
147
    /**
148
     * @param array $keys
149
     *
150
     * @return string
151
     */
152
    protected function computeHash(array $keys)
153
    {
154
        ksort($keys);
155
156
        return hash('sha256', $this->token.serialize($keys));
157
    }
158
}
159