Passed
Push — master ( fedff9...360060 )
by Magnar Ovedal
07:05
created

IfRange   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 28
c 1
b 0
f 0
dl 0
loc 123
ccs 36
cts 36
cp 1
rs 10
wmc 21

9 Methods

Rating   Name   Duplication   Size   Complexity  
A fromValue() 0 20 6
A isValid() 0 3 1
A setValidator() 0 7 2
A getName() 0 3 1
A getValidator() 0 3 1
A __construct() 0 7 2
A evaluate() 0 13 6
A getValue() 0 3 1
A __toString() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stadly\Http\Header\Request;
6
7
use InvalidArgumentException;
8
use Stadly\Http\Exception\InvalidHeader;
9
use Stadly\Http\Header\Value\Date;
10
use Stadly\Http\Header\Value\EntityTag\EntityTag;
11
use Stadly\Http\Utilities\Rfc7231;
12
use Stadly\Http\Utilities\Rfc7232;
13
14
/**
15
 * Class for handling the HTTP header field If-Range.
16
 *
17
 * Specification: https://tools.ietf.org/html/rfc7233#section-3.2
18
 */
19
final class IfRange implements Header
20
{
21
    /**
22
     * @var EntityTag|Date Strong validator.
23
     */
24
    private $validator;
25
26
    /**
27
     * Constructor.
28
     *
29
     * @param EntityTag|Date $validator Strong validator.
30
     */
31 4
    public function __construct($validator)
32
    {
33 4
        if ($validator->isWeak()) {
34 2
            throw new InvalidArgumentException('Validator must be strong: ' . $validator);
35
        }
36
37 2
        $this->validator = $validator;
38 2
    }
39
40
    /**
41
     * Construct header from value.
42
     *
43
     * @param string $value Header value.
44
     * @return self Header generated based on the value.
45
     * @throws InvalidHeader If the header value is invalid.
46
     */
47 4
    public static function fromValue(string $value): self
48
    {
49 4
        $entityTagRegEx = '{^' . Rfc7232::ENTITY_TAG . '$}';
50 4
        if (utf8_decode($value) === $value && preg_match($entityTagRegEx, $value) === 1) {
51 2
            $entityTag = EntityTag::fromString($value);
52
53
            // Validator must be strong.
54 2
            if ($entityTag->isWeak()) {
55 1
                throw new InvalidHeader('Validator must be strong: ' . $value);
56
            }
57
58 1
            return new self($entityTag);
59
        }
60
61 2
        $dateRegEx = '{^' . Rfc7231::HTTP_DATE . '$}';
62 2
        if (utf8_decode($value) === $value && preg_match($dateRegEx, $value) === 1) {
63 1
            return new self(Date::fromString($value, /*isWeak*/false));
64
        }
65
66 1
        throw new InvalidHeader('Invalid header value: ' . $value);
67
    }
68
69
    /**
70
     * @inheritDoc
71
     * @throws void The header is always valid.
72
     */
73 2
    public function __toString(): string
74
    {
75 2
        return $this->getName() . ': ' . $this->getValue();
76
    }
77
78
    /**
79
     * @return true The header is always valid.
80
     */
81 1
    public function isValid(): bool
82
    {
83 1
        return true;
84
    }
85
86
    /**
87
     * @inheritDoc
88
     */
89 1
    public function getName(): string
90
    {
91 1
        return 'If-Range';
92
    }
93
94
    /**
95
     * @inheritDoc
96
     * @throws void The header is always valid.
97
     */
98 2
    public function getValue(): string
99
    {
100 2
        return (string)$this->validator;
101
    }
102
103
    /**
104
     * @param EntityTag|Date|null $validator Validator. Should be a strong entity tag or date, or null if unknown.
105
     * @return bool Whether the condition is satisfied by the validator.
106
     */
107 11
    public function evaluate($validator): bool
108
    {
109 11
        if ($validator instanceof EntityTag && $this->validator instanceof EntityTag) {
110
            // Entity tags must be strong.
111 3
            return $this->validator->compareStrongly($validator);
112
        }
113
114 8
        if ($validator instanceof Date && $this->validator instanceof Date) {
115
            // Dates must be strong and match exactly.
116 4
            return !$validator->isWeak() && $this->validator->isEq($validator);
117
        }
118
119 4
        return false;
120
    }
121
122
    /**
123
     * @return EntityTag|Date Strong validator.
124
     */
125 1
    public function getValidator()
126
    {
127 1
        return $this->validator;
128
    }
129
130
    /**
131
     * Set validator.
132
     *
133
     * @param EntityTag|Date $validator Strong validator.
134
     */
135 4
    public function setValidator($validator): void
136
    {
137 4
        if ($validator->isWeak()) {
138 2
            throw new InvalidArgumentException('Validator must be strong: ' . $validator);
139
        }
140
141 2
        $this->validator = $validator;
142 2
    }
143
}
144