-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions.php
152 lines (144 loc) · 4.26 KB
/
functions.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?php
namespace Koded\Http;
/*
* This file is part of the Koded package.
*
* (c) Mihail Binev <[email protected]>
*
* Please view the LICENSE distributed with this source code
* for the full copyright and license information.
*
*/
use InvalidArgumentException;
use Psr\Http\Message\{StreamInterface, UploadedFileInterface};
use function array_merge;
use function array_splice;
use function fopen;
use function fseek;
use function fwrite;
use function gettype;
use function is_array;
use function is_callable;
use function is_string;
use function method_exists;
/**
* @param mixed $resource The string that is to be written
* @param string $mode Type of access to the stream
*
* @return StreamInterface
*/
function create_stream(mixed $resource, string $mode = 'r+b'): StreamInterface
{
if (null === $resource || is_string($resource)) {
$stream = fopen('php://temp', $mode);
fwrite($stream, $resource ?? '');
fseek($stream, 0);
return new Stream($stream);
}
if ($resource instanceof StreamInterface) {
return $resource;
}
if (is_callable($resource)) {
return new CallableStream($resource);
}
$type = gettype($resource);
if ('resource' === $type) {
return new Stream($resource);
}
if ('object' === $type && method_exists($resource, '__toString')) {
return create_stream((string)$resource);
}
throw new InvalidArgumentException('Failed to create a stream. '
. 'Expected a file name, StreamInterface instance, or a resource. '
. "Given {$type} type.");
}
/**
* Copies the stream to another stream object.
*
* @param StreamInterface $source The source stream object
* @param StreamInterface $destination Destination stream object
* @param int [optional] $length Read up to $length bytes from the source stream.
* Fewer than $length bytes may be returned if underlying stream
* call returns fewer bytes
*
* @return int The total count of bytes copied
*/
function stream_copy(
StreamInterface $source,
StreamInterface $destination,
int $length = 8192): int
{
$bytes = 0;
while (false === $source->eof()) {
$bytes += $destination->write($source->read($length));
}
$destination->close();
return $bytes;
}
/**
* @param StreamInterface $stream
*
* @return string
* @throws \RuntimeException on failure
*/
function stream_to_string(StreamInterface $stream): string
{
$content = '';
$stream->rewind();
while (false === $stream->eof()) {
$content .= $stream->read(65536); // 64KB
}
return $content;
}
/**
* Transforms the array to much desired files array structure.
* Deals with any nested level.
*
* @param array $files Typically the $_FILES array
*
* @return array A files array to a sane format
*/
function normalize_files_array(array $files): array
{
$sane = function(array $files, array $file = [], array $path = []) use (&$sane) {
foreach ($files as $k => $v) {
$list = $path;
$list[] = $k;
if (is_array($v)) {
$file = $sane($v, $file, $list);
} else {
$next = array_splice($list, 1, 1);
$copy = &$file;
foreach (array_merge($list, $next) as $k) {
$copy = &$copy[$k];
}
$copy = $v;
}
}
return $file;
};
return $sane($files);
}
/**
* Preserves the array structure and replaces the
* file description with instance of UploadedFile.
*
* @param array $files Normalized _FILES array
*
* @return array An array tree of UploadedFileInterface instances
*/
function build_files_array(array $files): array
{
foreach ($files as $index => $file) {
if ($file instanceof UploadedFileInterface) {
$files[$index] = $file;
} elseif (isset($file['tmp_name']) && is_array($file)) {
$files[$index] = new UploadedFile($file);
} elseif (is_array($file)) {
$files[$index] = build_files_array($file);
} else {
throw new InvalidArgumentException('Failed to process the uploaded files. Invalid file structure provided');
}
}
return $files;
}