Passed
Push — gh-pages ( 22b0fe...eb2d91 )
by
unknown
12:27 queued 10:15
created

create_uri_from_globals()   C

Complexity

Conditions 13
Paths 240

Size

Total Lines 43
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 25
nc 240
nop 0
dl 0
loc 43
rs 5.2833
c 0
b 0
f 0

How to fix   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
 * @created      28.08.2018
4
 * @author       smiley <[email protected]>
5
 * @copyright    2018 smiley
6
 * @license      MIT
7
 */
8
9
namespace chillerlan\HTTP\Psr17;
10
11
use Psr\Http\Message\ServerRequestInterface;
12
use chillerlan\HTTP\Psr7\{ServerRequest, Stream, UriExtended};
13
use InvalidArgumentException;
14
use Psr\Http\Message\StreamInterface;
15
16
use function chillerlan\HTTP\Psr7\normalize_files;
17
use function explode, function_exists, getallheaders, is_scalar, method_exists, str_replace;
18
19
const PSR17_INCLUDES = true;
20
21
const STREAM_MODES_READ_WRITE = [
22
	'a+'  => true,
23
	'c+'  => true,
24
	'c+b' => true,
25
	'c+t' => true,
26
	'r+'  => true,
27
	'r+b' => true,
28
	'r+t' => true,
29
	'w+'  => true,
30
	'w+b' => true,
31
	'w+t' => true,
32
	'x+'  => true,
33
	'x+b' => true,
34
	'x+t' => true,
35
];
36
37
const STREAM_MODES_READ = STREAM_MODES_READ_WRITE + [
38
	'r'   => true,
39
	'rb'  => true,
40
	'rt'  => true,
41
];
42
43
const STREAM_MODES_WRITE = STREAM_MODES_READ_WRITE + [
44
	'a'   => true,
45
	'rw'  => true,
46
	'w'   => true,
47
	'wb'  => true,
48
];
49
50
/**
51
 * Return a ServerRequest populated with superglobals:
52
 * $_GET
53
 * $_POST
54
 * $_COOKIE
55
 * $_FILES
56
 * $_SERVER
57
 */
58
function create_server_request_from_globals():ServerRequestInterface{
59
60
	$serverRequest = new ServerRequest(
61
		$_SERVER['REQUEST_METHOD'] ?? ServerRequest::METHOD_GET,
62
		create_uri_from_globals(),
63
		function_exists('getallheaders') ? getallheaders() : [],
0 ignored issues
show
Bug introduced by
It seems like function_exists('getallh...tallheaders() : array() can also be of type true; however, parameter $headers of chillerlan\HTTP\Psr7\ServerRequest::__construct() does only seem to accept array|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

63
		/** @scrutinizer ignore-type */ function_exists('getallheaders') ? getallheaders() : [],
Loading history...
64
		(new StreamFactory)->createStream(),
65
		isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1',
66
		$_SERVER
67
	);
68
69
	return $serverRequest
70
		->withCookieParams($_COOKIE)
71
		->withQueryParams($_GET)
72
		->withParsedBody($_POST)
73
		->withUploadedFiles(normalize_files($_FILES))
74
	;
75
}
76
77
/**
78
 * Get a Uri populated with values from $_SERVER.
79
 */
80
function create_uri_from_globals():UriExtended{
81
	$parts    = [];
82
	$hasPort  = false;
83
	$hasQuery = false;
84
85
	$parts['scheme'] = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http';
86
87
	if(isset($_SERVER['HTTP_HOST'])){
88
		$hostHeaderParts = explode(':', $_SERVER['HTTP_HOST']);
89
		$parts['host']   = $hostHeaderParts[0];
90
91
		if(isset($hostHeaderParts[1])){
92
			$hasPort       = true;
93
			$parts['port'] = $hostHeaderParts[1];
94
		}
95
	}
96
	elseif(isset($_SERVER['SERVER_NAME'])){
97
		$parts['host'] = $_SERVER['SERVER_NAME'];
98
	}
99
	elseif(isset($_SERVER['SERVER_ADDR'])){
100
		$parts['host'] = $_SERVER['SERVER_ADDR'];
101
	}
102
103
	if(!$hasPort && isset($_SERVER['SERVER_PORT'])){
104
		$parts['port'] = $_SERVER['SERVER_PORT'];
105
	}
106
107
	if(isset($_SERVER['REQUEST_URI'])){
108
		$requestUriParts = explode('?', $_SERVER['REQUEST_URI']);
109
		$parts['path']   = $requestUriParts[0];
110
111
		if(isset($requestUriParts[1])){
112
			$hasQuery       = true;
113
			$parts['query'] = $requestUriParts[1];
114
		}
115
	}
116
117
	if(!$hasQuery && isset($_SERVER['QUERY_STRING'])){
118
		$parts['query'] = $_SERVER['QUERY_STRING'];
119
	}
120
121
	/** @noinspection PhpIncompatibleReturnTypeInspection */
122
	return UriExtended::fromParts($parts);
123
}
124
125
/**
126
 * Create a new writable stream from a string.
127
 *
128
 * The stream SHOULD be created with a temporary resource.
129
 *
130
 * @param string $content String content with which to populate the stream.
131
 * @param string $mode    one of \chillerlan\HTTP\Psr17\STREAM_MODES_WRITE
132
 * @param bool   $rewind  rewind the stream
133
 *
134
 * @return \Psr\Http\Message\StreamInterface
135
 */
136
function create_stream(string $content = '', string $mode = 'r+', bool $rewind = true):StreamInterface{
137
138
	if(!isset(STREAM_MODES_WRITE[$mode])){
139
		throw new InvalidArgumentException('invalid mode');
140
	}
141
142
	$stream = new Stream(fopen('php://temp', $mode));
143
144
	if($content !== ''){
145
		$stream->write($content);
146
	}
147
148
	if($rewind){
149
		$stream->rewind();
150
	}
151
152
	return $stream;
153
}
154
155
/**
156
 * @param mixed $in
157
 *
158
 * @return \Psr\Http\Message\StreamInterface
159
 */
160
function create_stream_from_input($in = null):StreamInterface{
161
	$in = $in ?? '';
162
163
	// not sure about this one, it might cause:
164
	// a) trouble if the given string accidentally matches a file path, and
165
	// b) security implications because of the above.
166
	// use with caution and never with user input!
167
#	if(\is_string($in) && \is_file($in) && \is_readable($in)){
168
#		return new Stream(\fopen($in, 'r'));
169
#	}
170
171
	if(is_scalar($in)){
172
		return create_stream((string)$in);
173
	}
174
175
	$type = gettype($in);
176
177
	if($type === 'resource'){
178
		return new Stream($in);
179
	}
180
	elseif($type === 'object'){
181
182
		if($in instanceof StreamInterface){
183
			return $in;
184
		}
185
		elseif(method_exists($in, '__toString')){
186
			return create_stream((string)$in);
187
		}
188
189
	}
190
191
	throw new InvalidArgumentException('Invalid resource type: '.$type);
192
}
193