Passed
Push — main ( 404000...b70a85 )
by smiley
01:56
created

Header::normalize()   C

Complexity

Conditions 12
Paths 27

Size

Total Lines 59
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 28
c 1
b 0
f 0
nc 27
nop 1
dl 0
loc 59
rs 6.9666

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
2
/**
3
 * Class Header
4
 *
5
 * @created      28.03.2021
6
 * @author       smiley <[email protected]>
7
 * @copyright    2021 smiley
8
 * @license      MIT
9
 */
10
11
namespace chillerlan\HTTP\Psr7;
12
13
use function array_keys;
14
use function array_map;
15
use function array_values;
16
use function count;
17
use function explode;
18
use function implode;
19
use function is_array;
20
use function is_numeric;
21
use function is_string;
22
use function strtolower;
23
use function trim;
24
use function ucfirst;
25
26
/**
27
 *
28
 */
29
class Header{
30
31
	/**
32
	 * Normalizes an array of header lines to format ["Name" => "Value (, Value2, Value3, ...)", ...]
33
	 * An exception is being made for Set-Cookie, which holds an array of values for each cookie.
34
	 * For multiple cookies with the same name, only the last value will be kept.
35
	 *
36
	 * @param array $headers
37
	 *
38
	 * @return array
39
	 */
40
	public static function normalize(array $headers):array{
41
		$normalized = [];
42
43
		foreach($headers as $key => $val){
44
45
			// the key is numeric, so $val is either a string or an array
46
			if(is_numeric($key)){
47
48
				// "key: val"
49
				if(is_string($val)){
50
					$header = explode(':', $val, 2);
51
52
					if(count($header) !== 2){
53
						continue;
54
					}
55
56
					$key = $header[0];
57
					$val = $header[1];
58
				}
59
				// [$key, $val], ["key" => $key, "val" => $val]
60
				elseif(is_array($val)){
61
					$key = array_keys($val)[0];
62
					$val = array_values($val)[0];
63
				}
64
				else{
65
					continue;
66
				}
67
			}
68
			// the key is named, so we assume $val holds the header values only, either as string or array
69
			else{
70
				if(is_array($val)){
71
					$val = implode(', ', array_values($val));
72
				}
73
			}
74
75
			$key = implode('-', array_map(fn(string $v):string => ucfirst(strtolower(trim($v))), explode('-', $key)));
76
			$val = trim($val);
77
78
			// skip if the header already exists but the current value is empty
79
			if(isset($normalized[$key]) && empty($val)){
80
				continue;
81
			}
82
83
			// cookie headers may appear multiple times
84
			// https://tools.ietf.org/html/rfc6265#section-4.1.2
85
			if($key === 'Set-Cookie'){
86
				// i'll just collect the last value here and leave parsing up to you :P
87
				$normalized[$key][strtolower(explode('=', $val, 2)[0])] = $val;
88
			}
89
			// combine header fields with the same name
90
			// https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
91
			else{
92
				isset($normalized[$key]) && !empty($normalized[$key])
93
					? $normalized[$key] .= ', '.$val
94
					: $normalized[$key] = $val;
95
			}
96
		}
97
98
		return $normalized;
99
	}
100
101
102
}
103