Completed
Pull Request — master (#351)
by David
15:28
created

PurgeListener   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 7
dl 0
loc 91
ccs 26
cts 26
cp 1
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getSubscribedEvents() 0 6 1
B handlePurge() 0 30 6
A getOptionsResolver() 0 8 1
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\SymfonyCache;
13
14
use Symfony\Component\HttpFoundation\Response;
15
use Symfony\Component\OptionsResolver\OptionsResolver;
16
17
/**
18
 * Purge handler for the symfony built-in HttpCache.
19
 *
20
 * @author David Buchmann <[email protected]>
21
 *
22
 * {@inheritdoc}
23
 */
24
class PurgeListener extends AccessControlledListener
25
{
26
    const DEFAULT_PURGE_METHOD = 'PURGE';
27
28
    /**
29
     * The purge method to use.
30
     *
31
     * @var string
32
     */
33
    private $purgeMethod;
34
35
    /**
36
     * When creating the purge listener, you can configure an additional option.
37
     *
38
     * - purge_method: HTTP method that identifies purge requests.
39
     *
40
     * @param array $options Options to overwrite the default options
41
     *
42
     * @throws \InvalidArgumentException if unknown keys are found in $options
43
     *
44
     * @see AccessControlledListener::__construct
45
     */
46 8
    public function __construct(array $options = [])
47
    {
48 8
        parent::__construct($options);
49
50 6
        $this->purgeMethod = $this->getOptionsResolver()->resolve($options)['purge_method'];
51 6
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 1
    public static function getSubscribedEvents()
57
    {
58
        return [
59 1
            Events::PRE_INVALIDATE => 'handlePurge',
60 1
        ];
61
    }
62
63
    /**
64
     * Look at unsafe requests and handle purge requests.
65
     *
66
     * Prevents access when the request comes from a non-authorized client.
67
     *
68
     * @param CacheEvent $event
69
     */
70 5
    public function handlePurge(CacheEvent $event)
71
    {
72 5
        $request = $event->getRequest();
73 5
        if ($this->purgeMethod !== $request->getMethod()) {
74 1
            return;
75
        }
76
77 4
        if (!$this->isRequestAllowed($request)) {
78 2
            $event->setResponse(new Response('', 400));
79
80 2
            return;
81
        }
82
83 2
        // because symfony cache respects the scheme when caching and purging, we need to invalidate both variants
84 2
        $uri = $request->getUri();
85 1
        $uri2 = 0 === strpos($uri, 'https://')
86 1
            ? preg_replace('https', 'http', $uri, 1)
87 1
            : preg_replace('http', 'https', $uri, 1);
88
        $store = $event->getKernel()->getStore();
89 2
        $response = new Response();
90 2
91
        if ($store->purge($uri)
92
            || $store->purge($uri2)
93
        ) {
94
            $response->setStatusCode(200, 'Purged');
95
        } else {
96
            $response->setStatusCode(200, 'Not found');
97 8
        }
98
        $event->setResponse($response);
99 8
    }
100 8
101 8
    /**
102
     * Add the purge_method option.
103 8
     *
104
     * @return OptionsResolver
105
     */
106
    protected function getOptionsResolver()
107
    {
108
        $resolver = parent::getOptionsResolver();
109
        $resolver->setDefault('purge_method', static::DEFAULT_PURGE_METHOD);
110
        $resolver->setAllowedTypes('purge_method', 'string');
111
112
        return $resolver;
113
    }
114
}
115