Completed
Push — master ( f5da3a...e4ac8c )
by David
12s
created

ResponseTagger   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

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

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 17 1
A getTagsHeaderName() 0 4 1
A getTagsHeaderValue() 0 4 1
A hasTags() 0 4 1
A addTags() 0 12 3
A clear() 0 4 1
A tagResponse() 0 15 3
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;
13
14
use FOS\HttpCache\Exception\InvalidTagException;
15
use FOS\HttpCache\TagHeaderFormatter\CommaSeparatedTagHeaderFormatter;
16
use FOS\HttpCache\TagHeaderFormatter\TagHeaderFormatter;
17
use Psr\Http\Message\ResponseInterface;
18
use Symfony\Component\OptionsResolver\Options;
19
use Symfony\Component\OptionsResolver\OptionsResolver;
20
21
/**
22
 * Service for Response cache tagging.
23
 *
24
 * Record tags with this class and then either get the tags header or have the
25
 * tagger add the tags to a PSR-7 response.
26
 * Recorded tags are cleared after tagging a response.
27
 *
28
 * @author David de Boer <[email protected]>
29
 * @author David Buchmann <[email protected]>
30
 * @author André Rømcke <[email protected]>
31
 * @author Wicliff Wolda <[email protected]>
32
 * @author Yanick Witschi <[email protected]>
33
 */
34
class ResponseTagger
35
{
36
    /**
37
     * @var array
38
     */
39
    private $options;
40
41
    /**
42
     * @var TagHeaderFormatter
43
     */
44
    private $headerFormatter;
45
46
    /**
47
     * @var array
48
     */
49
    private $tags = [];
50
51
    /**
52
     * Create the response tagger with a tag header formatter and options.
53
     *
54
     * Supported options are:
55
     *
56
     * - header_formatter (TagHeaderFormatter) Default: CommaSeparatedTagHeaderFormatter with default header name
57 7
     * - strict (bool) Default: false. If set to true, throws exception when adding empty tags
58
     *
59 7
     * @param array $options
60 7
     */
61
    public function __construct(array $options = [])
62 7
    {
63 1
        $resolver = new OptionsResolver();
64 7
        $resolver->setDefaults([
65
            // callback to avoid instantiating the formatter when its not needed
66
            'header_formatter' => function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
67
                return new CommaSeparatedTagHeaderFormatter();
68 7
            },
69 7
            'strict' => false,
70
        ]);
71 7
72 7
        $resolver->setAllowedTypes('header_formatter', TagHeaderFormatter::class);
73 7
        $resolver->setAllowedTypes('strict', 'bool');
74
75
        $this->options = $resolver->resolve($options);
76
        $this->headerFormatter = $this->options['header_formatter'];
77
    }
78
79
    /**
80 3
     * Get the HTTP header name that will hold cache tags.
81
     *
82 3
     * @return string
83
     */
84
    public function getTagsHeaderName()
85
    {
86
        return $this->headerFormatter->getTagsHeaderName();
87
    }
88
89
    /**
90
     * Get the value for the HTTP tag header.
91
     *
92 4
     * This concatenates all tags and ensures correct encoding.
93
     *
94 4
     * @return string
95
     */
96
    public function getTagsHeaderValue()
97
    {
98
        return $this->headerFormatter->getTagsHeaderValue($this->tags);
99
    }
100
101
    /**
102 5
     * Check whether the tag handler has any tags to set on the response.
103
     *
104 5
     * @return bool True if this handler will set at least one tag
105
     */
106
    public function hasTags()
107
    {
108
        return 0 < count($this->tags);
109
    }
110
111
    /**
112
     * Add tags to be set on the response.
113
     *
114
     * This must be called before any HTTP response is sent to the client.
115
     *
116
     * @param array $tags List of tags to add
117
     *
118 5
     * @throws InvalidTagException
119
     *
120 5
     * @return $this
121
     */
122 5
    public function addTags(array $tags)
123 1
    {
124
        $filtered = array_filter($tags, 'strlen');
125
126 4
        if ($this->options['strict'] && array_diff($tags, $filtered)) {
127
            throw new InvalidTagException('Empty tags are not allowed');
128 4
        }
129
130
        $this->tags = array_unique(array_merge($this->tags, $filtered));
131
132
        return $this;
133
    }
134
135
    /**
136
     * Remove all tags that have been recorded.
137
     *
138
     * This is usually called after adding the tags header to a response. It is
139
     * automatically called by the tagResponse method.
140 3
     */
141
    public function clear()
142 3
    {
143 1
        $this->tags = [];
144
    }
145
146 2
    /**
147 1
     * Set tags on a response and then clear the tags.
148
     *
149
     * @param ResponseInterface $response Original response
150 1
     * @param bool              $replace  Whether to replace the current tags
151
     *                                    on the response
152
     *
153
     * @return ResponseInterface Tagged response
154
     */
155
    public function tagResponse(ResponseInterface $response, $replace = false)
156
    {
157
        if (!$this->hasTags()) {
158
            return $response;
159
        }
160
161
        $tagsHeaderValue = $this->getTagsHeaderValue();
162
        $this->clear();
163
164
        if ($replace) {
165
            return $response->withHeader($this->getTagsHeaderName(), $tagsHeaderValue);
166
        }
167
168
        return $response->withAddedHeader($this->getTagsHeaderName(), $tagsHeaderValue);
169
    }
170
}
171