Completed
Pull Request — master (#440)
by David
33:33
created

MultiplexerClient::purge()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 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\ProxyClient;
13
14
use FOS\HttpCache\Exception\ExceptionCollection;
15
use FOS\HttpCache\Exception\InvalidArgumentException;
16
use FOS\HttpCache\Exception\UnsupportedProxyOperationException;
17
use FOS\HttpCache\ProxyClient\Invalidation\BanCapable;
18
use FOS\HttpCache\ProxyClient\Invalidation\ClearCapable;
19
use FOS\HttpCache\ProxyClient\Invalidation\PurgeCapable;
20
use FOS\HttpCache\ProxyClient\Invalidation\RefreshCapable;
21
use FOS\HttpCache\ProxyClient\Invalidation\TagCapable;
22
23
/**
24
 * This class forwards invalidation to all attached clients.
25
 *
26
 * @author Emanuele Panzeri <[email protected]>
27
 */
28
class MultiplexerClient implements BanCapable, PurgeCapable, RefreshCapable, TagCapable, ClearCapable
29
{
30
    /**
31
     * @var ProxyClient[]
32
     */
33
    private $proxyClients;
34
35
    /**
36
     * MultiplexerClient constructor.
37
     *
38
     * @param ProxyClient[] $proxyClients The list of Proxy clients
39 8
     */
40
    public function __construct(array $proxyClients)
41 8
    {
42 8
        foreach ($proxyClients as $proxyClient) {
43 2
            if (!$proxyClient instanceof ProxyClient) {
44
                throw new InvalidArgumentException(
45 8
                    'Expected ProxyClientInterface, got: '.
46
                    (is_object($proxyClient) ? get_class($proxyClient) : gettype($proxyClient))
47
                );
48
            }
49
        }
50 6
51 6
        $this->proxyClients = $proxyClients;
52
    }
53
54
    /**
55
     * Forwards to all clients.
56
     *
57
     * @param array $headers HTTP headers that path must match to be banned
58
     *
59
     * @return $this
60 1
     */
61
    public function ban(array $headers)
62 1
    {
63
        $this->invoke(BanCapable::class, 'ban', [$headers]);
64 1
65
        return $this;
66
    }
67
68
    /**
69
     * Forwards to all clients.
70
     *
71
     * @param string       $path        Regular expression pattern for URI to invalidate
72
     * @param string       $contentType Regular expression pattern for the content type to limit banning, for instance
73
     *                                  'text'
74
     * @param array|string $hosts       Regular expression of a host name or list of exact host names to limit banning
75
     *
76
     * @return $this
77 1
     */
78
    public function banPath($path, $contentType = null, $hosts = null)
79 1
    {
80
        $this->invoke(BanCapable::class, 'banPath', [$path, $contentType, $hosts]);
81 1
82
        return $this;
83
    }
84
85
    /**
86
     * Forwards to all clients.
87
     *
88
     * @throws ExceptionCollection If any errors occurred during flush
89
     *
90
     * @return int The number of cache invalidations performed per caching server
91 1
     */
92
    public function flush()
93 1
    {
94 1
        $count = 0;
95 1
        foreach ($this->proxyClients as $proxyClient) {
96
            $count += $proxyClient->flush();
97
        }
98 1
99
        return $count;
100
    }
101
102
    /**
103
     * Forwards tag invalidation request to all clients.
104
     *
105
     * {@inheritdoc}
106
     *
107
     * @param array $tags
108
     *
109
     * @return $this
110 1
     */
111
    public function invalidateTags(array $tags)
112 1
    {
113
        $this->invoke(TagCapable::class, 'invalidateTags', [$tags]);
114 1
115
        return $this;
116
    }
117
118
    /**
119
     * Forwards to all clients.
120
     *
121
     * @param string $url     Path or URL to purge
122
     * @param array  $headers Extra HTTP headers to send to the caching proxy (optional)
123
     *
124
     * @return $this
125 1
     */
126
    public function purge($url, array $headers = [])
127 1
    {
128
        $this->invoke(PurgeCapable::class, 'purge', [$url, $headers]);
129 1
130
        return $this;
131
    }
132
133
    /**
134
     * Forwards to all clients.
135
     *
136
     * @param string $url     Path or URL to refresh
137
     * @param array  $headers Extra HTTP headers to send to the caching proxy (optional)
138
     *
139
     * @return $this
140 1
     */
141
    public function refresh($url, array $headers = [])
142 1
    {
143
        $this->invoke(RefreshCapable::class, 'refresh', [$url, $headers]);
144 1
145
        return $this;
146
    }
147
148
    /**
149
     * Forwards to all clients.
150
     *
151
     * @return $this
152
     */
153
    public function clear()
154
    {
155 5
        $this->invoke(ClearCapable::class, 'clear', []);
156
157 5
        return $this;
158 5
    }
159
160 5
    /**
161
     * Invoke the given $method on all available ProxyClients implementing the
162
     * given $interface.
163
     *
164
     * @param string $interface The FQN of the interface
165
     * @param string $method    The method to invoke
166
     * @param array  $arguments The arguments to be passed to the method
167
     */
168
    private function invoke($interface, $method, array $arguments)
169
    {
170
        foreach ($this->getProxyClients($interface) as $proxyClient) {
171
            call_user_func_array([$proxyClient, $method], $arguments);
172
        }
173
    }
174
175
    /**
176
     * Invoke the given $method on the first available ProxyClient implementing
177
     * the given $interface.
178
     *
179
     * @param string $interface The FQN of the interface
180
     * @param string $method    The method to invoke
181
     * @param array  $arguments The arguments to be passed to the method
182
     *
183
     * @return mixed Return value of ProxyClient method call
184
     *
185
     * @throws UnsupportedProxyOperationException
186
     */
187
    private function invokeFirst($interface, $method, array $arguments)
188
    {
189
        foreach ($this->getProxyClients($interface) as $proxyClient) {
190 5
            return call_user_func_array([$proxyClient, $method], $arguments);
191
        }
192 5
193 5
        throw UnsupportedProxyOperationException::cacheDoesNotImplement($interface);
194 5
    }
195 5
196 5
    /**
197
     * Get proxy clients that implement a feature interface.
198
     *
199
     * @param string $interface
200
     *
201
     * @return ProxyClient[]
202
     */
203
    private function getProxyClients($interface)
204
    {
205
        return array_filter(
206
            $this->proxyClients,
207
            function ($proxyClient) use ($interface) {
208
                return is_subclass_of($proxyClient, $interface);
209
            }
210
        );
211
    }
212
}
213