-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFormDataInput.php
More file actions
150 lines (130 loc) · 4 KB
/
FormDataInput.php
File metadata and controls
150 lines (130 loc) · 4 KB
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
<?php declare(strict_types=1);
/**
* Part of Windwalker project.
*
* @copyright Copyright (C) 2019 LYRASOFT.
* @license GNU General Public License version 2 or later.
*/
namespace Windwalker\IO;
/**
* The FormInput class.
*
* @since 2.1.7
*/
class FormDataInput extends Input
{
/**
* The raw JSON string from the request.
*
* @var string
* @since 2.0
*/
protected static $raw;
/**
* Prepare source.
*
* @param array $source Optional source data. If omitted, a copy of the server variable '_REQUEST' is used.
* @param boolean $reference If set to true, he source in first argument will be reference.
*
* @return void
*/
public function prepareSource(&$source = null, $reference = false)
{
if (is_null($source)) {
$raw = static::loadRawFromRequest();
if (isset($_SERVER['CONTENT_TYPE']) && strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') === 0) {
static::parseFormData($raw, $this->data);
} else {
parse_str($raw, $this->data);
}
if (!is_array($this->data)) {
$this->data = [];
}
} else {
if ($reference) {
$this->data = &$source;
} else {
$this->data = $source;
}
}
}
/**
* Gets the raw HTTP data string from the request.
*
* @return string The raw HTP data string from the request.
*
* @since 2.0
*/
public static function getRawFormData()
{
return static::$raw;
}
/**
* setRawData
*
* @param string $data
*
* @return string
*/
public static function setRawFormData($data)
{
static::$raw = $data;
}
/**
* loadRawFromRequest
*
* @return string
*/
protected function loadRawFromRequest()
{
if (static::$raw) {
return static::$raw;
}
static::$raw = file_get_contents('php://input');
// This is a workaround for where php://input has already been read.
// See note under php://input on http://php.net/manual/en/wrappers.php.php
if (empty($this->raw) && isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
static::$raw = $GLOBALS['HTTP_RAW_POST_DATA'];
}
return static::$raw;
}
/**
* parseFormData
*
* @param string $input
* @param array &$data
*
* @link http://stackoverflow.com/questions/5483851/manually-parse-raw-http-data-with-php/5488449#5488449
*
* @return array
*/
public static function parseFormData($input, array &$data)
{
// grab multipart boundary from content type header
preg_match('/boundary=(.*)$/', $_SERVER['CONTENT_TYPE'], $matches);
$boundary = $matches[1];
// split content by boundary and get rid of last -- element
$aBlocks = preg_split("/-+$boundary/", $input);
array_pop($aBlocks);
// loop data blocks
foreach ($aBlocks as $id => $block) {
if (empty($block)) {
continue;
}
// you'll have to var_dump $block to understand this and maybe replace \n or \r with a visibile char
// parse uploaded files
if (strpos($block, 'application/octet-stream') !== false) {
// match "name", then everything after "stream" (optional) except for prepending newlines
preg_match("/name=\"([^\"]*)\".*stream[\n|\r]+([^\n\r].*)?$/s", $block, $matches);
} else {
// parse all other fields
// match "name" and optional value in between newline sequences
preg_match('/name=\"([^\"]*)\"[\n|\r]+([^\n\r].*)?[\n|\r]$/s', $block, $matches);
}
if (isset($matches[1]) && isset($matches[2])) {
$data[$matches[1]] = rtrim($matches[2], "\n\r");
}
}
return $data;
}
}