summaryrefslogtreecommitdiffstats
path: root/vendor/paypal/paypalhttp/lib/PayPalHttp
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2022-01-11 12:35:47 +0100
committerAnton Luka Šijanec <anton@sijanec.eu>2022-01-11 12:35:47 +0100
commit19985dbb8c0aa66dc4bf7905abc1148de909097d (patch)
tree2cd5a5d20d7e80fc2a51adf60d838d8a2c40999e /vendor/paypal/paypalhttp/lib/PayPalHttp
download1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.gz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.bz2
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.lz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.xz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.zst
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.zip
Diffstat (limited to '')
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Curl.php57
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Encoder.php114
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Environment.php18
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php231
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/HttpException.php23
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/HttpRequest.php42
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/HttpResponse.php34
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/IOException.php13
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Injector.php19
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer.php29
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Form.php46
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/FormPart.php25
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Json.php38
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Multipart.php134
-rw-r--r--vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Text.php38
15 files changed, 861 insertions, 0 deletions
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Curl.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Curl.php
new file mode 100644
index 0000000..08e6eaf
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Curl.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace PayPalHttp;
+
+/**
+ * Class Curl
+ * @package PayPalHttp
+ *
+ * Curl wrapper used by HttpClient to make curl requests.
+ * @see HttpClient
+ */
+class Curl
+{
+ protected $curl;
+
+ public function __construct($curl = NULL)
+ {
+
+ if (is_null($curl))
+ {
+ $curl = curl_init();
+ }
+ $this->curl = $curl;
+ }
+
+ public function setOpt($option, $value)
+ {
+ curl_setopt($this->curl, $option, $value);
+ return $this;
+ }
+
+ public function close()
+ {
+ curl_close($this->curl);
+ return $this;
+ }
+
+ public function exec()
+ {
+ return curl_exec($this->curl);
+ }
+
+ public function errNo()
+ {
+ return curl_errno($this->curl);
+ }
+
+ public function getInfo($option)
+ {
+ return curl_getinfo($this->curl, $option);
+ }
+
+ public function error()
+ {
+ return curl_error($this->curl);
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Encoder.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Encoder.php
new file mode 100644
index 0000000..b7158a7
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Encoder.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace PayPalHttp;
+
+use PayPalHttp\Serializer\Form;
+use PayPalHttp\Serializer\Json;
+use PayPalHttp\Serializer\Multipart;
+use PayPalHttp\Serializer\Text;
+
+/**
+ * Class Encoder
+ * @package PayPalHttp
+ *
+ * Encoding class for serializing and deserializing request/response.
+ */
+class Encoder
+{
+ private $serializers = [];
+
+ function __construct()
+ {
+ $this->serializers[] = new Json();
+ $this->serializers[] = new Text();
+ $this->serializers[] = new Multipart();
+ $this->serializers[] = new Form();
+ }
+
+
+
+ public function serializeRequest(HttpRequest $request)
+ {
+ if (!array_key_exists('content-type', $request->headers)) {
+ $message = "HttpRequest does not have Content-Type header set";
+ echo $message;
+ throw new \Exception($message);
+ }
+
+ $contentType = $request->headers['content-type'];
+ /** @var Serializer $serializer */
+ $serializer = $this->serializer($contentType);
+
+ if (is_null($serializer)) {
+ $message = sprintf("Unable to serialize request with Content-Type: %s. Supported encodings are: %s", $contentType, implode(", ", $this->supportedEncodings()));
+ echo $message;
+ throw new \Exception($message);
+ }
+
+ if (!(is_string($request->body) || is_array($request->body))) {
+ $message = "Body must be either string or array";
+ echo $message;
+ throw new \Exception($message);
+ }
+
+ $serialized = $serializer->encode($request);
+
+ if (array_key_exists("content-encoding", $request->headers) && $request->headers["content-encoding"] === "gzip") {
+ $serialized = gzencode($serialized);
+ }
+ return $serialized;
+ }
+
+
+ public function deserializeResponse($responseBody, $headers)
+ {
+
+ if (!array_key_exists('content-type', $headers)) {
+ $message = "HTTP response does not have Content-Type header set";
+ echo $message;
+ throw new \Exception($message);
+ }
+
+ $contentType = $headers['content-type'];
+ /** @var Serializer $serializer */
+ $serializer = $this->serializer($contentType);
+
+ if (is_null($serializer)) {
+ throw new \Exception(sprintf("Unable to deserialize response with Content-Type: %s. Supported encodings are: %s", $contentType, implode(", ", $this->supportedEncodings())));
+ }
+
+ if (array_key_exists("content-encoding", $headers) && $headers["content-encoding"] === "gzip") {
+ $responseBody = gzdecode($responseBody);
+ }
+
+ return $serializer->decode($responseBody);
+ }
+
+ private function serializer($contentType)
+ {
+ /** @var Serializer $serializer */
+ foreach ($this->serializers as $serializer) {
+ try {
+ if (preg_match($serializer->contentType(), $contentType) == 1) {
+ return $serializer;
+ }
+ } catch (\Exception $ex) {
+ $message = sprintf("Error while checking content type of %s: %s", get_class($serializer), $ex->getMessage());
+ echo $message;
+ throw new \Exception($message, $ex->getCode(), $ex);
+ }
+ }
+
+ return NULL;
+ }
+
+ private function supportedEncodings()
+ {
+ $values = [];
+ /** @var Serializer $serializer */
+ foreach ($this->serializers as $serializer) {
+ $values[] = $serializer->contentType();
+ }
+ return $values;
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Environment.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Environment.php
new file mode 100644
index 0000000..4eb0ce0
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Environment.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace PayPalHttp;
+
+/**
+ * Interface Environment
+ * @package PayPalHttp
+ *
+ * Describes a domain that hosts a REST API, against which an HttpClient will make requests.
+ * @see HttpClient
+ */
+interface Environment
+{
+ /**
+ * @return string
+ */
+ public function baseUrl();
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php
new file mode 100644
index 0000000..dbbdb79
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php
@@ -0,0 +1,231 @@
+<?php
+
+namespace PayPalHttp;
+
+/**
+ * Class HttpClient
+ * @package PayPalHttp
+ *
+ * Client used to make HTTP requests.
+ */
+class HttpClient
+{
+ /**
+ * @var Environment
+ */
+ public $environment;
+
+ /**
+ * @var Injector[]
+ */
+ public $injectors = [];
+
+ /**
+ * @var Encoder
+ */
+ public $encoder;
+
+ /**
+ * HttpClient constructor. Pass the environment you wish to make calls to.
+ *
+ * @param $environment Environment
+ * @see Environment
+ */
+ function __construct(Environment $environment)
+ {
+ $this->environment = $environment;
+ $this->encoder = new Encoder();
+ $this->curlCls = Curl::class;
+ }
+
+ /**
+ * Injectors are blocks that can be used for executing arbitrary pre-flight logic, such as modifying a request or logging data.
+ * Executed in first-in first-out order.
+ *
+ * @param Injector $inj
+ */
+ public function addInjector(Injector $inj)
+ {
+ $this->injectors[] = $inj;
+ }
+
+ /**
+ * The method that takes an HTTP request, serializes the request, makes a call to given environment, and deserialize response
+ *
+ * @param $httpRequest HttpRequest
+ * @return HttpResponse
+ */
+ public function execute(HttpRequest $httpRequest)
+ {
+ $requestCpy = clone $httpRequest;
+ $curl = new Curl();
+
+ foreach ($this->injectors as $inj) {
+ $inj->inject($requestCpy);
+ }
+
+ $url = $this->environment->baseUrl() . $requestCpy->path;
+ $formattedHeaders = $this->prepareHeaders($requestCpy->headers);
+ if (!array_key_exists("user-agent", $formattedHeaders)) {
+ $requestCpy->headers["user-agent"] = $this->userAgent();
+ }
+
+ $body = "";
+ if (!is_null($requestCpy->body)) {
+ $rawHeaders = $requestCpy->headers;
+ $requestCpy->headers = $formattedHeaders;
+ $body = $this->encoder->serializeRequest($requestCpy);
+ $requestCpy->headers = $this->mapHeaders($rawHeaders,$requestCpy->headers);
+ }
+
+ $curl->setOpt(CURLOPT_URL, $url);
+ $curl->setOpt(CURLOPT_CUSTOMREQUEST, $requestCpy->verb);
+ $curl->setOpt(CURLOPT_HTTPHEADER, $this->serializeHeaders($requestCpy->headers));
+ $curl->setOpt(CURLOPT_RETURNTRANSFER, 1);
+ $curl->setOpt(CURLOPT_HEADER, 0);
+
+ if (!is_null($requestCpy->body)) {
+ $curl->setOpt(CURLOPT_POSTFIELDS, $body);
+ }
+
+ if (strpos($this->environment->baseUrl(), "https://") === 0) {
+ $curl->setOpt(CURLOPT_SSL_VERIFYPEER, true);
+ $curl->setOpt(CURLOPT_SSL_VERIFYHOST, 2);
+ }
+
+ if ($caCertPath = $this->getCACertFilePath()) {
+ $curl->setOpt(CURLOPT_CAINFO, $caCertPath);
+ }
+
+ $response = $this->parseResponse($curl);
+ $curl->close();
+
+ return $response;
+ }
+
+ /**
+ * Returns an array representing headers with their keys
+ * to be lower case
+ * @param $headers
+ * @return array
+ */
+ public function prepareHeaders($headers){
+ return array_change_key_case($headers);
+ }
+
+ /**
+ * Returns an array representing headers with their key in
+ * original cases and updated values
+ * @param $rawHeaders
+ * @param $formattedHeaders
+ * @return array
+ */
+ public function mapHeaders($rawHeaders, $formattedHeaders){
+ $rawHeadersKey = array_keys($rawHeaders);
+ foreach ($rawHeadersKey as $array_key) {
+ if(array_key_exists(strtolower($array_key), $formattedHeaders)){
+ $rawHeaders[$array_key] = $formattedHeaders[strtolower($array_key)];
+ }
+ }
+ return $rawHeaders;
+ }
+
+ /**
+ * Returns default user-agent
+ *
+ * @return string
+ */
+ public function userAgent()
+ {
+ return "PayPalHttp-PHP HTTP/1.1";
+ }
+
+ /**
+ * Return the filepath to your custom CA Cert if needed.
+ * @return string
+ */
+ protected function getCACertFilePath()
+ {
+ return null;
+ }
+
+ protected function setCurl(Curl $curl)
+ {
+ $this->curl = $curl;
+ }
+
+ protected function setEncoder(Encoder $encoder)
+ {
+ $this->encoder = $encoder;
+ }
+
+ private function serializeHeaders($headers)
+ {
+ $headerArray = [];
+ if ($headers) {
+ foreach ($headers as $key => $val) {
+ $headerArray[] = $key . ": " . $val;
+ }
+ }
+
+ return $headerArray;
+ }
+
+ private function parseResponse($curl)
+ {
+ $headers = [];
+ $curl->setOpt(CURLOPT_HEADERFUNCTION,
+ function($curl, $header) use (&$headers)
+ {
+ $len = strlen($header);
+
+ $k = "";
+ $v = "";
+
+ $this->deserializeHeader($header, $k, $v);
+ $headers[$k] = $v;
+
+ return $len;
+ });
+
+ $responseData = $curl->exec();
+ $statusCode = $curl->getInfo(CURLINFO_HTTP_CODE);
+ $errorCode = $curl->errNo();
+ $error = $curl->error();
+
+ if ($errorCode > 0) {
+ throw new IOException($error, $errorCode);
+ }
+
+ $body = $responseData;
+
+ if ($statusCode >= 200 && $statusCode < 300) {
+ $responseBody = NULL;
+
+ if (!empty($body)) {
+ $responseBody = $this->encoder->deserializeResponse($body, $this->prepareHeaders($headers));
+ }
+
+ return new HttpResponse(
+ $errorCode === 0 ? $statusCode : $errorCode,
+ $responseBody,
+ $headers
+ );
+ } else {
+ throw new HttpException($body, $statusCode, $headers);
+ }
+ }
+
+ private function deserializeHeader($header, &$key, &$value)
+ {
+ if (strlen($header) > 0) {
+ if (empty($header) || strpos($header, ':') === false) {
+ return NULL;
+ }
+
+ list($k, $v) = explode(":", $header);
+ $key = trim($k);
+ $value = trim($v);
+ }
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpException.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpException.php
new file mode 100644
index 0000000..5f4d2db
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpException.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace PayPalHttp;
+
+class HttpException extends IOException
+{
+ /**
+ * @var statusCode
+ */
+ public $statusCode;
+
+ public $headers;
+
+ /**
+ * @param string $response
+ */
+ public function __construct($message, $statusCode, $headers)
+ {
+ parent::__construct($message);
+ $this->statusCode = $statusCode;
+ $this->headers = $headers;
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpRequest.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpRequest.php
new file mode 100644
index 0000000..89b7480
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpRequest.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace PayPalHttp;
+
+/**
+ * Class HttpRequest
+ * @package PayPalHttp
+ *
+ * Request object that holds all the necessary information required by HTTPClient
+ *
+ * @see HttpClient
+ */
+class HttpRequest
+{
+ /**
+ * @var string
+ */
+ public $path;
+
+ /**
+ * @var array | string
+ */
+ public $body;
+
+ /**
+ * @var string
+ */
+ public $verb;
+
+ /**
+ * @var array
+ */
+ public $headers;
+
+ function __construct($path, $verb)
+ {
+ $this->path = $path;
+ $this->verb = $verb;
+ $this->body = NULL;
+ $this->headers = [];
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpResponse.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpResponse.php
new file mode 100644
index 0000000..ef8fb35
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpResponse.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace PayPalHttp;
+
+/**
+ * Class HttpResponse
+ * @package PayPalHttp
+ *
+ * Object that holds your response details
+ */
+class HttpResponse
+{
+ /**
+ * @var integer
+ */
+ public $statusCode;
+
+ /**
+ * @var array | string
+ */
+ public $result;
+
+ /**
+ * @var array
+ */
+ public $headers;
+
+ public function __construct($statusCode, $body, $headers)
+ {
+ $this->statusCode = $statusCode;
+ $this->headers = $headers;
+ $this->result = $body;
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/IOException.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/IOException.php
new file mode 100644
index 0000000..7bfc91c
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/IOException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace PayPalHttp;
+
+use Throwable;
+
+class IOException extends \Exception
+{
+ public function __construct($message = "", $code = 0, Throwable $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Injector.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Injector.php
new file mode 100644
index 0000000..3ae23c7
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Injector.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace PayPalHttp;
+
+/**
+ * Interface Injector
+ * @package PayPalHttp
+ *
+ * Interface that can be implemented to apply injectors to Http client.
+ *
+ * @see HttpClient
+ */
+interface Injector
+{
+ /**
+ * @param $httpRequest HttpRequest
+ */
+ public function inject($httpRequest);
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer.php
new file mode 100644
index 0000000..2edcfe2
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace PayPalHttp;
+
+/**
+ * Interface Serializer
+ * @package PayPalHttp
+ *
+ * Used to implement different serializers for different content types
+ */
+interface Serializer
+{
+ /**
+ * @return string Regex that matches the content type it supports.
+ */
+ public function contentType();
+
+ /**
+ * @param HttpRequest $request
+ * @return string representation of your data after being serialized.
+ */
+ public function encode(HttpRequest $request);
+
+ /**
+ * @param $body
+ * @return mixed object/string representing the de-serialized response body.
+ */
+ public function decode($body);
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Form.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Form.php
new file mode 100644
index 0000000..bead9d3
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Form.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace PayPalHttp\Serializer;
+
+use PayPalHttp\HttpRequest;
+use PayPalHttp\Serializer;
+
+class Form implements Serializer
+{
+ /**
+ * @return string Regex that matches the content type it supports.
+ */
+ public function contentType()
+ {
+ return "/^application\/x-www-form-urlencoded$/";
+ }
+
+ /**
+ * @param HttpRequest $request
+ * @return string representation of your data after being serialized.
+ */
+ 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"]);
+ }
+
+ return http_build_query($request->body);
+ }
+
+ /**
+ * @param $body
+ * @return mixed
+ * @throws \Exception as multipart does not support deserialization.
+ */
+ public function decode($body)
+ {
+ throw new \Exception("CurlSupported does not support deserialization");
+ }
+
+ private function isAssociative(array $array)
+ {
+ return array_values($array) !== $array;
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/FormPart.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/FormPart.php
new file mode 100644
index 0000000..3779a9b
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/FormPart.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace PayPalHttp\Serializer;
+
+class FormPart
+{
+ private $value;
+ private $headers;
+
+ public function __construct($value, $headers)
+ {
+ $this->value = $value;
+ $this->headers = array_merge([], $headers);
+ }
+
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Json.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Json.php
new file mode 100644
index 0000000..3f66314
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Json.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace PayPalHttp\Serializer;
+
+use PayPalHttp\HttpRequest;
+use PayPalHttp\Serializer;
+
+/**
+ * Class Json
+ * @package PayPalHttp\Serializer
+ *
+ * Serializer for JSON content types.
+ */
+class Json implements Serializer
+{
+
+ public function contentType()
+ {
+ return "/^application\\/json/";
+ }
+
+ public function encode(HttpRequest $request)
+ {
+ $body = $request->body;
+ if (is_string($body)) {
+ return $body;
+ }
+ if (is_array($body)) {
+ return json_encode($body);
+ }
+ throw new \Exception("Cannot serialize data. Unknown type");
+ }
+
+ public function decode($data)
+ {
+ return json_decode($data);
+ }
+}
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);
+ }
+}
diff --git a/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Text.php b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Text.php
new file mode 100644
index 0000000..e2ce0ca
--- /dev/null
+++ b/vendor/paypal/paypalhttp/lib/PayPalHttp/Serializer/Text.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace PayPalHttp\Serializer;
+
+use PayPalHttp\HttpRequest;
+use PayPalHttp\Serializer;
+
+/**
+ * Class Text
+ * @package PayPalHttp\Serializer
+ *
+ * Serializer for Text content types.
+ */
+class Text implements Serializer
+{
+
+ public function contentType()
+ {
+ return "/^text\\/.*/";
+ }
+
+ public function encode(HttpRequest $request)
+ {
+ $body = $request->body;
+ if (is_string($body)) {
+ return $body;
+ }
+ if (is_array($body)) {
+ return json_encode($body);
+ }
+ return implode(" ", $body);
+ }
+
+ public function decode($data)
+ {
+ return $data;
+ }
+}