CacheControl::hasNoCache()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * PSR-7 Cache Helpers
4
 *
5
 * @copyright Copyright (c) 2016, Michel Hunziker <[email protected]>
6
 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD-3-Clause License
7
 */
8
9
namespace Micheh\Cache\Header;
10
11
use InvalidArgumentException;
12
13
/**
14
 * Base class for the Cache-Control header.
15
 */
16
abstract class CacheControl
17
{
18
    /**
19
     * @var array
20
     */
21
    private $directives = [];
22
23
    /**
24
     * @var array
25
     */
26
    private static $commonMethods = [
27
        'max-age' => 'withMaxAge',
28
        'no-cache' => 'withNoCache',
29
        'no-store' => 'withNoStore',
30
        'no-transform' => 'withNoTransform',
31
    ];
32
33
    /**
34
     * @var array Maps the directive names to the methods
35
     */
36
    protected static $directiveMethods = [];
37
38
    /**
39
     * Create a new Cache-Control object from a header string.
40
     *
41
     * @param string $string
42
     * @return static
43
     */
44 6
    protected static function createFromString($string)
45
    {
46 6
        $cacheControl = new static();
47
48 6
        $parts = explode(',', $string);
49 6
        foreach ($parts as $part) {
50 6
            $index = strpos($part, '=');
51 6
            if ($index !== false) {
52 4
                $directive = substr($part, 0, $index);
53 4
                $value = trim(substr($part, $index + 1));
54 4
            } else {
55 3
                $directive = $part;
56 3
                $value = true;
57
            }
58
59 6
            $directive = trim($directive);
60 6
            $method = self::getMethod($directive);
61
62 6
            if ($method === null && $value === true) {
63
                // Ignore unknown flag
64 1
                continue;
65
            }
66
67
            $cacheControl = $method
68 5
                ? $cacheControl->$method($value)
69 5
                : $cacheControl->withExtension($directive, $value);
70 6
        }
71
72 6
        return $cacheControl;
73
    }
74
75
    /**
76
     * Set how many seconds to cache.
77
     *
78
     * @param int $seconds
79
     * @return static
80
     */
81 1
    public function withMaxAge($seconds)
82
    {
83 1
        return $this->withDirective('max-age', (int) $seconds);
84
    }
85
86
    /**
87
     * @return int|null
88
     */
89 1
    public function getMaxAge()
90
    {
91 1
        return $this->getDirective('max-age');
92
    }
93
94
    /**
95
     * Set whether a representation should be cached.
96
     *
97
     * @param bool $flag
98
     * @return static
99
     */
100 1
    public function withNoCache($flag = true)
101
    {
102 1
        return $this->withDirective('no-cache', (bool) $flag);
103
    }
104
105
    /**
106
     * @return bool
107
     */
108 1
    public function hasNoCache()
109
    {
110 1
        return $this->hasDirective('no-cache');
111
    }
112
113
    /**
114
     * Set whether a representation should be stored.
115
     *
116
     * @param bool $flag
117
     * @return static
118
     */
119 1
    public function withNoStore($flag = true)
120
    {
121 1
        return $this->withDirective('no-store', (bool) $flag);
122
    }
123
124
    /**
125
     * @return bool
126
     */
127 1
    public function hasNoStore()
128
    {
129 1
        return $this->hasDirective('no-store');
130
    }
131
132
    /**
133
     * Set whether the payload can be transformed.
134
     *
135
     * @param bool $flag
136
     * @return static
137
     */
138 1
    public function withNoTransform($flag = true)
139
    {
140 1
        return $this->withDirective('no-transform', (bool) $flag);
141
    }
142
143
    /**
144
     * @return bool
145
     */
146 1
    public function hasNoTransform()
147
    {
148 1
        return $this->hasDirective('no-transform');
149
    }
150
151
    /**
152
     * Add a custom extension directive to the Cache-Control.
153
     *
154
     * @param string $name Name of the directive
155
     * @param string $value Value of the directive as a string
156
     * @return static
157
     * @throws InvalidArgumentException If the name or the value of the directive is not a string
158
     */
159 2
    public function withExtension($name, $value)
160
    {
161 2
        if (!is_string($name) || !is_string($value)) {
162 1
            throw new InvalidArgumentException('Name and value of the extension have to be a string.');
163
        }
164
165 1
        return $this->withDirective($name, trim($value, '" '));
166
    }
167
168
    /**
169
     * @param string $name
170
     * @return string|null
171
     */
172 1
    public function getExtension($name)
173
    {
174 1
        return $this->getDirective($name);
175
    }
176
177
    /**
178
     * @return string Header string, which can added to the response.
179
     */
180 5
    public function __toString()
181
    {
182 5
        $parts = [];
183 5
        foreach ($this->directives as $directive => $value) {
184 4
            if ($value === true) {
185 2
                $parts[] = $directive;
186 2
                continue;
187
            }
188
189 3
            if (is_string($value)) {
190 1
                $value = '"' . $value . '"';
191 1
            }
192
193 3
            $parts[] = $directive . '=' . $value;
194 5
        }
195
196 5
        return implode(', ', $parts);
197
    }
198
199
    /**
200
     * Set a directive with the provided name and value.
201
     *
202
     * @param string $name Name of the directive
203
     * @param string|int|bool|null $value Value of the directive
204
     * @return static
205
     */
206 6
    protected function withDirective($name, $value)
207
    {
208 6
        $clone = clone($this);
209
210 6
        if (is_numeric($value)) {
211 1
            $value = max(0, (int) $value);
212 1
        }
213
214 6
        if ($value !== null && $value !== false) {
215 5
            $clone->directives[$name] = $value;
216 5
            return $clone;
217
        }
218
219 3
        if ($clone->hasDirective($name)) {
220 2
            unset($clone->directives[$name]);
221 2
        }
222
223 3
        return $clone;
224
    }
225
226
    /**
227
     * Returns true if the Cache-Control has a directive and false otherwise.
228
     *
229
     * @param string $name Name of the directive
230
     * @return bool
231
     */
232 2
    protected function hasDirective($name)
233
    {
234 2
        return array_key_exists($name, $this->directives);
235
    }
236
237
    /**
238
     * Returns the directive value if available, or `null` if not available.
239
     *
240
     * @param string $name Name of the directive
241
     * @return string|int|null
242
     */
243 2
    protected function getDirective($name)
244
    {
245 2
        if ($this->hasDirective($name)) {
246 1
            return $this->directives[$name];
247
        }
248
249 1
        return null;
250
    }
251
252
    /**
253
     * Returns the method name to set the provided directive. If the directive cannot be set, the
254
     * method returns `null`.
255
     *
256
     * @param string $directive Name of the directive
257
     * @return string|null
258
     */
259 6
    private static function getMethod($directive)
260
    {
261 6
        if (isset(static::$directiveMethods[$directive])) {
262 1
            return static::$directiveMethods[$directive];
263
        }
264
265 5
        if (isset(self::$commonMethods[$directive])) {
266 3
            return self::$commonMethods[$directive];
267
        }
268
269 2
        return null;
270
    }
271
}
272