CacheControlHeader::isProxyReValidate()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/*
3
 * This file is part of the Borobudur-Http package.
4
 *
5
 * (c) Hexacodelabs <http://hexacodelabs.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Borobudur\Http\Header;
12
13
use Borobudur\Http\Header\Exception\InvalidHeaderValueException;
14
15
/**
16
 * @author      Iqbal Maulana <[email protected]>
17
 * @created     7/19/15
18
 */
19
class CacheControlHeader implements HeaderInterface
20
{
21
    /**
22
     * @var array
23
     */
24
    private $directives = array();
25
    
26
    /**
27
     * Constructor.
28
     *
29
     * @param array $directives
30
     */
31
    public function __construct(array $directives = array())
32
    {
33
        foreach ($directives as $key => $value) {
34
            if (is_int($key)) {
35
                $key = $value;
36
                $value = null;
37
            }
38
39
            $this->setDirective($key, $value);
40
        }
41
    }
42
    
43
    /**
44
     * Add cache directive, some directive don't have any value.
45
     * Example: no-store, must-revalidate, etc.
46
     *
47
     * @param string      $key
48
     * @param string|null $value
49
     *
50
     * @return $this
51
     */
52
    public function setDirective($key, $value = null)
53
    {
54
        $maps = array(
55
            'public'   => 'setPublic',
56
            'private'  => 'setPrivate',
57
            'max-age'  => 'setMaxAge',
58
            's-maxage' => 'setSharedMaxAge',
59
        );
60
61
        if (isset($maps[$key])) {
62
            return $this->{$maps[$key]}($value);
63
        }
64
65
        return $this->set($key, $value);
66
    }
67
    
68
    /**
69
     * Set cache as public.
70
     *
71
     * @return $this
72
     */
73
    public function setPublic()
74
    {
75
        if ($this->isPrivate()) {
76
            $this->removeDirective('private');
77
        }
78
        
79
        return $this->set('public');
80
    }
81
    
82
    /**
83
     * Check if cache private.
84
     *
85
     * @return bool
86
     */
87
    public function isPrivate()
88
    {
89
        return $this->hasDirective('private');
90
    }
91
92
    /**
93
     * Set auto privilege.
94
     *
95
     * @return $this
96
     */
97
    public function setAutoPrivilege()
98
    {
99
        if ($this->isHasPrivileges()) {
100
            return $this;
101
        }
102
103
        if (null === $this->getSharedMaxAge()) {
104
            return $this->setPrivate();
105
        }
106
107
        return $this->setPublic();
108
    }
109
110
    /**
111
     * Check if cache has privileges directive.
112
     *
113
     * @return bool
114
     */
115
    public function isHasPrivileges()
116
    {
117
        return $this->isPublic() || $this->isPrivate();
118
    }
119
    
120
    /**
121
     * Check if directive exist.
122
     *
123
     * @param string $key
124
     *
125
     * @return bool Return true if directive exist, false otherwise
126
     */
127
    public function hasDirective($key)
128
    {
129
        return array_key_exists($key, $this->directives);
130
    }
131
    
132
    /**
133
     * Remove directive by key.
134
     *
135
     * @param string $key
136
     *
137
     * @return $this
138
     */
139
    public function removeDirective($key)
140
    {
141
        unset($this->directives[$key]);
142
        
143
        return $this;
144
    }
145
    
146
    /**
147
     * Set directive.
148
     *
149
     * @param string      $key
150
     * @param string|null $value
151
     *
152
     * @return $this
153
     *
154
     * @throws InvalidHeaderValueException
155
     */
156
    private function set($key, $value = null)
157
    {
158
        GenericHeader::assertHeaderValue($key);
159
        if (null !== $value) {
160
            GenericHeader::assertHeaderValue($value);
161
        }
162
        
163
        $this->directives[$key] = $value;
164
        
165
        return $this;
166
    }
167
    
168
    /**
169
     * Set cache as private.
170
     *
171
     * @param string|null $value
172
     *
173
     * @return $this
174
     */
175
    public function setPrivate($value = null)
176
    {
177
        if ($this->isPublic()) {
178
            $this->removeDirective('public');
179
        }
180
        
181
        return $this->set('private', $value);
182
    }
183
    
184
    /**
185
     * Check if cache is public.
186
     *
187
     * @return bool
188
     */
189
    public function isPublic()
190
    {
191
        return $this->hasDirective('public');
192
    }
193
    
194
    /**
195
     * Set cache max-age.
196
     *
197
     * @param int $deltaSeconds
198
     *
199
     * @return $this
200
     */
201
    public function setMaxAge($deltaSeconds)
202
    {
203
        return $this->setDeltaSeconds('max-age', $deltaSeconds);
204
    }
205
    
206
    /**
207
     * Set shared max age.
208
     *
209
     * @param int $deltaSeconds
210
     *
211
     * @return $this
212
     */
213
    public function setSharedMaxAge($deltaSeconds)
214
    {
215
        return $this->setDeltaSeconds('s-maxage', $deltaSeconds);
216
    }
217
    
218
    /**
219
     * Factory create CacheControlHeader from string representation.
220
     *
221
     * @param string $headerLine
222
     *
223
     * @return $this
224
     */
225
    public static function fromString($headerLine)
226
    {
227
        list($fieldName, $fieldValue) = GenericHeader::splitHeaderLine($headerLine);
228
        GenericHeader::assertHeaderFieldName('Cache-Control', $fieldName);
229
        preg_match_all('#((("[^"\']++")|(\'[^"\']++\'))|[^,"\'])+#', $fieldValue, $matches);
230
        $directives = array();
231
232
        foreach ($matches[0] as $item) {
233
            $pos = strpos($item, '=');
234
235
            if (false === $pos) {
236
                $directives[$item] = null;
237
                continue;
238
            }
239
            
240
            $directives[substr($item, 0, $pos)] = substr($item, $pos + 1);
241
        }
242
        
243
        return new static($directives);
244
    }
245
    
246
    /**
247
     * Add no-cache directive.
248
     *
249
     * @param string|null $value
250
     *
251
     * @return $this
252
     */
253
    public function setNoCache($value = null)
254
    {
255
        return $this->set('no-cache', $value);
256
    }
257
    
258
    /**
259
     * Check if no cached.
260
     *
261
     * @return bool
262
     */
263
    public function isNoCache()
264
    {
265
        return $this->hasDirective('no-cache');
266
    }
267
    
268
    /**
269
     * Add no-store directive.
270
     *
271
     * @return $this
272
     */
273
    public function setNoStore()
274
    {
275
        return $this->set('no-store');
276
    }
277
    
278
    /**
279
     * Check if no stored.
280
     *
281
     * @return bool
282
     */
283
    public function isNoStored()
284
    {
285
        return $this->hasDirective('no-store');
286
    }
287
    
288
    /**
289
     * Set proxy-revalidate.
290
     *
291
     * @return $this
292
     */
293
    public function setProxyReValidate()
294
    {
295
        return $this->set('proxy-revalidate');
296
    }
297
    
298
    /**
299
     * Check is proxy-revalidate.
300
     *
301
     * @return bool
302
     */
303
    public function isProxyReValidate()
304
    {
305
        return $this->hasDirective('proxy-revalidate');
306
    }
307
    
308
    /**
309
     * Cache should re-validate.
310
     *
311
     * @return $this
312
     */
313
    public function setMustReValidate()
314
    {
315
        return $this->set('must-revalidate');
316
    }
317
    
318
    /**
319
     * Check if cache must re-validate.
320
     *
321
     * @return bool
322
     */
323
    public function isMustReValidate()
324
    {
325
        return $this->hasDirective('must-revalidate');
326
    }
327
    
328
    /**
329
     * Set no-transform.
330
     *
331
     * @return $this
332
     */
333
    public function setNoTransform()
334
    {
335
        return $this->set('no-transform');
336
    }
337
    
338
    /**
339
     * Check if cache is no-transform.
340
     *
341
     * @return bool
342
     */
343
    public function isNoTransform()
344
    {
345
        return $this->hasDirective('no-transform');
346
    }
347
    
348
    /**
349
     * Get max-age.
350
     *
351
     * @return int|null
352
     */
353
    public function getMaxAge()
354
    {
355
        return $this->getDirective('max-age');
356
    }
357
    
358
    /**
359
     * Get directive by key.
360
     *
361
     * @param string $key
362
     *
363
     * @return string|null
364
     */
365
    public function getDirective($key)
366
    {
367
        return $this->hasDirective($key) ? $this->directives[$key] : null;
368
    }
369
    
370
    /**
371
     * Get shared max age.
372
     *
373
     * @return int|null
374
     */
375
    public function getSharedMaxAge()
376
    {
377
        return $this->getDirective('s-maxage');
378
    }
379
    
380
    /**
381
     * Get all directives.
382
     *
383
     * @return array
384
     */
385
    public function allDirectives()
386
    {
387
        return $this->directives;
388
    }
389
    
390
    /**
391
     * Cast header to string.
392
     *
393
     * @return string
394
     */
395
    public function __toString()
396
    {
397
        return sprintf('%s: %s', $this->getFieldName(), $this->getFieldValue());
398
    }
399
    
400
    /**
401
     * Get header field name.
402
     *
403
     * @return string
404
     */
405
    public function getFieldName()
406
    {
407
        return 'Cache-Control';
408
    }
409
    
410
    /**
411
     * Get header field value.
412
     *
413
     * @return mixed
414
     */
415
    public function getFieldValue()
416
    {
417
        ksort($this->directives);
418
        
419
        return implode(',', array_map(function ($key, $value = null) {
420
            
421
            if (null === $value) {
422
                return $key;
423
            }
424
            
425
            return $key . '=' . $value;
426
        }, array_keys($this->directives), $this->directives));
427
    }
428
429
    /**
430
     * Set delta second to specified key.
431
     *
432
     * @param string $key
433
     * @param int    $deltaSeconds
434
     *
435
     * @return $this
436
     */
437
    private function setDeltaSeconds($key, $deltaSeconds)
438
    {
439
        $this->set($key, GenericHeader::computeDeltaSeconds($deltaSeconds));
440
441
        return $this;
442
    }
443
}
444