Passed
Pull Request — master (#31)
by Anatoly
39:30
created

header_accept_parse()   D

Complexity

Conditions 30
Paths 9

Size

Total Lines 103
Code Lines 73

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 930

Importance

Changes 0
Metric Value
cc 30
eloc 73
c 0
b 0
f 0
nc 9
nop 1
dl 0
loc 103
ccs 0
cts 73
cp 0
crap 930
rs 4.1666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Nekhay <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Nekhay
8
 * @license https://github.com/sunrise-php/http-message/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-message
10
 */
11
12
namespace Sunrise\Http\Message;
13
14
/**
15
 * Import functions
16
 */
17
use function uasort;
18
19
/**
20
 * Parses the given Accept header
21
 *
22
 * @param string $header
23
 *
24
 * @return array<string, array<string, string>>
25
 */
26
function header_accept_parse(string $header): array
27
{
28
    static $cache = [];
29
30
    if (isset($cache[$header])) {
31
        return $cache[$header];
32
    }
33
34
    $cursor = -1;
35
    $cursorInValue = true;
36
    $cursorInParameter = false;
37
    $cursorInParameterName = false;
38
    $cursorInParameterValue = false;
39
    $cursorInQuotedParameterValue = false;
40
41
    $data = [];
42
    $valueIndex = 0;
43
    $parameterIndex = 0;
44
45
    while (true) {
46
        $char = $header[++$cursor] ?? null;
47
        $prev = $header[$cursor-1] ?? null;
48
        $next = $header[$cursor+1] ?? null;
49
50
        if ($char === null) {
51
            break;
52
        }
53
54
        if ($char === ' ' && !$cursorInQuotedParameterValue) {
55
            continue;
56
        }
57
58
        if ($char === ',' && !$cursorInQuotedParameterValue) {
59
            $cursorInValue = true;
60
            $cursorInParameter = false;
61
            $cursorInParameterName = false;
62
            $cursorInParameterValue = false;
63
            $cursorInQuotedParameterValue = false;
64
            $parameterIndex = 0;
65
            $valueIndex++;
66
            continue;
67
        }
68
        if ($char === ';' && !$cursorInQuotedParameterValue) {
69
            $cursorInValue = false;
70
            $cursorInParameter = true;
71
            $cursorInParameterName = true;
72
            $cursorInParameterValue = false;
73
            $cursorInQuotedParameterValue = false;
74
            $parameterIndex++;
75
            continue;
76
        }
77
        if ($char === '=' && !$cursorInQuotedParameterValue && $cursorInParameterName) {
78
            $cursorInValue = false;
79
            $cursorInParameter = true;
80
            $cursorInParameterName = false;
81
            $cursorInParameterValue = true;
82
            $cursorInQuotedParameterValue = false;
83
            continue;
84
        }
85
86
        if ($char === '"' && !$cursorInQuotedParameterValue && $cursorInParameterValue) {
87
            $cursorInQuotedParameterValue = true;
88
            continue;
89
        }
90
        if ($char === '\\' && $next === '"' && $cursorInQuotedParameterValue) {
91
            continue;
92
        }
93
        if ($char === '"' && $prev !== '\\' && $cursorInQuotedParameterValue) {
94
            $cursorInParameterValue = false;
95
            $cursorInQuotedParameterValue = false;
96
            continue;
97
        }
98
99
        if ($cursorInValue) {
100
            $data[$valueIndex][0] ??= '';
101
            $data[$valueIndex][0] .= $char;
102
            continue;
103
        }
104
        if ($cursorInParameterName && isset($data[$valueIndex][0])) {
105
            $data[$valueIndex][1][$parameterIndex][0] ??= '';
106
            $data[$valueIndex][1][$parameterIndex][0] .= $char;
107
            continue;
108
        }
109
        if ($cursorInParameterValue && isset($data[$valueIndex][1][$parameterIndex][0])) {
110
            $data[$valueIndex][1][$parameterIndex][1] ??= '';
111
            $data[$valueIndex][1][$parameterIndex][1] .= $char;
112
            continue;
113
        }
114
    }
115
116
    $result = [];
117
    foreach ($data as $item) {
118
        $result[$item[0]] = [];
119
        if (isset($item[1])) {
120
            foreach ($item[1] as $param) {
121
                $result[$item[0]][$param[0]] = $param[1] ?? '';
122
            }
123
        }
124
    }
125
126
    uasort($result, fn(array $a, array $b): int => ($b['q'] ?? 1) <=> ($a['q'] ?? 1));
127
128
    return $cache[$header] = $result;
129
}
130