FactoryHelpers::create_stream_from_input()   A
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 29
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 11
nc 5
nop 1
dl 0
loc 29
rs 9.2222
c 1
b 0
f 0
1
<?php
2
/**
3
 * Class FactoryHelpers
4
 *
5
 * @created      20.10.2022
6
 * @author       smiley <[email protected]>
7
 * @copyright    2022 smiley
8
 * @license      MIT
9
 */
10
11
namespace chillerlan\HTTP\Psr17;
12
13
use chillerlan\HTTP\Psr7\Stream;
14
use InvalidArgumentException;
15
use Psr\Http\Message\StreamInterface;
16
use function fopen, gettype, in_array, is_scalar, method_exists;
17
18
/**
19
 *
20
 */
21
class FactoryHelpers{
22
23
	public const STREAM_MODES_READ_WRITE = [
24
		'a+', 'c+', 'c+b', 'c+t', 'r+' , 'r+b', 'r+t', 'w+' , 'w+b', 'w+t', 'x+' , 'x+b', 'x+t'
25
	];
26
	public const STREAM_MODES_READ       = [...self::STREAM_MODES_READ_WRITE, 'r', 'rb', 'rt'];
27
	public const STREAM_MODES_WRITE      = [...self::STREAM_MODES_READ_WRITE, 'a', 'rw', 'w', 'wb'];
28
29
	/**
30
	 * Create a new writable stream from a string.
31
	 *
32
	 * The stream SHOULD be created with a temporary resource.
33
	 *
34
	 * @param string $content String content with which to populate the stream.
35
	 * @param string $mode    one of \chillerlan\HTTP\Psr17\STREAM_MODES_WRITE
36
	 * @param bool   $rewind  rewind the stream
37
	 *
38
	 * @return \Psr\Http\Message\StreamInterface
39
	 */
40
	public static function create_stream(string $content = '', string $mode = 'r+', bool $rewind = true):StreamInterface{
41
42
		if(!in_array($mode, self::STREAM_MODES_WRITE)){
43
			throw new InvalidArgumentException('invalid mode');
44
		}
45
46
		$stream = new Stream(fopen('php://temp', $mode));
47
48
		if($content !== ''){
49
			$stream->write($content);
50
		}
51
52
		if($rewind){
53
			$stream->rewind();
54
		}
55
56
		return $stream;
57
	}
58
59
	/**
60
	 *
61
	 */
62
	public static function create_stream_from_input(mixed $in = null):StreamInterface{
63
		$in ??= '';
64
65
		// not sure about this one, it might cause:
66
		// a) trouble if the given string accidentally matches a file path, and
67
		// b) security implications because of the above.
68
		// use with caution and never with user input!
69
#		if(\is_string($in) && \is_file($in) && \is_readable($in)){
70
#			return new Stream(\fopen($in, 'r'));
71
#		}
72
#
73
		if($in instanceof StreamInterface){
74
			return $in;
75
		}
76
77
		if(is_scalar($in)){
78
			return self::create_stream((string)$in);
79
		}
80
81
		$type = gettype($in);
82
83
		if($type === 'resource'){
84
			return new Stream($in);
85
		}
86
		elseif($type === 'object' && method_exists($in, '__toString')){
87
			return self::create_stream((string)$in);
88
		}
89
90
		throw new InvalidArgumentException('Invalid resource type: '.$type);
91
	}
92
93
}
94