CacheControl   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 27
c 1
b 0
f 0
dl 0
loc 123
ccs 35
cts 35
cp 1
rs 10
wmc 17

10 Methods

Rating   Name   Duplication   Size   Complexity  
A isValid() 0 3 1
A hasDirective() 0 3 1
A getDirective() 0 7 2
A getName() 0 3 1
A unsetDirective() 0 4 2
A __toString() 0 3 1
A getValue() 0 7 2
A setDirective() 0 4 2
A __construct() 0 3 1
A fromValue() 0 17 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stadly\Http\Header\Response;
6
7
use OutOfBoundsException;
8
use Stadly\Http\Exception\InvalidHeader;
9
use Stadly\Http\Header\Value\CacheControl\Directive;
10
use Stadly\Http\Utilities\Rfc7234;
11
12
/**
13
 * Class for handling the HTTP header field Cache-Control.
14
 *
15
 * Specification: https://tools.ietf.org/html/rfc7234#section-5.2
16
 */
17
final class CacheControl implements Header
18
{
19
    /**
20
     * @var array<Directive> Directives.
21
     */
22
    private $directives = [];
23
24
    /**
25
     * Constructor.
26
     *
27
     * @param Directive ...$directives Directives.
28
     */
29 3
    public function __construct(Directive ...$directives)
30
    {
31 3
        $this->setDirective(...$directives);
32
    }
33
34
    /**
35
     * Construct header from value.
36
     *
37
     * @param string $value Header value.
38
     * @return self Header generated based on the value.
39
     * @throws InvalidHeader If the header value is invalid.
40
     */
41 6
    public static function fromValue(string $value): self
42
    {
43 6
        $regEx = '{^' . Rfc7234::CACHE_CONTROL . '$}';
44 6
        $plainValue = mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8');
45 6
        if ($plainValue !== $value || preg_match($regEx, $value) !== 1) {
46 2
            throw new InvalidHeader('Invalid header value: ' . $value);
47
        }
48
49 4
        $directiveRegEx = '{' . Rfc7234::CACHE_DIRECTIVE_CAPTURE . '}';
50 4
        preg_match_all($directiveRegEx, $value, $matches);
51
52 4
        $directives = [];
53 4
        foreach ($matches['CACHE_DIRECTIVE'] as $directive) {
54 4
            $directives[] = Directive::fromString($directive);
55
        }
56
57 4
        return new self(...$directives);
58
    }
59
60
    /**
61
     * @inheritDoc
62
     */
63 3
    public function __toString(): string
64
    {
65 3
        return $this->getName() . ': ' . $this->getValue();
66
    }
67
68
    /**
69
     * @inheritDoc
70
     */
71 2
    public function isValid(): bool
72
    {
73 2
        return $this->directives !== [];
74
    }
75
76
    /**
77
     * @inheritDoc
78
     */
79 1
    public function getName(): string
80
    {
81 1
        return 'Cache-Control';
82
    }
83
84
    /**
85
     * @inheritDoc
86
     */
87 3
    public function getValue(): string
88
    {
89 3
        if ($this->directives === []) {
90 1
            throw new InvalidHeader('Header has no directives.');
91
        }
92
93 2
        return implode(', ', $this->directives);
94
    }
95
96
    /**
97
     * @param string $name Directive name.
98
     * @return bool Whether the directive exists.
99
     */
100 2
    public function hasDirective(string $name): bool
101
    {
102 2
        return array_key_exists(strtolower($name), $this->directives);
103
    }
104
105
    /**
106
     * @param string $name Directive name.
107
     * @return Directive Directive.
108
     * @throws OutOfBoundsException If the directive does not exist.
109
     */
110 2
    public function getDirective(string $name): Directive
111
    {
112 2
        if (!$this->hasDirective($name)) {
113 1
            throw new OutOfBoundsException('Directive not found: ' . $name);
114
        }
115
116 1
        return $this->directives[strtolower($name)];
117
    }
118
119
    /**
120
     * Set directives.
121
     *
122
     * @param Directive ...$directives Directives to set.
123
     */
124 7
    public function setDirective(Directive ...$directives): void
125
    {
126 7
        foreach ($directives as $directive) {
127 7
            $this->directives[strtolower($directive->getName())] = $directive;
128
        }
129
    }
130
131
    /**
132
     * Unset directives.
133
     *
134
     * @param string ...$names Directive names.
135
     */
136 4
    public function unsetDirective(string ...$names): void
137
    {
138 4
        foreach ($names as $name) {
139 4
            unset($this->directives[strtolower($name)]);
140
        }
141
    }
142
}
143