diff --git a/library/Requests.php b/library/Requests.php index bb266189c..38551fc00 100644 --- a/library/Requests.php +++ b/library/Requests.php @@ -258,15 +258,41 @@ public static function trace($url, $headers = array(), $options = array()) { * @param string $url * @param array $headers * @param array $data + * @param array $files * @param array $options * @return Requests_Response */ /** - * Send a POST request - */ - public static function post($url, $headers = array(), $data = array(), $options = array()) { - return self::request($url, $headers, $data, self::POST, $options); - } + * Send a POST request/Support for multiple files, complex array parameters + */ + public static function post($url, $headers = [], $data = [], $files = [], $options = []){ + if (count($files)) { + self::httpBuildQuery($data); + // replacing file paths with curlFile Object + array_walk($files, function ($filePath, $key) use (&$data) { + if (is_array($filePath)) { + array_walk($filePath, function ($subFilePath, $subKey) use (&$data, $key) { + $data["{$key}[{$subKey}]"] = new \CURLFile(realpath($subFilePath)); + }); + } else { + $data[ $key ] = new \CURLFile(realpath($filePath)); + } + }); + + // starting to add a hook to attach file to request + $hooks = new \Requests_Hooks(); + $hooks->register('curl.before_send', function ($fp) use ($data) { + curl_setopt($fp, CURLOPT_SAFE_UPLOAD, true); + curl_setopt($fp, CURLOPT_POSTFIELDS, $data); + }); + $options = ['hooks' => $hooks]; + // no need to set the body, it's taken care of by hooks + $data = []; + } + + return self::request($url, $headers, $data, self::POST, $options); + } + /** * Send a PUT request */ @@ -977,4 +1003,16 @@ public static function match_domain($host, $reference) { return false; } + + protected static function httpBuildQuery(array &$data, $key = '', $value = null) { + foreach ($value ?? $data as $k => $v) { + $cur_key = $key ? "{$key}[{$k}]" : "{$k}"; + if (is_array($v)) { + self::httpBuildQuery($data, "{$cur_key}", $v); + unset($data[$k]); + }else{ + $data[$cur_key] = $v; + } + } + } } diff --git a/tests/Transport/Base.php b/tests/Transport/Base.php index 566e09fad..4f5604228 100644 --- a/tests/Transport/Base.php +++ b/tests/Transport/Base.php @@ -160,7 +160,7 @@ public function testTRACE() { public function testRawPOST() { $data = 'test'; - $request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions()); + $request = Requests::post(httpbin('/post'), array(), $data,['fiilename' => tempnam(sys_get_temp_dir(), 'RLT')], $this->getOptions()); $this->assertEquals(200, $request->status_code); $result = json_decode($request->body, true); @@ -169,7 +169,7 @@ public function testRawPOST() { public function testFormPost() { $data = 'test=true&test2=test'; - $request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions()); + $request = Requests::post(httpbin('/post'), array(), $data,['fiilename' => tempnam(sys_get_temp_dir(), 'RLT')], $this->getOptions()); $this->assertEquals(200, $request->status_code); $result = json_decode($request->body, true); @@ -181,7 +181,7 @@ public function testPOSTWithArray() { 'test' => 'true', 'test2' => 'test', ); - $request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions()); + $request = Requests::post(httpbin('/post'), array(), $data,['fiilename' => tempnam(sys_get_temp_dir(), 'RLT')], $this->getOptions()); $this->assertEquals(200, $request->status_code); $result = json_decode($request->body, true); @@ -196,7 +196,7 @@ public function testPOSTWithNestedData() { 'test4' => 'test-too', ), ); - $request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions()); + $request = Requests::post(httpbin('/post'), array(), $data,['fiilename' => tempnam(sys_get_temp_dir(), 'RLT')], $this->getOptions()); $this->assertEquals(200, $request->status_code); $result = json_decode($request->body, true); @@ -828,7 +828,7 @@ public function testReusableTransport() { public function testQueryDataFormat() { $data = array('test' => 'true', 'test2' => 'test'); - $request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions(array('data_format' => 'query'))); + $request = Requests::post(httpbin('/post'), array(), $data,['filename' => tempnam(sys_get_temp_dir(), 'RLT')], $this->getOptions(array('data_format' => 'query'))); $this->assertEquals(200, $request->status_code); $result = json_decode($request->body, true); @@ -838,7 +838,7 @@ public function testQueryDataFormat() { public function testBodyDataFormat() { $data = array('test' => 'true', 'test2' => 'test'); - $request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions(array('data_format' => 'body'))); + $request = Requests::post(httpbin('/post'), array(), $data,['filename' => tempnam(sys_get_temp_dir(), 'RLT')], $this->getOptions(array('data_format' => 'body'))); $this->assertEquals(200, $request->status_code); $result = json_decode($request->body, true);