Completed
Pull Request — master (#419)
by Yanick
13:46
created

Symfony::refresh()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 7
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 7
loc 7
ccs 0
cts 0
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
crap 2
1
<?php
2
3
/*
4
 * This file is part of the FOSHttpCache package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
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 FOS\HttpCache\ProxyClient;
13
14
use FOS\HttpCache\Exception\ExceptionCollection;
15
use FOS\HttpCache\ProxyClient\Invalidation\PurgeCapable;
16
use FOS\HttpCache\ProxyClient\Invalidation\RefreshCapable;
17
use FOS\HttpCache\ProxyClient\Invalidation\TagCapable;
18
use FOS\HttpCache\SymfonyCache\HttpCacheAwareKernelInterface;
19
use FOS\HttpCache\SymfonyCache\PurgeListener;
20
use FOS\HttpCache\SymfonyCache\PurgeTagsListener;
21
use Http\Message\RequestFactory;
22
use Symfony\Component\HttpFoundation\Request;
23
24
/**
25
 * Symfony HttpCache invalidator.
26
 *
27
 * Additional constructor options:
28
 * - purge_method:         HTTP method that identifies purge requests.
29
 *
30
 * @author David de Boer <[email protected]>
31
 * @author David Buchmann <[email protected]>
32
 */
33
class Symfony extends HttpProxyClient implements PurgeCapable, RefreshCapable, TagCapable
34 4
{
35
    const HTTP_METHOD_REFRESH = 'GET';
36 4
37
    /**
38 4
     * @var array
39
     */
40
    private $queue;
41
42
    /**
43
     * @var HttpCacheAwareKernelInterface
44 3
     */
45
    private $kernel;
46 3
47 3
    /**
48
     * Additional parameter for (optional) kernel.
49 3
     *
50
     * {@inheritdoc}
51
     */
52 7
    public function __construct(
53
        HttpDispatcher $httpDispatcher,
54 7
        array $options = [],
55 7
        RequestFactory $messageFactory = null,
56 7
        HttpCacheAwareKernelInterface $kernel = null
57
    ) {
58
        parent::__construct($httpDispatcher, $options, $messageFactory);
59 7
60
        $this->kernel = $kernel;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function purge($url, array $headers = [])
67
    {
68
        $this->queueRequest($this->options['purge_method'], $url, $headers);
69
70
        return $this;
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 View Code Duplication
    public function refresh($url, array $headers = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
    {
78
        $headers = array_merge($headers, ['Cache-Control' => 'no-cache']);
79
        $this->queueRequest(self::HTTP_METHOD_REFRESH, $url, $headers);
80
81
        return $this;
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87
    public function flush()
88
    {
89
        if (!$this->isDirectRoutingEnabled()) {
90
            return parent::flush();
91
        }
92
93
        $exceptions = new ExceptionCollection();
94
95
        foreach ($this->queue as $request) {
96
            try {
97
                $this->kernel->getHttpCache()
98
                    ->handle($request, HttpCacheAwareKernelInterface::MASTER_REQUEST);
99
            } catch (\Exception $e) {
100
                $exceptions->add($e);
101
            }
102
        }
103
104
        if (count($exceptions)) {
105
            throw $exceptions;
106
        }
107
108
        return count($this->queue);
109
    }
110
111
    /**
112
     * Remove/Expire cache objects based on cache tags.
113
     *
114
     * @param array $tags Tags that should be removed/expired from the cache
115
     *
116
     * @return $this
117
     */
118
    public function invalidateTags(array $tags)
119
    {
120
        $escapedTags = $this->escapeTags($tags);
121
122
        $chunkSize = $this->determineTagsPerHeader($escapedTags, ',');
123
124
        foreach (array_chunk($escapedTags, $chunkSize) as $tagchunk) {
125
            $this->queueRequest(
126
                $this->options['tags_method'],
127
                '/',
128
                [$this->options['tags_header'] => implode(',', $tagchunk)],
129
                false
130
            );
131
        }
132
133
        return $this;
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139
    protected function queueRequest($method, $url, array $headers, $validateHost = true)
140
    {
141
        if (!$this->isDirectRoutingEnabled()) {
142
            return parent::queueRequest($method, $url, $headers, $validateHost);
143
        }
144
145
        $request = Request::create((string) $url, $method);
146
        $request->headers->replace($headers);
147
148
        $this->queue[sha1((string) $request)] = $request;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    protected function configureOptions()
155
    {
156
        $resolver = parent::configureOptions();
157
        $resolver->setDefaults([
158
            'purge_method' => PurgeListener::DEFAULT_PURGE_METHOD,
159
            'tags_method' => PurgeTagsListener::DEFAULT_TAGS_METHOD,
160
            'tags_header' => PurgeTagsListener::DEFAULT_TAGS_HEADER,
161
            'header_length' => 7500,
162
            'enable_kernel_routing' => false,
163
        ]);
164
        $resolver->setAllowedTypes('purge_method', 'string');
165
        $resolver->setAllowedTypes('tags_method', 'string');
166
        $resolver->setAllowedTypes('tags_header', 'string');
167
        $resolver->setAllowedTypes('header_length', 'int');
168
        $resolver->setAllowedTypes('enable_kernel_routing', ['boolean']);
169
170
        return $resolver;
171
    }
172
173
    /**
174
     * @return bool
175
     */
176
    protected function isDirectRoutingEnabled()
177
    {
178
        if ($this->options['enable_kernel_routing']
179
            && $this->kernel instanceof HttpCacheAwareKernelInterface
180
        ) {
181
            return true;
182
        }
183
184
        return false;
185
    }
186
}
187