Completed
Push — master ( 4da634...5f9942 )
by Frederik
04:04
created

HeaderValue   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 94.44%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 2
dl 0
loc 103
ccs 34
cts 36
cp 0.9444
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A withParameter() 0 6 1
A getRaw() 0 4 1
A __toString() 0 5 1
A assertValid() 0 6 2
C validate() 0 25 7
A getParameter() 0 8 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Header;
5
6
/**
7
 * Class HeaderValue
8
 * @package Genkgo\Mail\Header
9
 */
10
final class HeaderValue
11
{
12
    /**
13
     * @var string
14
     */
15
    private $value;
16
    /**
17
     * @var array
18
     */
19
    private $parameters = [];
20
21
    /**
22
     * HeaderValue constructor.
23
     * @param string $value
24
     */
25 72
    public function __construct(string $value)
26
    {
27 72
        $this->assertValid($value);
28
29 69
        $this->value = $value;
30 69
    }
31
32
    /**
33
     * @param HeaderValueParameter $parameter
34
     * @return HeaderValue
35
     */
36 23
    public function withParameter(HeaderValueParameter $parameter): HeaderValue
37
    {
38 23
        $clone = clone $this;
39 23
        $clone->parameters[$parameter->getName()] = $parameter;
40 23
        return $clone;
41
    }
42
43
    /**
44
     * @return string
45
     */
46 2
    public function getRaw(): string
47
    {
48 2
        return $this->value;
49
    }
50
51
    /**
52
     * @return string
53
     */
54 59
    public function __toString(): string
55
    {
56 59
        $value = implode('; ', array_merge([$this->value], $this->parameters));
57 59
        return (string) (new OptimalEncodedHeaderValue($value));
58
    }
59
60
    /**
61
     * @param string $value
62
     */
63 72
    private function assertValid(string $value): void
64
    {
65 72
        if ($this->validate($value) === false) {
66 3
            throw new \InvalidArgumentException('Invalid header value ' . $value);
67
        }
68 69
    }
69
70
    /**
71
     * @param $value
72
     * @return bool
73
     */
74 72
    private function validate(string $value): bool
75
    {
76 72
        $total = strlen($value);
77
78 72
        for ($i = 0; $i < $total; $i += 1) {
79 72
            $ord = ord($value[$i]);
80 72
            if ($ord === 10) {
81 1
                return false;
82
            }
83 72
            if ($ord === 13) {
84 2
                if ($i + 2 >= $total) {
85
                    return false;
86
                }
87 2
                $lf = ord($value[$i + 1]);
88 2
                $sp = ord($value[$i + 2]);
89 2
                if ($lf !== 10 || ! in_array($sp, [9, 32], true)) {
90 2
                    return false;
91
                }
92
                // skip over the LF following this
93
                $i += 2;
94
            }
95
        }
96
97 69
        return true;
98
    }
99
100
    /**
101
     * @param string $name
102
     * @return HeaderValueParameter
103
     */
104 4
    public function getParameter(string $name): HeaderValueParameter
105
    {
106 4
        if (isset($this->parameters[$name])) {
107 4
            return $this->parameters[$name];
108
        }
109
110 2
        throw new \UnexpectedValueException('No parameter with name ' . $name);
111
    }
112
}