Completed
Pull Request — master (#439)
by David
44:17
created

KernelDispatcher::invalidate()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 9.0648
c 0
b 0
f 0
cc 5
nc 5
nop 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\SymfonyCache;
13
14
use FOS\HttpCache\Exception\ExceptionCollection;
15
use FOS\HttpCache\Exception\ProxyUnreachableException;
16
use FOS\HttpCache\ProxyClient\Dispatcher;
17
use Psr\Http\Message\RequestInterface;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpKernel\HttpKernelInterface;
20
21
/**
22
 * This Dispatcher directly calls the Symfony HttpCache kernel without
23
 * executing any actual HTTP requests.
24
 *
25
 * This dispatcher can only be used if your application runs on one single
26
 * server.
27
 *
28
 * If you use Varnish/Nginx or have multiple servers, this client can not be
29
 * used.
30
 *
31
 * @author Yanick Witschi <[email protected]>
32
 */
33
class KernelDispatcher implements Dispatcher
34
{
35
    /**
36
     * @var HttpCacheProvider
37
     */
38
    private $httpCacheProvider;
39
40
    /**
41
     * @var array
42
     */
43
    private $queue = [];
44
45
    public function __construct(HttpCacheProvider $httpCacheProvider)
46
    {
47
        $this->httpCacheProvider = $httpCacheProvider;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function invalidate(RequestInterface $invalidationRequest, $validateHost = true)
54
    {
55
        $request = Request::create(
56
            $invalidationRequest->getUri(),
57
            $invalidationRequest->getMethod(),
58
            [],
59
            [],
60
            [],
61
            ['REMOTE_ADDR' => '127.0.0.1'],
62
            $invalidationRequest->getBody()->getContents()
63
        );
64
65
        // Add headers
66
        $headers = $invalidationRequest->getHeaders();
67
        foreach ($headers as $name => $values) {
68
            $name = strtolower($name);
69
70
            // symfony won't look at the cookies header but parses it when creating the request
71
            if ('cookie' === $name) {
72
                foreach ($values as $value) {
73
                    foreach (explode(';', $value) as $cookieString) {
74
                        $chunks = explode('=', $cookieString, 2);
75
                        $request->cookies->add([trim($chunks[0]) => trim($chunks[1])]);
76
                    }
77
                }
78
79
                continue;
80
            }
81
82
            $request->headers->set($name, $values);
83
        }
84
85
        $this->queue[sha1($request)] = $request;
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    public function flush()
92
    {
93
        if (!count($this->queue)) {
94
            return 0;
95
        }
96
        $queue = $this->queue;
97
        $this->queue = [];
98
99
        $exceptions = new ExceptionCollection();
100
        $httpCache = $this->httpCacheProvider->getHttpCache();
101
        if (null === $httpCache) {
102
            throw new ProxyUnreachableException('Kernel did not return a HttpCache instance. Did you forget $kernel->setHttpCache($cacheKernel) in your front controller?');
103
        }
104
105
        foreach ($queue as $request) {
106
            try {
107
                $httpCache->handle($request, HttpKernelInterface::MASTER_REQUEST, false);
108
            } catch (\Exception $e) {
109
                $exceptions->add($e);
110
            }
111
        }
112
113
        if (count($exceptions)) {
114
            throw $exceptions;
115
        }
116
117
        return count($queue);
118
    }
119
}
120