Completed
Pull Request — master (#376)
by David
04:50
created

HttpProxyClient   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 4
dl 0
loc 137
ccs 42
cts 42
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A flush() 0 4 1
A configureOptions() 0 4 1
A escapeTags() 0 8 1
A queueRequest() 0 7 1
A __construct() 0 9 2
B splitLongHeaderValue() 0 31 5
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 Http\Discovery\MessageFactoryDiscovery;
15
use Http\Message\RequestFactory;
16
use Psr\Http\Message\UriInterface;
17
use Symfony\Component\OptionsResolver\OptionsResolver;
18
19
/**
20
 * Base class for HTTP based caching proxy client.
21
 *
22
 * @author David de Boer <[email protected]>
23
 */
24
abstract class HttpProxyClient implements ProxyClient
25
{
26
    /**
27
     * Dispatcher for invalidation HTTP requests.
28
     *
29
     * @var HttpDispatcher
30
     */
31
    private $httpDispatcher;
32
33
    /**
34
     * @var RequestFactory
35
     */
36
    private $requestFactory;
37
38
    /**
39
     * The options configured in the constructor argument or default values.
40
     *
41
     * @var array The resolved options
42
     */
43
    protected $options;
44
45
    /**
46
     * Constructor.
47
     *
48
     * The base class has no options.
49
     *
50
     * @param HttpDispatcher      $httpDispatcher Helper to send HTTP requests to caching proxy
51
     * @param array               $options        Options for this client
52
     * @param RequestFactory|null $messageFactory Factory for PSR-7 messages. If none supplied,
53
     *                                            a default one is created
54
     */
55 33
    public function __construct(
56
        HttpDispatcher $httpDispatcher,
57
        array $options = [],
58 1
        RequestFactory $messageFactory = null
59 1
    ) {
60 33
        $this->httpDispatcher = $httpDispatcher;
61 33
        $this->options = $this->configureOptions()->resolve($options);
62 33
        $this->requestFactory = $messageFactory ?: MessageFactoryDiscovery::find();
63 33
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 21
    public function flush()
69
    {
70 21
        return $this->httpDispatcher->flush();
71
    }
72
73
    /**
74
     * Get options resolver with default settings.
75
     *
76
     * @return OptionsResolver
77
     */
78 33
    protected function configureOptions()
79
    {
80 33
        return new OptionsResolver();
81
    }
82
83
    /**
84
     * Create a request and queue it with the HTTP dispatcher.
85
     *
86
     * @param string              $method
87
     * @param string|UriInterface $url
88
     * @param array               $headers
89
     * @param bool                $validateHost see HttpDispatcher::invalidate
90
     */
91 31
    protected function queueRequest($method, $url, array $headers, $validateHost = true)
92
    {
93 31
        $this->httpDispatcher->invalidate(
94 31
            $this->requestFactory->createRequest($method, $url, $headers),
95
            $validateHost
96 31
        );
97 31
    }
98
99
    /**
100
     * Make sure that the tags are valid.
101
     *
102
     * Reusable function for proxy clients.
103
     * Escapes `,` and `\n` (newline) characters.
104
     *
105
     * @param array $tags The tags to escape
106
     *
107
     * @return array Sane tags
108
     */
109
    protected function escapeTags(array $tags)
110
    {
111 6
        array_walk($tags, function (&$tag) {
112 6
            $tag = str_replace([',', "\n"], ['_', '_'], $tag);
113 6
        });
114
115 6
        return $tags;
116
    }
117
118
    /**
119
     * Splits a header value into an array of values. E.g. useful for tag
120
     * invalidation requests where you might need multiple requests if you
121
     * want to invalidate too many cache tags (so the header would get too long).
122
     *
123
     * @param string $value
124
     * @param int    $length
125
     * @param string $delimiter
126
     *
127
     * @return array
128
     */
129 2
    protected function splitLongHeaderValue($value, $length = 7500, $delimiter = ',')
130
    {
131 2
        if (mb_strlen($value) <= $length) {
132 1
            return [$value];
133
        }
134
135 1
        $tmp = [];
136 1
        $chunks = explode($delimiter, $value);
137 1
        $currentLength = 0;
138 1
        $index = 0;
139
140 1
        foreach ($chunks as $chunk) {
141 1
            $chunkLength = mb_strlen($chunk) + 1;
142
143 1
            if (($currentLength + $chunkLength) <= $length) {
144 1
                $tmp[$index][] = $chunk;
145 1
                $currentLength += $chunkLength;
146 1
            } else {
147 2
                ++$index;
148 1
                $currentLength = $chunkLength;
149 1
                $tmp[$index][] = $chunk;
150
            }
151 1
        }
152
153 1
        $result = [];
154 1
        foreach ($tmp as $values) {
155 1
            $result[] = implode($delimiter, $values);
156 1
        }
157
158 1
        return $result;
159
    }
160
}
161