Passed
Push — master ( 4a0863...f9bf6d )
by Magnar Ovedal
03:47 queued 10s
created

IntegerDirective::fromString()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 9
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 18
ccs 10
cts 10
cp 1
crap 7
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stadly\Http\Header\Value\CacheControl;
6
7
use InvalidArgumentException;
8
use Stadly\Http\Utilities\Rfc7230;
9
use Stadly\Http\Utilities\Rfc7234;
10
11
/**
12
 * Class for handling cache control directives with integer value.
13
 *
14
 * Specification: https://tools.ietf.org/html/rfc7234#section-5.2.2
15
 */
16
final class IntegerDirective extends Directive
17
{
18
    public const RESERVED_NAMES = [
19
        'max-age',
20
        's-maxage',
21
    ];
22
23
    /**
24
     * @var string Value.
25
     */
26
    private $value;
27
28
    /**
29
     * Constructor.
30
     *
31
     * @param string $name Name.
32
     * @param string $value Value.
33
     */
34 7
    public function __construct(string $name, string $value)
35
    {
36 7
        $this->setName($name);
37 3
        $this->setValue($value);
38 1
    }
39
40
    /**
41
     * Construct directive from string.
42
     *
43
     * @param string $directive Directive string.
44
     * @return self Directive generated based on the string.
45
     */
46 7
    public static function fromString(string $directive): self
47
    {
48 7
        $regEx = '{^' . Rfc7234::CACHE_DIRECTIVE_CAPTURE . '$}';
49 7
        if (utf8_decode($directive) !== $directive || preg_match($regEx, $directive, $matches) !== 1) {
50 3
            throw new InvalidArgumentException('Invalid directive: ' . $directive);
51
        }
52
53 4
        if (!isset($matches['VALUE'])) {
54 1
            throw new InvalidArgumentException('Directive must have value');
55
        }
56
57 3
        $value = $matches['VALUE'];
58
        // Strip slashes if value is quoted.
59 3
        if (mb_strlen($value) >= 2 && mb_substr($value, 0, 1) === '"' && mb_substr($value, -1) === '"') {
60 2
            $value = stripslashes(mb_substr($value, 1, -1));
61
        }
62
63 3
        return new self($matches['NAME'], $value);
64
    }
65
66
    /**
67
     * @inheritDoc
68
     */
69 1
    public function __toString(): string
70
    {
71 1
        return $this->name . '=' . $this->value;
72
    }
73
74
    /**
75
     * @param string $name Name.
76
     */
77 5
    public function setName(string $name): void
78
    {
79 5
        if (utf8_decode($name) !== $name || preg_match('{^' . Rfc7230::TOKEN . '$}', $name) !== 1) {
80 2
            throw new InvalidArgumentException('Invalid name: ' . $name);
81
        }
82
83 5
        if (in_array(strtolower($name), FieldListDirective::RESERVED_NAMES, /*strict*/true)) {
84 1
            throw new InvalidArgumentException('Name reserved for field list directive: ' . $name);
85
        }
86 5
        if (in_array(strtolower($name), ValuelessDirective::RESERVED_NAMES, /*strict*/true)) {
87 1
            throw new InvalidArgumentException('Name reserved for valueless directive: ' . $name);
88
        }
89
90 5
        $this->name = $name;
91 5
    }
92
93
    /**
94
     * @return string Value.
95
     */
96 1
    public function getValue(): string
97
    {
98 1
        return $this->value;
99
    }
100
101
    /**
102
     * Set the value. It must be a non-negative integer string.
103
     *
104
     * @param string $value Value.
105
     */
106 3
    public function setValue(string $value): void
107
    {
108 3
        $regEx = '{^' . Rfc7234::DELTA_SECONDS . '$}';
109 3
        if (utf8_decode($value) !== $value || preg_match($regEx, $value) !== 1) {
110 2
            throw new InvalidArgumentException('Invalid value: ' . $value);
111
        }
112
113 3
        $this->value = $value;
114 3
    }
115
}
116