diff options
Diffstat (limited to 'vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Multipart.php')
-rw-r--r-- | vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Multipart.php | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Multipart.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Multipart.php new file mode 100644 index 0000000..a420205 --- /dev/null +++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Multipart.php @@ -0,0 +1,134 @@ +<?php + +namespace PayPalHttp\Serializer; + +use finfo; +use PayPalHttp\HttpRequest; +use PayPalHttp\Serializer; +use PayPalHttp\Encoder; +use PayPalHttp\Serializer\FormPart; + +/** + * Class Multipart + * @package PayPalHttp\Serializer + * + * Serializer for multipart. + */ +class Multipart implements Serializer +{ + const LINEFEED = "\r\n"; + + public function contentType() + { + return "/^multipart\/.*$/"; + } + + public function encode(HttpRequest $request) + { + if (!is_array($request->body) || !$this->isAssociative($request->body)) + { + throw new \Exception("HttpRequest body must be an associative array when Content-Type is: " . $request->headers["content-type"]); + } + $boundary = "---------------------" . md5(mt_rand() . microtime()); + $contentTypeHeader = $request->headers["content-type"]; + $request->headers["content-type"] = "{$contentTypeHeader}; boundary={$boundary}"; + + $value_params = []; + $file_params = []; + + $disallow = ["\0", "\"", "\r", "\n"]; + + $body = []; + + foreach ($request->body as $k => $v) { + $k = str_replace($disallow, "_", $k); + if (is_resource($v)) { + $file_params[] = $this->prepareFilePart($k, $v, $boundary); + } else if ($v instanceof FormPart) { + $value_params[] = $this->prepareFormPart($k, $v, $boundary); + } else { + $value_params[] = $this->prepareFormField($k, $v, $boundary); + } + } + + $body = array_merge($value_params, $file_params); + + // add boundary for each parameters + array_walk($body, function (&$part) use ($boundary) { + $part = "--{$boundary}" . self::LINEFEED . "{$part}"; + }); + + // add final boundary + $body[] = "--{$boundary}--"; + $body[] = ""; + + return implode(self::LINEFEED, $body); + } + + public function decode($data) + { + throw new \Exception("Multipart does not support deserialization"); + } + + private function isAssociative(array $array) + { + return array_values($array) !== $array; + } + + private function prepareFormField($partName, $value, $boundary) + { + return implode(self::LINEFEED, [ + "Content-Disposition: form-data; name=\"{$partName}\"", + "", + filter_var($value), + ]); + } + + private function prepareFilePart($partName, $file, $boundary) + { + $fileInfo = new finfo(FILEINFO_MIME_TYPE); + $filePath = stream_get_meta_data($file)['uri']; + $data = file_get_contents($filePath); + $mimeType = $fileInfo->buffer($data); + + $splitFilePath = explode(DIRECTORY_SEPARATOR, $filePath); + $filePath = end($splitFilePath); + $disallow = ["\0", "\"", "\r", "\n"]; + $filePath = str_replace($disallow, "_", $filePath); + return implode(self::LINEFEED, [ + "Content-Disposition: form-data; name=\"{$partName}\"; filename=\"{$filePath}\"", + "Content-Type: {$mimeType}", + "", + $data, + ]); + } + + private function prepareFormPart($partName, $formPart, $boundary) + { + $contentDisposition = "Content-Disposition: form-data; name=\"{$partName}\""; + + $partHeaders = $formPart->getHeaders(); + $formattedheaders = array_change_key_case($partHeaders); + if (array_key_exists("content-type", $formattedheaders)) { + if ($formattedheaders["content-type"] === "application/json") { + $contentDisposition .= "; filename=\"{$partName}.json\""; + } + $tempRequest = new HttpRequest('/', 'POST'); + $tempRequest->headers = $formattedheaders; + $tempRequest->body = $formPart->getValue(); + $encoder = new Encoder(); + $partValue = $encoder->serializeRequest($tempRequest); + } else { + $partValue = $formPart->getValue(); + } + + $finalPartHeaders = []; + foreach ($partHeaders as $k => $v) { + $finalPartHeaders[] = "{$k}: {$v}"; + } + + $body = array_merge([$contentDisposition], $finalPartHeaders, [""], [$partValue]); + + return implode(self::LINEFEED, $body); + } +} |