diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES new file mode 100644 index 0000000..d3a76f0 --- /dev/null +++ b/.openapi-generator/FILES @@ -0,0 +1,27 @@ +.phplint.yml +src/Api/TransactionApi.php +src/ApiException.php +src/Configuration.php +src/FormDataProcessor.php +src/HeaderSelector.php +src/Model/Currency.php +src/Model/Delivery.php +src/Model/Invoice.php +src/Model/Item.php +src/Model/Language.php +src/Model/Method.php +src/Model/ModelInterface.php +src/Model/Start200Response.php +src/Model/Transaction.php +src/Model/TransactionUrls.php +src/ObjectSerializer.php +tests/Api/TransactionApiTest.php +tests/Model/CurrencyTest.php +tests/Model/DeliveryTest.php +tests/Model/InvoiceTest.php +tests/Model/ItemTest.php +tests/Model/LanguageTest.php +tests/Model/MethodTest.php +tests/Model/Start200ResponseTest.php +tests/Model/TransactionTest.php +tests/Model/TransactionUrlsTest.php diff --git a/.openapi-generator/VERSION b/.openapi-generator/VERSION new file mode 100644 index 0000000..e465da4 --- /dev/null +++ b/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.14.0 diff --git a/src/Api/TransactionApi.php b/src/Api/TransactionApi.php new file mode 100644 index 0000000..b05d827 --- /dev/null +++ b/src/Api/TransactionApi.php @@ -0,0 +1,478 @@ + [ + 'application/json', + ], + ]; + + /** + * @param ClientInterface|null $client + * @param Configuration|null $config + * @param HeaderSelector|null $selector + * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec + */ + public function __construct( + ?ClientInterface $client = null, + ?Configuration $config = null, + ?HeaderSelector $selector = null, + int $hostIndex = 0 + ) { + $this->client = $client ?: new Client(); + $this->config = $config ?: Configuration::getDefaultConfiguration(); + $this->headerSelector = $selector ?: new HeaderSelector(); + $this->hostIndex = $hostIndex; + } + + /** + * Set the host index + * + * @param int $hostIndex Host index (required) + */ + public function setHostIndex(int $hostIndex): void + { + $this->hostIndex = $hostIndex; + } + + /** + * Get the host index + * + * @return int Host index + */ + public function getHostIndex(): int + { + return $this->hostIndex; + } + + /** + * @return Configuration + */ + public function getConfig(): Configuration + { + return $this->config; + } + + /** + * Operation start + * + * Start a transaction + * + * @param \Cone\SimplePay\Model\Transaction $transaction The transaction object you would like to start. (required) + * @param string|null $signature The signature. (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['start'] to see the possible values for this operation + * + * @throws ApiException on non-2xx response or if the response body is not in the expected format + * @throws InvalidArgumentException + * @return \Cone\SimplePay\Model\Start200Response + */ + public function start( + \Cone\SimplePay\Model\Transaction $transaction, + ?string $signature = null, + string $contentType = self::contentTypes['start'][0] + ): \Cone\SimplePay\Model\Start200Response { + list($response) = $this->startWithHttpInfo($transaction, $signature, $contentType); + return $response; + } + + /** + * Operation startWithHttpInfo + * + * Start a transaction + * + * @param \Cone\SimplePay\Model\Transaction $transaction The transaction object you would like to start. (required) + * @param string|null $signature The signature. (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['start'] to see the possible values for this operation + * + * @throws ApiException on non-2xx response or if the response body is not in the expected format + * @throws InvalidArgumentException + * @return array of \Cone\SimplePay\Model\Start200Response, HTTP status code, HTTP response headers (array of strings) + */ + public function startWithHttpInfo( + \Cone\SimplePay\Model\Transaction $transaction, + ?string $signature = null, + string $contentType = self::contentTypes['start'][0] + ): array { + $request = $this->startRequest($transaction, $signature, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + switch ($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\Cone\SimplePay\Model\Start200Response', + $request, + $response, + ); + } + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\Cone\SimplePay\Model\Start200Response', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\Cone\SimplePay\Model\Start200Response', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + throw $e; + } + } + + /** + * Operation startAsync + * + * Start a transaction + * + * @param \Cone\SimplePay\Model\Transaction $transaction The transaction object you would like to start. (required) + * @param string|null $signature The signature. (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['start'] to see the possible values for this operation + * + * @throws InvalidArgumentException + * @return PromiseInterface + */ + public function startAsync( + \Cone\SimplePay\Model\Transaction $transaction, + ?string $signature = null, + string $contentType = self::contentTypes['start'][0] + ): PromiseInterface { + return $this->startAsyncWithHttpInfo($transaction, $signature, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation startAsyncWithHttpInfo + * + * Start a transaction + * + * @param \Cone\SimplePay\Model\Transaction $transaction The transaction object you would like to start. (required) + * @param string|null $signature The signature. (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['start'] to see the possible values for this operation + * + * @throws InvalidArgumentException + * @return PromiseInterface + */ + public function startAsyncWithHttpInfo( + \Cone\SimplePay\Model\Transaction $transaction, + ?string $signature = null, + string $contentType = self::contentTypes['start'][0] + ): PromiseInterface { + $returnType = '\Cone\SimplePay\Model\Start200Response'; + $request = $this->startRequest($transaction, $signature, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if (in_array($returnType, ['\SplFileObject', '\Psr\Http\Message\StreamInterface'], true)) { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders(), + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'start' + * + * @param \Cone\SimplePay\Model\Transaction $transaction The transaction object you would like to start. (required) + * @param string|null $signature The signature. (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['start'] to see the possible values for this operation + * + * @throws InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function startRequest( + \Cone\SimplePay\Model\Transaction $transaction, + ?string $signature = null, + string $contentType = self::contentTypes['start'][0] + ): Request { + + // verify the required parameter 'transaction' is set + if ($transaction === null || (is_array($transaction) && count($transaction) === 0)) { + throw new InvalidArgumentException( + 'Missing the required parameter $transaction when calling start' + ); + } + + + + $resourcePath = '/start'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + // header params + if ($signature !== null) { + $headerParams['Signature'] = ObjectSerializer::toHeaderValue($signature); + } + + + + $headers = $this->headerSelector->selectHeaders( + ['application/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (isset($transaction)) { + if (stripos($headers['Content-Type'], 'application/json') !== false) { + // if Content-Type contains "application/json", json_encode the body + $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($transaction)); + } else { + $httpBody = $transaction; + } + } elseif (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem, + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + // if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'POST', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Create http client option + * + * @throws \RuntimeException on file opening failure + * @return array of http client options + */ + protected function createHttpClientOption(): array + { + $options = []; + if ($this->config->getDebug()) { + $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a'); + if (!$options[RequestOptions::DEBUG]) { + throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile()); + } + } + + return $options; + } + + private function handleResponseWithDataType( + string $dataType, + RequestInterface $request, + ResponseInterface $response, + ): array { + if (in_array($dataType, ['\SplFileObject', '\Psr\Http\Message\StreamInterface'], true)) { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($dataType !== 'string') { + try { + $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException $exception) { + throw new ApiException( + sprintf( + 'Error JSON decoding server response (%s)', + $request->getUri() + ), + $response->getStatusCode(), + $response->getHeaders(), + $content + ); + } + } + } + + return [ + ObjectSerializer::deserialize($content, $dataType, []), + $response->getStatusCode(), + $response->getHeaders(), + ]; + } + + private function responseWithinRangeCode( + string $rangeCode, + int $statusCode, + ): bool { + $left = (int) ($rangeCode[0].'00'); + $right = (int) ($rangeCode[0].'99'); + + return $statusCode >= $left && $statusCode <= $right; + } +} diff --git a/src/ApiException.php b/src/ApiException.php new file mode 100644 index 0000000..c4830f2 --- /dev/null +++ b/src/ApiException.php @@ -0,0 +1,118 @@ +responseHeaders = $responseHeaders; + $this->responseBody = $responseBody; + } + + /** + * Gets the HTTP response header + * + * @return string[][]|null HTTP response header + */ + public function getResponseHeaders(): ?array + { + return $this->responseHeaders; + } + + /** + * Gets the HTTP body of the server response either as Json or string + * + * @return stdClass|string|null HTTP body of the server response either as \stdClass or string + */ + public function getResponseBody(): stdClass|string|null + { + return $this->responseBody; + } + + /** + * Sets the deserialized response object (during deserialization) + * + * @param mixed $obj Deserialized response object + * + * @return void + */ + public function setResponseObject(mixed $obj): void + { + $this->responseObject = $obj; + } + + /** + * Gets the deserialized response object (during deserialization) + * + * @return mixed the deserialized response object + */ + public function getResponseObject(): mixed + { + return $this->responseObject; + } +} diff --git a/src/Configuration.php b/src/Configuration.php new file mode 100644 index 0000000..d7daa83 --- /dev/null +++ b/src/Configuration.php @@ -0,0 +1,530 @@ +tempFolderPath = sys_get_temp_dir(); + } + + /** + * Sets API key + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * @param string $key API key or token + * + * @return $this + */ + public function setApiKey(string $apiKeyIdentifier, string $key): static + { + $this->apiKeys[$apiKeyIdentifier] = $key; + return $this; + } + + /** + * Gets API key + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * + * @return null|string API key or token + */ + public function getApiKey(string $apiKeyIdentifier): ?string + { + return $this->apiKeys[$apiKeyIdentifier] ?? null; + } + + /** + * Sets the prefix for API key (e.g. Bearer) + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * @param string $prefix API key prefix, e.g. Bearer + * + * @return $this + */ + public function setApiKeyPrefix(string $apiKeyIdentifier, string $prefix): static + { + $this->apiKeyPrefixes[$apiKeyIdentifier] = $prefix; + return $this; + } + + /** + * Gets API key prefix + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * + * @return null|string + */ + public function getApiKeyPrefix(string $apiKeyIdentifier): ?string + { + return $this->apiKeyPrefixes[$apiKeyIdentifier] ?? null; + } + + /** + * Sets the access token for OAuth + * + * @param string $accessToken Token for OAuth + * + * @return $this + */ + public function setAccessToken(string $accessToken): static + { + $this->accessToken = $accessToken; + return $this; + } + + /** + * Gets the access token for OAuth + * + * @return string Access token for OAuth + */ + public function getAccessToken(): string + { + return $this->accessToken; + } + + /** + * Sets boolean format for query string. + * + * @param string $booleanFormat Boolean format for query string + * + * @return $this + */ + public function setBooleanFormatForQueryString(string $booleanFormat): static + { + $this->booleanFormatForQueryString = $booleanFormat; + + return $this; + } + + /** + * Gets boolean format for query string. + * + * @return string Boolean format for query string + */ + public function getBooleanFormatForQueryString(): string + { + return $this->booleanFormatForQueryString; + } + + /** + * Sets the username for HTTP basic authentication + * + * @param string $username Username for HTTP basic authentication + * + * @return $this + */ + public function setUsername(string $username): static + { + $this->username = $username; + return $this; + } + + /** + * Gets the username for HTTP basic authentication + * + * @return string Username for HTTP basic authentication + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * Sets the password for HTTP basic authentication + * + * @param string $password Password for HTTP basic authentication + * + * @return $this + */ + public function setPassword(string $password): static + { + $this->password = $password; + return $this; + } + + /** + * Gets the password for HTTP basic authentication + * + * @return string Password for HTTP basic authentication + */ + public function getPassword(): string + { + return $this->password; + } + + /** + * Sets the host + * + * @param string $host Host + * + * @return $this + */ + public function setHost(string $host): static + { + $this->host = $host; + return $this; + } + + /** + * Gets the host + * + * @return string Host + */ + public function getHost(): string + { + return $this->host; + } + + /** + * Sets the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * + * @throws InvalidArgumentException + * @return $this + */ + public function setUserAgent(string $userAgent): static + { + $this->userAgent = $userAgent; + return $this; + } + + /** + * Gets the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent(): string + { + return $this->userAgent; + } + + /** + * Sets debug flag + * + * @param bool $debug Debug flag + * + * @return $this + */ + public function setDebug(bool $debug): static + { + $this->debug = $debug; + return $this; + } + + /** + * Gets the debug flag + * + * @return bool + */ + public function getDebug(): bool + { + return $this->debug; + } + + /** + * Sets the debug file + * + * @param string $debugFile Debug file + * + * @return $this + */ + public function setDebugFile(string $debugFile): static + { + $this->debugFile = $debugFile; + return $this; + } + + /** + * Gets the debug file + * + * @return string + */ + public function getDebugFile(): string + { + return $this->debugFile; + } + + /** + * Sets the temp folder path + * + * @param string $tempFolderPath Temp folder path + * + * @return $this + */ + public function setTempFolderPath(string $tempFolderPath): static + { + $this->tempFolderPath = $tempFolderPath; + return $this; + } + + /** + * Gets the temp folder path + * + * @return string Temp folder path + */ + public function getTempFolderPath(): string + { + return $this->tempFolderPath; + } + + /** + * Gets the default configuration instance + * + * @return Configuration + */ + public static function getDefaultConfiguration(): Configuration + { + if (self::$defaultConfiguration === null) { + self::$defaultConfiguration = new Configuration(); + } + + return self::$defaultConfiguration; + } + + /** + * Sets the default configuration instance + * + * @param Configuration $config An instance of the Configuration Object + * + * @return void + */ + public static function setDefaultConfiguration(Configuration $config): void + { + self::$defaultConfiguration = $config; + } + + /** + * Gets the essential information for debugging + * + * @return string The report for debugging + */ + public static function toDebugReport(): string + { + $report = 'PHP SDK (Cone\SimplePay) Debug Report:' . PHP_EOL; + $report .= ' OS: ' . php_uname() . PHP_EOL; + $report .= ' PHP Version: ' . PHP_VERSION . PHP_EOL; + $report .= ' The version of the OpenAPI document: 2.0.0' . PHP_EOL; + $report .= ' Temp Folder Path: ' . self::getDefaultConfiguration()->getTempFolderPath() . PHP_EOL; + + return $report; + } + + /** + * Get API key (with prefix if set) + * + * @param string $apiKeyIdentifier name of apikey + * + * @return null|string API key with the prefix + */ + public function getApiKeyWithPrefix(string $apiKeyIdentifier): ?string + { + $prefix = $this->getApiKeyPrefix($apiKeyIdentifier); + $apiKey = $this->getApiKey($apiKeyIdentifier); + + if ($apiKey === null) { + return null; + } + + if ($prefix === null) { + $keyWithPrefix = $apiKey; + } else { + $keyWithPrefix = $prefix . ' ' . $apiKey; + } + + return $keyWithPrefix; + } + + /** + * Returns an array of host settings + * + * @return array an array of host settings + */ + public function getHostSettings(): array + { + return [ + [ + "url" => "https://secure.simplepay.hu/payment/v2", + "description" => "The Production SimplePay API", + ], + [ + "url" => "https://sandbox.simplepay.hu/payment/v2", + "description" => "The Test SimplePay API", + ], + ]; + } + + /** + * Returns URL based on host settings, index and variables + * + * @param array $hostSettings array of host settings, generated from getHostSettings() or equivalent from the API clients + * @param int $hostIndex index of the host settings + * @param array|null $variables hash of variable and the corresponding value (optional) + * @return string URL based on host settings + */ + public static function getHostString(array $hostSettings, int $hostIndex, ?array $variables = null): string + { + if (null === $variables) { + $variables = []; + } + + // check array index out of bound + if ($hostIndex < 0 || $hostIndex >= count($hostSettings)) { + throw new InvalidArgumentException("Invalid index $hostIndex when selecting the host. Must be less than ".count($hostSettings)); + } + + $host = $hostSettings[$hostIndex]; + $url = $host["url"]; + + // go through variable and assign a value + foreach ($host["variables"] ?? [] as $name => $variable) { + if (array_key_exists($name, $variables)) { // check to see if it's in the variables provided by the user + if (!isset($variable['enum_values']) || in_array($variables[$name], $variable["enum_values"], true)) { // check to see if the value is in the enum + $url = str_replace("{".$name."}", $variables[$name], $url); + } else { + throw new InvalidArgumentException("The variable `$name` in the host URL has invalid value ".$variables[$name].". Must be ".join(',', $variable["enum_values"])."."); + } + } else { + // use default value + $url = str_replace("{".$name."}", $variable["default_value"], $url); + } + } + + return $url; + } + + /** + * Returns URL based on the index and variables + * + * @param int $index index of the host settings + * @param array|null $variables hash of variable and the corresponding value (optional) + * @return string URL based on host settings + */ + public function getHostFromSettings(int $index, ?array $variables = null): string + { + return self::getHostString($this->getHostSettings(), $index, $variables); + } +} diff --git a/src/FormDataProcessor.php b/src/FormDataProcessor.php new file mode 100644 index 0000000..79d14b0 --- /dev/null +++ b/src/FormDataProcessor.php @@ -0,0 +1,237 @@ + $values the value of the form parameter + * + * @return array [key => value] of formdata + */ + public function prepare(array $values): array + { + $this->has_file = false; + $result = []; + + foreach ($values as $k => $v) { + if ($v === null) { + continue; + } + + $result[$k] = $this->makeFormSafe($v); + } + + return $result; + } + + /** + * Flattens a multi-level array of data and generates a single-level array + * compatible with formdata - a single-level array where the keys use bracket + * notation to signify nested data. + * + * credit: https://github.com/FranBar1966/FlatPHP + */ + public static function flatten(array $source, string $start = ''): array + { + $opt = [ + 'prefix' => '[', + 'suffix' => ']', + 'suffix-end' => true, + 'prefix-list' => '[', + 'suffix-list' => ']', + 'suffix-list-end' => true, + ]; + + if ($start === '') { + $currentPrefix = ''; + $currentSuffix = ''; + $currentSuffixEnd = false; + } elseif (array_is_list($source)) { + $currentPrefix = $opt['prefix-list']; + $currentSuffix = $opt['suffix-list']; + $currentSuffixEnd = $opt['suffix-list-end']; + } else { + $currentPrefix = $opt['prefix']; + $currentSuffix = $opt['suffix']; + $currentSuffixEnd = $opt['suffix-end']; + } + + $currentName = $start; + $result = []; + + foreach ($source as $key => $val) { + $currentName .= $currentPrefix . $key; + + if (is_array($val) && !empty($val)) { + $currentName .= $currentSuffix; + $result += self::flatten($val, $currentName); + } else { + if ($currentSuffixEnd) { + $currentName .= $currentSuffix; + } + + $result[$currentName] = ObjectSerializer::toString($val); + } + + $currentName = $start; + } + + return $result; + } + + /** + * formdata must be limited to scalars or arrays of scalar values, + * or a resource for a file upload. Here we iterate through all available + * data and identify how to handle each scenario + * + * @param string|bool|array|DateTime|ArrayAccess|SplFileObject $value + */ + protected function makeFormSafe(mixed $value) + { + if ($value instanceof SplFileObject) { + return $this->processFiles([$value])[0]; + } + + if (is_resource($value)) { + $this->has_file = true; + + return $value; + } + + if ($value instanceof ModelInterface) { + return $this->processModel($value); + } + + if (is_array($value) || is_object($value)) { + $data = []; + + foreach ($value as $k => $v) { + $data[$k] = $this->makeFormSafe($v); + } + + return $data; + } + + return ObjectSerializer::toString($value); + } + + /** + * We are able to handle nested ModelInterface. We do not simply call + * json_decode(json_encode()) because any given model may have binary data + * or other data that cannot be serialized to a JSON string + */ + protected function processModel(ModelInterface $model): array + { + $result = []; + + foreach ($model::openAPITypes() as $name => $type) { + $value = $model->offsetGet($name); + + if ($value === null) { + continue; + } + + if (str_contains($type, '\SplFileObject')) { + $file = is_array($value) ? $value : [$value]; + $result[$name] = $this->processFiles($file); + + continue; + } + + if ($value instanceof ModelInterface) { + $result[$name] = $this->processModel($value); + + continue; + } + + if (is_array($value) || is_object($value)) { + $result[$name] = $this->makeFormSafe($value); + + continue; + } + + $result[$name] = ObjectSerializer::toString($value); + } + + return $result; + } + + /** + * Handle file data + */ + protected function processFiles(array $files): array + { + $this->has_file = true; + + $result = []; + + foreach ($files as $i => $file) { + if (is_array($file)) { + $result[$i] = $this->processFiles($file); + + continue; + } + + if ($file instanceof StreamInterface) { + $result[$i] = $file; + + continue; + } + + if ($file instanceof SplFileObject) { + $result[$i] = $this->tryFopen($file); + } + } + + return $result; + } + + private function tryFopen(SplFileObject $file) + { + return Utils::tryFopen($file->getRealPath(), 'rb'); + } +} diff --git a/src/HeaderSelector.php b/src/HeaderSelector.php new file mode 100644 index 0000000..f3349aa --- /dev/null +++ b/src/HeaderSelector.php @@ -0,0 +1,242 @@ +selectAcceptHeader($accept); + if ($accept !== null) { + $headers['Accept'] = $accept; + } + + if (!$isMultipart) { + if ($contentType === '') { + $contentType = 'application/json'; + } + + $headers['Content-Type'] = $contentType; + } + + return $headers; + } + + /** + * Return the header 'Accept' based on an array of Accept provided. + * + * @param string[] $accept Array of header + * + * @return null|string Accept (e.g. application/json) + */ + private function selectAcceptHeader(array $accept): ?string + { + // filter out empty entries + $accept = array_filter($accept); + + if (count($accept) === 0) { + return null; + } + + // If there's only one Accept header, just use it + if (count($accept) === 1) { + return reset($accept); + } + + // If none of the available Accept headers is of type "json", then just use all them + $headersWithJson = preg_grep('~(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$~', $accept); + if (count($headersWithJson) === 0) { + return implode(',', $accept); + } + + // If we got here, then we need add quality values (weight), as described in IETF RFC 9110, Items 12.4.2/12.5.1, + // to give the highest priority to json-like headers - recalculating the existing ones, if needed + return $this->getAcceptHeaderWithAdjustedWeight($accept, $headersWithJson); + } + + /** + * Create an Accept header string from the given "Accept" headers array, recalculating all weights + * + * @param string[] $accept Array of Accept Headers + * @param string[] $headersWithJson Array of Accept Headers of type "json" + * + * @return string "Accept" Header (e.g. "application/json, text/html; q=0.9") + */ + private function getAcceptHeaderWithAdjustedWeight(array $accept, array $headersWithJson): string + { + $processedHeaders = [ + 'withApplicationJson' => [], + 'withJson' => [], + 'withoutJson' => [], + ]; + + foreach ($accept as $header) { + + $headerData = $this->getHeaderAndWeight($header); + + if (stripos($headerData['header'], 'application/json') === 0) { + $processedHeaders['withApplicationJson'][] = $headerData; + } elseif (in_array($header, $headersWithJson, true)) { + $processedHeaders['withJson'][] = $headerData; + } else { + $processedHeaders['withoutJson'][] = $headerData; + } + } + + $acceptHeaders = []; + $currentWeight = 1000; + + $hasMoreThan28Headers = count($accept) > 28; + + foreach ($processedHeaders as $headers) { + if (count($headers) > 0) { + $acceptHeaders[] = $this->adjustWeight($headers, $currentWeight, $hasMoreThan28Headers); + } + } + + $acceptHeaders = array_merge(...$acceptHeaders); + + return implode(',', $acceptHeaders); + } + + /** + * Given an Accept header, returns an associative array splitting the header and its weight + * + * @param string $header "Accept" Header + * + * @return array with the header and its weight + */ + private function getHeaderAndWeight(string $header): array + { + // matches headers with weight, splitting the header and the weight in $outputArray + if (preg_match('/(.*);\s*q=(1(?:\.0+)?|0\.\d+)$/', $header, $outputArray) === 1) { + $headerData = [ + 'header' => $outputArray[1], + 'weight' => (int)($outputArray[2] * 1000), + ]; + } else { + $headerData = [ + 'header' => trim($header), + 'weight' => 1000, + ]; + } + + return $headerData; + } + + /** + * @param array[] $headers + * @param float $currentWeight + * @param bool $hasMoreThan28Headers + * @return string[] array of adjusted "Accept" headers + */ + private function adjustWeight(array $headers, float &$currentWeight, bool $hasMoreThan28Headers): array + { + usort($headers, function (array $a, array $b) { + return $b['weight'] - $a['weight']; + }); + + $acceptHeaders = []; + foreach ($headers as $index => $header) { + if ($index > 0 && $headers[$index - 1]['weight'] > $header['weight']) { + $currentWeight = $this->getNextWeight($currentWeight, $hasMoreThan28Headers); + } + + $weight = $currentWeight; + + $acceptHeaders[] = $this->buildAcceptHeader($header['header'], $weight); + } + + $currentWeight = $this->getNextWeight($currentWeight, $hasMoreThan28Headers); + + return $acceptHeaders; + } + + /** + * @param string $header + * @param int $weight + * @return string + */ + private function buildAcceptHeader(string $header, int $weight): string + { + if ($weight === 1000) { + return $header; + } + + return trim($header, '; ') . ';q=' . rtrim(sprintf('%0.3f', $weight / 1000), '0'); + } + + /** + * Calculate the next weight, based on the current one. + * + * If there are less than 28 "Accept" headers, the weights will be decreased by 1 on its highest significant digit, using the + * following formula: + * + * next weight = current weight - 10 ^ (floor(log(current weight - 1))) + * + * ( current weight minus ( 10 raised to the power of ( floor of (log to the base 10 of ( current weight minus 1 ) ) ) ) ) + * + * Starting from 1000, this generates the following series: + * + * 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 + * + * The resulting quality codes are closer to the average "normal" usage of them (like "q=0.9", "q=0.8" and so on), but it only works + * if there is a maximum of 28 "Accept" headers. If we have more than that (which is extremely unlikely), then we fall back to a 1-by-1 + * decrement rule, which will result in quality codes like "q=0.999", "q=0.998" etc. + * + * @param int $currentWeight varying from 1 to 1000 (will be divided by 1000 to build the quality value) + * @param bool $hasMoreThan28Headers + * @return int + */ + public function getNextWeight(int $currentWeight, bool $hasMoreThan28Headers): int + { + if ($currentWeight <= 1) { + return 1; + } + + if ($hasMoreThan28Headers) { + return $currentWeight - 1; + } + + return $currentWeight - 10 ** floor(log10($currentWeight - 1)); + } +} diff --git a/src/Model/Currency.php b/src/Model/Currency.php new file mode 100644 index 0000000..4351eeb --- /dev/null +++ b/src/Model/Currency.php @@ -0,0 +1,44 @@ + + */ +class Delivery implements ModelInterface, ArrayAccess, JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static string $openAPIModelName = 'Delivery'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPITypes = [ + 'city' => 'string', + 'phone' => 'string', + 'state' => 'string', + 'zip' => 'string', + 'company' => 'string', + 'country' => 'string', + 'address' => 'string', + 'address2' => 'string', + 'name' => 'string', + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPIFormats = [ + 'city' => null, + 'phone' => null, + 'state' => null, + 'zip' => null, + 'company' => null, + 'country' => null, + 'address' => null, + 'address2' => null, + 'name' => null, + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var array + */ + protected static array $openAPINullables = [ + 'city' => false, + 'phone' => false, + 'state' => false, + 'zip' => false, + 'company' => false, + 'country' => false, + 'address' => false, + 'address2' => true, + 'name' => false, + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var array + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes(): array + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats(): array + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return array + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param array $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var array + */ + protected static array $attributeMap = [ + 'city' => 'city', + 'phone' => 'phone', + 'state' => 'state', + 'zip' => 'zip', + 'company' => 'company', + 'country' => 'country', + 'address' => 'address', + 'address2' => 'address2', + 'name' => 'name', + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var array + */ + protected static array $setters = [ + 'city' => 'setCity', + 'phone' => 'setPhone', + 'state' => 'setState', + 'zip' => 'setZip', + 'company' => 'setCompany', + 'country' => 'setCountry', + 'address' => 'setAddress', + 'address2' => 'setAddress2', + 'name' => 'setName', + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var array + */ + protected static array $getters = [ + 'city' => 'getCity', + 'phone' => 'getPhone', + 'state' => 'getState', + 'zip' => 'getZip', + 'company' => 'getCompany', + 'country' => 'getCountry', + 'address' => 'getAddress', + 'address2' => 'getAddress2', + 'name' => 'getName', + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap(): array + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters(): array + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters(): array + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName(): string + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var array + */ + protected array $container = []; + + /** + * Constructor + * + * @param array $data Associated array of property values initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('city', $data ?? [], null); + $this->setIfExists('phone', $data ?? [], null); + $this->setIfExists('state', $data ?? [], null); + $this->setIfExists('zip', $data ?? [], null); + $this->setIfExists('company', $data ?? [], null); + $this->setIfExists('country', $data ?? [], null); + $this->setIfExists('address', $data ?? [], null); + $this->setIfExists('address2', $data ?? [], null); + $this->setIfExists('name', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, mixed $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return string[] invalid properties with reasons + */ + public function listInvalidProperties(): array + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid(): bool + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets city + * + * @return string|null + */ + public function getCity(): ?string + { + return $this->container['city']; + } + + /** + * Sets city + * + * @param string|null $city city + * + * @return $this + */ + public function setCity(?string $city): static + { + if (is_null($city)) { + throw new InvalidArgumentException('non-nullable city cannot be null'); + } + $this->container['city'] = $city; + + return $this; + } + + /** + * Gets phone + * + * @return string|null + */ + public function getPhone(): ?string + { + return $this->container['phone']; + } + + /** + * Sets phone + * + * @param string|null $phone phone + * + * @return $this + */ + public function setPhone(?string $phone): static + { + if (is_null($phone)) { + throw new InvalidArgumentException('non-nullable phone cannot be null'); + } + $this->container['phone'] = $phone; + + return $this; + } + + /** + * Gets state + * + * @return string|null + */ + public function getState(): ?string + { + return $this->container['state']; + } + + /** + * Sets state + * + * @param string|null $state state + * + * @return $this + */ + public function setState(?string $state): static + { + if (is_null($state)) { + throw new InvalidArgumentException('non-nullable state cannot be null'); + } + $this->container['state'] = $state; + + return $this; + } + + /** + * Gets zip + * + * @return string|null + */ + public function getZip(): ?string + { + return $this->container['zip']; + } + + /** + * Sets zip + * + * @param string|null $zip zip + * + * @return $this + */ + public function setZip(?string $zip): static + { + if (is_null($zip)) { + throw new InvalidArgumentException('non-nullable zip cannot be null'); + } + $this->container['zip'] = $zip; + + return $this; + } + + /** + * Gets company + * + * @return string|null + */ + public function getCompany(): ?string + { + return $this->container['company']; + } + + /** + * Sets company + * + * @param string|null $company company + * + * @return $this + */ + public function setCompany(?string $company): static + { + if (is_null($company)) { + throw new InvalidArgumentException('non-nullable company cannot be null'); + } + $this->container['company'] = $company; + + return $this; + } + + /** + * Gets country + * + * @return string|null + */ + public function getCountry(): ?string + { + return $this->container['country']; + } + + /** + * Sets country + * + * @param string|null $country The ISO 3166-1 alpha-2 format of the country. + * + * @return $this + */ + public function setCountry(?string $country): static + { + if (is_null($country)) { + throw new InvalidArgumentException('non-nullable country cannot be null'); + } + $this->container['country'] = $country; + + return $this; + } + + /** + * Gets address + * + * @return string|null + */ + public function getAddress(): ?string + { + return $this->container['address']; + } + + /** + * Sets address + * + * @param string|null $address address + * + * @return $this + */ + public function setAddress(?string $address): static + { + if (is_null($address)) { + throw new InvalidArgumentException('non-nullable address cannot be null'); + } + $this->container['address'] = $address; + + return $this; + } + + /** + * Gets address2 + * + * @return string|null + */ + public function getAddress2(): ?string + { + return $this->container['address2']; + } + + /** + * Sets address2 + * + * @param string|null $address2 address2 + * + * @return $this + */ + public function setAddress2(?string $address2): static + { + if (is_null($address2)) { + array_push($this->openAPINullablesSetToNull, 'address2'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('address2', $nullablesSetToNull, true); + if ($index !== false) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['address2'] = $address2; + + return $this; + } + + /** + * Gets name + * + * @return string|null + */ + public function getName(): ?string + { + return $this->container['name']; + } + + /** + * Sets name + * + * @param string|null $name name + * + * @return $this + */ + public function setName(?string $name): static + { + if (is_null($name)) { + throw new InvalidArgumentException('non-nullable name cannot be null'); + } + $this->container['name'] = $name; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param int $offset Offset + * + * @return bool + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param int $offset Offset + * + * @return mixed|null + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset): mixed + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet(mixed $offset, mixed $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param int $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[ReturnTypeWillChange] + public function jsonSerialize(): mixed + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString(): string + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue(): string + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} diff --git a/src/Model/Invoice.php b/src/Model/Invoice.php new file mode 100644 index 0000000..ca41ee1 --- /dev/null +++ b/src/Model/Invoice.php @@ -0,0 +1,684 @@ + + */ +class Invoice implements ModelInterface, ArrayAccess, JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static string $openAPIModelName = 'Invoice'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPITypes = [ + 'city' => 'string', + 'phone' => 'string', + 'state' => 'string', + 'zip' => 'string', + 'company' => 'string', + 'country' => 'string', + 'address' => 'string', + 'address2' => 'string', + 'name' => 'string', + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPIFormats = [ + 'city' => null, + 'phone' => null, + 'state' => null, + 'zip' => null, + 'company' => null, + 'country' => null, + 'address' => null, + 'address2' => null, + 'name' => null, + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var array + */ + protected static array $openAPINullables = [ + 'city' => false, + 'phone' => false, + 'state' => false, + 'zip' => false, + 'company' => false, + 'country' => false, + 'address' => false, + 'address2' => true, + 'name' => false, + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var array + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes(): array + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats(): array + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return array + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param array $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var array + */ + protected static array $attributeMap = [ + 'city' => 'city', + 'phone' => 'phone', + 'state' => 'state', + 'zip' => 'zip', + 'company' => 'company', + 'country' => 'country', + 'address' => 'address', + 'address2' => 'address2', + 'name' => 'name', + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var array + */ + protected static array $setters = [ + 'city' => 'setCity', + 'phone' => 'setPhone', + 'state' => 'setState', + 'zip' => 'setZip', + 'company' => 'setCompany', + 'country' => 'setCountry', + 'address' => 'setAddress', + 'address2' => 'setAddress2', + 'name' => 'setName', + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var array + */ + protected static array $getters = [ + 'city' => 'getCity', + 'phone' => 'getPhone', + 'state' => 'getState', + 'zip' => 'getZip', + 'company' => 'getCompany', + 'country' => 'getCountry', + 'address' => 'getAddress', + 'address2' => 'getAddress2', + 'name' => 'getName', + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap(): array + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters(): array + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters(): array + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName(): string + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var array + */ + protected array $container = []; + + /** + * Constructor + * + * @param array $data Associated array of property values initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('city', $data ?? [], null); + $this->setIfExists('phone', $data ?? [], null); + $this->setIfExists('state', $data ?? [], null); + $this->setIfExists('zip', $data ?? [], null); + $this->setIfExists('company', $data ?? [], null); + $this->setIfExists('country', $data ?? [], null); + $this->setIfExists('address', $data ?? [], null); + $this->setIfExists('address2', $data ?? [], null); + $this->setIfExists('name', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, mixed $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return string[] invalid properties with reasons + */ + public function listInvalidProperties(): array + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid(): bool + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets city + * + * @return string|null + */ + public function getCity(): ?string + { + return $this->container['city']; + } + + /** + * Sets city + * + * @param string|null $city city + * + * @return $this + */ + public function setCity(?string $city): static + { + if (is_null($city)) { + throw new InvalidArgumentException('non-nullable city cannot be null'); + } + $this->container['city'] = $city; + + return $this; + } + + /** + * Gets phone + * + * @return string|null + */ + public function getPhone(): ?string + { + return $this->container['phone']; + } + + /** + * Sets phone + * + * @param string|null $phone phone + * + * @return $this + */ + public function setPhone(?string $phone): static + { + if (is_null($phone)) { + throw new InvalidArgumentException('non-nullable phone cannot be null'); + } + $this->container['phone'] = $phone; + + return $this; + } + + /** + * Gets state + * + * @return string|null + */ + public function getState(): ?string + { + return $this->container['state']; + } + + /** + * Sets state + * + * @param string|null $state state + * + * @return $this + */ + public function setState(?string $state): static + { + if (is_null($state)) { + throw new InvalidArgumentException('non-nullable state cannot be null'); + } + $this->container['state'] = $state; + + return $this; + } + + /** + * Gets zip + * + * @return string|null + */ + public function getZip(): ?string + { + return $this->container['zip']; + } + + /** + * Sets zip + * + * @param string|null $zip zip + * + * @return $this + */ + public function setZip(?string $zip): static + { + if (is_null($zip)) { + throw new InvalidArgumentException('non-nullable zip cannot be null'); + } + $this->container['zip'] = $zip; + + return $this; + } + + /** + * Gets company + * + * @return string|null + */ + public function getCompany(): ?string + { + return $this->container['company']; + } + + /** + * Sets company + * + * @param string|null $company company + * + * @return $this + */ + public function setCompany(?string $company): static + { + if (is_null($company)) { + throw new InvalidArgumentException('non-nullable company cannot be null'); + } + $this->container['company'] = $company; + + return $this; + } + + /** + * Gets country + * + * @return string|null + */ + public function getCountry(): ?string + { + return $this->container['country']; + } + + /** + * Sets country + * + * @param string|null $country The ISO 3166-1 alpha-2 format of the country. + * + * @return $this + */ + public function setCountry(?string $country): static + { + if (is_null($country)) { + throw new InvalidArgumentException('non-nullable country cannot be null'); + } + $this->container['country'] = $country; + + return $this; + } + + /** + * Gets address + * + * @return string|null + */ + public function getAddress(): ?string + { + return $this->container['address']; + } + + /** + * Sets address + * + * @param string|null $address address + * + * @return $this + */ + public function setAddress(?string $address): static + { + if (is_null($address)) { + throw new InvalidArgumentException('non-nullable address cannot be null'); + } + $this->container['address'] = $address; + + return $this; + } + + /** + * Gets address2 + * + * @return string|null + */ + public function getAddress2(): ?string + { + return $this->container['address2']; + } + + /** + * Sets address2 + * + * @param string|null $address2 address2 + * + * @return $this + */ + public function setAddress2(?string $address2): static + { + if (is_null($address2)) { + array_push($this->openAPINullablesSetToNull, 'address2'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('address2', $nullablesSetToNull, true); + if ($index !== false) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['address2'] = $address2; + + return $this; + } + + /** + * Gets name + * + * @return string|null + */ + public function getName(): ?string + { + return $this->container['name']; + } + + /** + * Sets name + * + * @param string|null $name name + * + * @return $this + */ + public function setName(?string $name): static + { + if (is_null($name)) { + throw new InvalidArgumentException('non-nullable name cannot be null'); + } + $this->container['name'] = $name; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param int $offset Offset + * + * @return bool + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param int $offset Offset + * + * @return mixed|null + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset): mixed + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet(mixed $offset, mixed $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param int $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[ReturnTypeWillChange] + public function jsonSerialize(): mixed + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString(): string + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue(): string + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} diff --git a/src/Model/Item.php b/src/Model/Item.php new file mode 100644 index 0000000..fc93426 --- /dev/null +++ b/src/Model/Item.php @@ -0,0 +1,612 @@ + + */ +class Item implements ModelInterface, ArrayAccess, JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static string $openAPIModelName = 'Item'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPITypes = [ + 'ref' => 'string', + 'title' => 'string', + 'desc' => 'string', + 'amount' => 'float', + 'price' => 'float', + 'tax' => 'float', + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPIFormats = [ + 'ref' => null, + 'title' => null, + 'desc' => null, + 'amount' => null, + 'price' => null, + 'tax' => null, + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var array + */ + protected static array $openAPINullables = [ + 'ref' => false, + 'title' => false, + 'desc' => true, + 'amount' => false, + 'price' => false, + 'tax' => false, + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var array + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes(): array + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats(): array + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return array + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param array $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var array + */ + protected static array $attributeMap = [ + 'ref' => 'ref', + 'title' => 'title', + 'desc' => 'desc', + 'amount' => 'amount', + 'price' => 'price', + 'tax' => 'tax', + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var array + */ + protected static array $setters = [ + 'ref' => 'setRef', + 'title' => 'setTitle', + 'desc' => 'setDesc', + 'amount' => 'setAmount', + 'price' => 'setPrice', + 'tax' => 'setTax', + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var array + */ + protected static array $getters = [ + 'ref' => 'getRef', + 'title' => 'getTitle', + 'desc' => 'getDesc', + 'amount' => 'getAmount', + 'price' => 'getPrice', + 'tax' => 'getTax', + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap(): array + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters(): array + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters(): array + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName(): string + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var array + */ + protected array $container = []; + + /** + * Constructor + * + * @param array $data Associated array of property values initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('ref', $data ?? [], null); + $this->setIfExists('title', $data ?? [], null); + $this->setIfExists('desc', $data ?? [], null); + $this->setIfExists('amount', $data ?? [], null); + $this->setIfExists('price', $data ?? [], null); + $this->setIfExists('tax', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, mixed $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return string[] invalid properties with reasons + */ + public function listInvalidProperties(): array + { + $invalidProperties = []; + + if ($this->container['ref'] === null) { + $invalidProperties[] = "'ref' can't be null"; + } + if ($this->container['title'] === null) { + $invalidProperties[] = "'title' can't be null"; + } + if ($this->container['amount'] === null) { + $invalidProperties[] = "'amount' can't be null"; + } + if (($this->container['amount'] <= 0)) { + $invalidProperties[] = "invalid value for 'amount', must be bigger than 0."; + } + + if ($this->container['price'] === null) { + $invalidProperties[] = "'price' can't be null"; + } + if (($this->container['price'] <= 0)) { + $invalidProperties[] = "invalid value for 'price', must be bigger than 0."; + } + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid(): bool + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets ref + * + * @return string + */ + public function getRef(): string + { + return $this->container['ref']; + } + + /** + * Sets ref + * + * @param string $ref ref + * + * @return $this + */ + public function setRef(string $ref): static + { + if (is_null($ref)) { + throw new InvalidArgumentException('non-nullable ref cannot be null'); + } + $this->container['ref'] = $ref; + + return $this; + } + + /** + * Gets title + * + * @return string + */ + public function getTitle(): string + { + return $this->container['title']; + } + + /** + * Sets title + * + * @param string $title title + * + * @return $this + */ + public function setTitle(string $title): static + { + if (is_null($title)) { + throw new InvalidArgumentException('non-nullable title cannot be null'); + } + $this->container['title'] = $title; + + return $this; + } + + /** + * Gets desc + * + * @return string|null + */ + public function getDesc(): ?string + { + return $this->container['desc']; + } + + /** + * Sets desc + * + * @param string|null $desc desc + * + * @return $this + */ + public function setDesc(?string $desc): static + { + if (is_null($desc)) { + array_push($this->openAPINullablesSetToNull, 'desc'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('desc', $nullablesSetToNull, true); + if ($index !== false) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['desc'] = $desc; + + return $this; + } + + /** + * Gets amount + * + * @return float + */ + public function getAmount(): float + { + return $this->container['amount']; + } + + /** + * Sets amount + * + * @param float $amount amount + * + * @return $this + */ + public function setAmount(float $amount): static + { + if (is_null($amount)) { + throw new InvalidArgumentException('non-nullable amount cannot be null'); + } + + if (($amount <= 0)) { + throw new InvalidArgumentException('invalid value for $amount when calling Item., must be bigger than 0.'); + } + + $this->container['amount'] = $amount; + + return $this; + } + + /** + * Gets price + * + * @return float + */ + public function getPrice(): float + { + return $this->container['price']; + } + + /** + * Sets price + * + * @param float $price price + * + * @return $this + */ + public function setPrice(float $price): static + { + if (is_null($price)) { + throw new InvalidArgumentException('non-nullable price cannot be null'); + } + + if (($price <= 0)) { + throw new InvalidArgumentException('invalid value for $price when calling Item., must be bigger than 0.'); + } + + $this->container['price'] = $price; + + return $this; + } + + /** + * Gets tax + * + * @return float|null + */ + public function getTax(): ?float + { + return $this->container['tax']; + } + + /** + * Sets tax + * + * @param float|null $tax tax + * + * @return $this + */ + public function setTax(?float $tax): static + { + if (is_null($tax)) { + throw new InvalidArgumentException('non-nullable tax cannot be null'); + } + $this->container['tax'] = $tax; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param int $offset Offset + * + * @return bool + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param int $offset Offset + * + * @return mixed|null + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset): mixed + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet(mixed $offset, mixed $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param int $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[ReturnTypeWillChange] + public function jsonSerialize(): mixed + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString(): string + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue(): string + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} diff --git a/src/Model/Language.php b/src/Model/Language.php new file mode 100644 index 0000000..1667ff4 --- /dev/null +++ b/src/Model/Language.php @@ -0,0 +1,70 @@ + + */ +class Start200Response implements ModelInterface, ArrayAccess, JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static string $openAPIModelName = 'start_200_response'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPITypes = [ + 'salt' => 'string', + 'merchant' => 'string', + 'orderRef' => 'string', + 'currency' => '\Cone\SimplePay\Model\Currency', + 'transactionId' => 'float', + 'timeout' => 'string', + 'total' => 'float', + 'paymentUrl' => 'string', + 'tokens' => 'string[]', + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPIFormats = [ + 'salt' => null, + 'merchant' => null, + 'orderRef' => null, + 'currency' => null, + 'transactionId' => null, + 'timeout' => null, + 'total' => null, + 'paymentUrl' => null, + 'tokens' => null, + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var array + */ + protected static array $openAPINullables = [ + 'salt' => false, + 'merchant' => false, + 'orderRef' => false, + 'currency' => false, + 'transactionId' => false, + 'timeout' => false, + 'total' => false, + 'paymentUrl' => false, + 'tokens' => false, + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var array + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes(): array + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats(): array + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return array + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param array $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var array + */ + protected static array $attributeMap = [ + 'salt' => 'salt', + 'merchant' => 'merchant', + 'orderRef' => 'orderRef', + 'currency' => 'currency', + 'transactionId' => 'transactionId', + 'timeout' => 'timeout', + 'total' => 'total', + 'paymentUrl' => 'paymentUrl', + 'tokens' => 'tokens', + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var array + */ + protected static array $setters = [ + 'salt' => 'setSalt', + 'merchant' => 'setMerchant', + 'orderRef' => 'setOrderRef', + 'currency' => 'setCurrency', + 'transactionId' => 'setTransactionId', + 'timeout' => 'setTimeout', + 'total' => 'setTotal', + 'paymentUrl' => 'setPaymentUrl', + 'tokens' => 'setTokens', + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var array + */ + protected static array $getters = [ + 'salt' => 'getSalt', + 'merchant' => 'getMerchant', + 'orderRef' => 'getOrderRef', + 'currency' => 'getCurrency', + 'transactionId' => 'getTransactionId', + 'timeout' => 'getTimeout', + 'total' => 'getTotal', + 'paymentUrl' => 'getPaymentUrl', + 'tokens' => 'getTokens', + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap(): array + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters(): array + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters(): array + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName(): string + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var array + */ + protected array $container = []; + + /** + * Constructor + * + * @param array $data Associated array of property values initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('salt', $data ?? [], null); + $this->setIfExists('merchant', $data ?? [], null); + $this->setIfExists('orderRef', $data ?? [], null); + $this->setIfExists('currency', $data ?? [], null); + $this->setIfExists('transactionId', $data ?? [], null); + $this->setIfExists('timeout', $data ?? [], null); + $this->setIfExists('total', $data ?? [], null); + $this->setIfExists('paymentUrl', $data ?? [], null); + $this->setIfExists('tokens', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, mixed $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return string[] invalid properties with reasons + */ + public function listInvalidProperties(): array + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid(): bool + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets salt + * + * @return string|null + */ + public function getSalt(): ?string + { + return $this->container['salt']; + } + + /** + * Sets salt + * + * @param string|null $salt salt + * + * @return $this + */ + public function setSalt(?string $salt): static + { + if (is_null($salt)) { + throw new InvalidArgumentException('non-nullable salt cannot be null'); + } + $this->container['salt'] = $salt; + + return $this; + } + + /** + * Gets merchant + * + * @return string|null + */ + public function getMerchant(): ?string + { + return $this->container['merchant']; + } + + /** + * Sets merchant + * + * @param string|null $merchant merchant + * + * @return $this + */ + public function setMerchant(?string $merchant): static + { + if (is_null($merchant)) { + throw new InvalidArgumentException('non-nullable merchant cannot be null'); + } + $this->container['merchant'] = $merchant; + + return $this; + } + + /** + * Gets orderRef + * + * @return string|null + */ + public function getOrderRef(): ?string + { + return $this->container['orderRef']; + } + + /** + * Sets orderRef + * + * @param string|null $orderRef orderRef + * + * @return $this + */ + public function setOrderRef(?string $orderRef): static + { + if (is_null($orderRef)) { + throw new InvalidArgumentException('non-nullable orderRef cannot be null'); + } + $this->container['orderRef'] = $orderRef; + + return $this; + } + + /** + * Gets currency + * + * @return \Cone\SimplePay\Model\Currency|null + */ + public function getCurrency(): ?\Cone\SimplePay\Model\Currency + { + return $this->container['currency']; + } + + /** + * Sets currency + * + * @param \Cone\SimplePay\Model\Currency|null $currency currency + * + * @return $this + */ + public function setCurrency(?\Cone\SimplePay\Model\Currency $currency): static + { + if (is_null($currency)) { + throw new InvalidArgumentException('non-nullable currency cannot be null'); + } + $this->container['currency'] = $currency; + + return $this; + } + + /** + * Gets transactionId + * + * @return float|null + */ + public function getTransactionId(): ?float + { + return $this->container['transactionId']; + } + + /** + * Sets transactionId + * + * @param float|null $transactionId transactionId + * + * @return $this + */ + public function setTransactionId(?float $transactionId): static + { + if (is_null($transactionId)) { + throw new InvalidArgumentException('non-nullable transactionId cannot be null'); + } + $this->container['transactionId'] = $transactionId; + + return $this; + } + + /** + * Gets timeout + * + * @return string|null + */ + public function getTimeout(): ?string + { + return $this->container['timeout']; + } + + /** + * Sets timeout + * + * @param string|null $timeout The ISO 8601 format of the timeout date. + * + * @return $this + */ + public function setTimeout(?string $timeout): static + { + if (is_null($timeout)) { + throw new InvalidArgumentException('non-nullable timeout cannot be null'); + } + $this->container['timeout'] = $timeout; + + return $this; + } + + /** + * Gets total + * + * @return float|null + */ + public function getTotal(): ?float + { + return $this->container['total']; + } + + /** + * Sets total + * + * @param float|null $total total + * + * @return $this + */ + public function setTotal(?float $total): static + { + if (is_null($total)) { + throw new InvalidArgumentException('non-nullable total cannot be null'); + } + $this->container['total'] = $total; + + return $this; + } + + /** + * Gets paymentUrl + * + * @return string|null + */ + public function getPaymentUrl(): ?string + { + return $this->container['paymentUrl']; + } + + /** + * Sets paymentUrl + * + * @param string|null $paymentUrl The payment interface URL. + * + * @return $this + */ + public function setPaymentUrl(?string $paymentUrl): static + { + if (is_null($paymentUrl)) { + throw new InvalidArgumentException('non-nullable paymentUrl cannot be null'); + } + $this->container['paymentUrl'] = $paymentUrl; + + return $this; + } + + /** + * Gets tokens + * + * @return string[]|null + */ + public function getTokens(): ?array + { + return $this->container['tokens']; + } + + /** + * Sets tokens + * + * @param string[]|null $tokens The recurring payment tokens. Provided only for the inital recurring payment. + * + * @return $this + */ + public function setTokens(?array $tokens): static + { + if (is_null($tokens)) { + throw new InvalidArgumentException('non-nullable tokens cannot be null'); + } + $this->container['tokens'] = $tokens; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param int $offset Offset + * + * @return bool + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param int $offset Offset + * + * @return mixed|null + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset): mixed + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet(mixed $offset, mixed $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param int $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[ReturnTypeWillChange] + public function jsonSerialize(): mixed + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString(): string + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue(): string + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} diff --git a/src/Model/Transaction.php b/src/Model/Transaction.php new file mode 100644 index 0000000..3acd21d --- /dev/null +++ b/src/Model/Transaction.php @@ -0,0 +1,1047 @@ + + */ +class Transaction implements ModelInterface, ArrayAccess, JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static string $openAPIModelName = 'Transaction'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPITypes = [ + 'customer' => 'string', + 'customerEmail' => 'string', + 'currency' => '\Cone\SimplePay\Model\Currency', + 'maySelectInvoice' => 'bool', + 'maySelectEmail' => 'bool', + 'maySelectDelivery' => 'string[]', + 'twoStep' => 'bool', + 'onlyCardReg' => 'bool', + 'url' => 'string', + 'urls' => '\Cone\SimplePay\Model\TransactionUrls', + 'language' => '\Cone\SimplePay\Model\Language', + 'discount' => 'float', + 'shippingCost' => 'float', + 'total' => 'float', + 'delivery' => '\Cone\SimplePay\Model\Delivery', + 'invoice' => '\Cone\SimplePay\Model\Invoice', + 'items' => '\Cone\SimplePay\Model\Item[]', + 'methods' => '\Cone\SimplePay\Model\Method[]', + 'timeout' => 'string', + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPIFormats = [ + 'customer' => null, + 'customerEmail' => 'email', + 'currency' => null, + 'maySelectInvoice' => null, + 'maySelectEmail' => null, + 'maySelectDelivery' => null, + 'twoStep' => null, + 'onlyCardReg' => null, + 'url' => null, + 'urls' => null, + 'language' => null, + 'discount' => null, + 'shippingCost' => null, + 'total' => null, + 'delivery' => null, + 'invoice' => null, + 'items' => null, + 'methods' => null, + 'timeout' => null, + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var array + */ + protected static array $openAPINullables = [ + 'customer' => false, + 'customerEmail' => false, + 'currency' => false, + 'maySelectInvoice' => false, + 'maySelectEmail' => false, + 'maySelectDelivery' => false, + 'twoStep' => false, + 'onlyCardReg' => false, + 'url' => false, + 'urls' => false, + 'language' => false, + 'discount' => false, + 'shippingCost' => false, + 'total' => false, + 'delivery' => false, + 'invoice' => false, + 'items' => false, + 'methods' => false, + 'timeout' => false, + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var array + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes(): array + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats(): array + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return array + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param array $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var array + */ + protected static array $attributeMap = [ + 'customer' => 'customer', + 'customerEmail' => 'customerEmail', + 'currency' => 'currency', + 'maySelectInvoice' => 'maySelectInvoice', + 'maySelectEmail' => 'maySelectEmail', + 'maySelectDelivery' => 'maySelectDelivery', + 'twoStep' => 'twoStep', + 'onlyCardReg' => 'onlyCardReg', + 'url' => 'url', + 'urls' => 'urls', + 'language' => 'language', + 'discount' => 'discount', + 'shippingCost' => 'shippingCost', + 'total' => 'total', + 'delivery' => 'delivery', + 'invoice' => 'invoice', + 'items' => 'items', + 'methods' => 'methods', + 'timeout' => 'timeout', + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var array + */ + protected static array $setters = [ + 'customer' => 'setCustomer', + 'customerEmail' => 'setCustomerEmail', + 'currency' => 'setCurrency', + 'maySelectInvoice' => 'setMaySelectInvoice', + 'maySelectEmail' => 'setMaySelectEmail', + 'maySelectDelivery' => 'setMaySelectDelivery', + 'twoStep' => 'setTwoStep', + 'onlyCardReg' => 'setOnlyCardReg', + 'url' => 'setUrl', + 'urls' => 'setUrls', + 'language' => 'setLanguage', + 'discount' => 'setDiscount', + 'shippingCost' => 'setShippingCost', + 'total' => 'setTotal', + 'delivery' => 'setDelivery', + 'invoice' => 'setInvoice', + 'items' => 'setItems', + 'methods' => 'setMethods', + 'timeout' => 'setTimeout', + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var array + */ + protected static array $getters = [ + 'customer' => 'getCustomer', + 'customerEmail' => 'getCustomerEmail', + 'currency' => 'getCurrency', + 'maySelectInvoice' => 'getMaySelectInvoice', + 'maySelectEmail' => 'getMaySelectEmail', + 'maySelectDelivery' => 'getMaySelectDelivery', + 'twoStep' => 'getTwoStep', + 'onlyCardReg' => 'getOnlyCardReg', + 'url' => 'getUrl', + 'urls' => 'getUrls', + 'language' => 'getLanguage', + 'discount' => 'getDiscount', + 'shippingCost' => 'getShippingCost', + 'total' => 'getTotal', + 'delivery' => 'getDelivery', + 'invoice' => 'getInvoice', + 'items' => 'getItems', + 'methods' => 'getMethods', + 'timeout' => 'getTimeout', + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap(): array + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters(): array + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters(): array + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName(): string + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var array + */ + protected array $container = []; + + /** + * Constructor + * + * @param array $data Associated array of property values initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('customer', $data ?? [], null); + $this->setIfExists('customerEmail', $data ?? [], null); + $this->setIfExists('currency', $data ?? [], null); + $this->setIfExists('maySelectInvoice', $data ?? [], false); + $this->setIfExists('maySelectEmail', $data ?? [], false); + $this->setIfExists('maySelectDelivery', $data ?? [], null); + $this->setIfExists('twoStep', $data ?? [], false); + $this->setIfExists('onlyCardReg', $data ?? [], false); + $this->setIfExists('url', $data ?? [], null); + $this->setIfExists('urls', $data ?? [], null); + $this->setIfExists('language', $data ?? [], null); + $this->setIfExists('discount', $data ?? [], 0); + $this->setIfExists('shippingCost', $data ?? [], 0); + $this->setIfExists('total', $data ?? [], 0); + $this->setIfExists('delivery', $data ?? [], null); + $this->setIfExists('invoice', $data ?? [], null); + $this->setIfExists('items', $data ?? [], null); + $this->setIfExists('methods', $data ?? [], null); + $this->setIfExists('timeout', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, mixed $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return string[] invalid properties with reasons + */ + public function listInvalidProperties(): array + { + $invalidProperties = []; + + if ($this->container['currency'] === null) { + $invalidProperties[] = "'currency' can't be null"; + } + if (!is_null($this->container['discount']) && ($this->container['discount'] < 0)) { + $invalidProperties[] = "invalid value for 'discount', must be bigger than or equal to 0."; + } + + if (!is_null($this->container['shippingCost']) && ($this->container['shippingCost'] < 0)) { + $invalidProperties[] = "invalid value for 'shippingCost', must be bigger than or equal to 0."; + } + + if (!is_null($this->container['total']) && ($this->container['total'] <= 0)) { + $invalidProperties[] = "invalid value for 'total', must be bigger than 0."; + } + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid(): bool + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets customer + * + * @return string|null + */ + public function getCustomer(): ?string + { + return $this->container['customer']; + } + + /** + * Sets customer + * + * @param string|null $customer customer + * + * @return $this + */ + public function setCustomer(?string $customer): static + { + if (is_null($customer)) { + throw new InvalidArgumentException('non-nullable customer cannot be null'); + } + $this->container['customer'] = $customer; + + return $this; + } + + /** + * Gets customerEmail + * + * @return string|null + */ + public function getCustomerEmail(): ?string + { + return $this->container['customerEmail']; + } + + /** + * Sets customerEmail + * + * @param string|null $customerEmail customerEmail + * + * @return $this + */ + public function setCustomerEmail(?string $customerEmail): static + { + if (is_null($customerEmail)) { + throw new InvalidArgumentException('non-nullable customerEmail cannot be null'); + } + $this->container['customerEmail'] = $customerEmail; + + return $this; + } + + /** + * Gets currency + * + * @return \Cone\SimplePay\Model\Currency + */ + public function getCurrency(): \Cone\SimplePay\Model\Currency + { + return $this->container['currency']; + } + + /** + * Sets currency + * + * @param \Cone\SimplePay\Model\Currency $currency currency + * + * @return $this + */ + public function setCurrency(\Cone\SimplePay\Model\Currency $currency): static + { + if (is_null($currency)) { + throw new InvalidArgumentException('non-nullable currency cannot be null'); + } + $this->container['currency'] = $currency; + + return $this; + } + + /** + * Gets maySelectInvoice + * + * @return bool|null + */ + public function getMaySelectInvoice(): ?bool + { + return $this->container['maySelectInvoice']; + } + + /** + * Sets maySelectInvoice + * + * @param bool|null $maySelectInvoice maySelectInvoice + * + * @return $this + */ + public function setMaySelectInvoice(?bool $maySelectInvoice): static + { + if (is_null($maySelectInvoice)) { + throw new InvalidArgumentException('non-nullable maySelectInvoice cannot be null'); + } + $this->container['maySelectInvoice'] = $maySelectInvoice; + + return $this; + } + + /** + * Gets maySelectEmail + * + * @return bool|null + */ + public function getMaySelectEmail(): ?bool + { + return $this->container['maySelectEmail']; + } + + /** + * Sets maySelectEmail + * + * @param bool|null $maySelectEmail maySelectEmail + * + * @return $this + */ + public function setMaySelectEmail(?bool $maySelectEmail): static + { + if (is_null($maySelectEmail)) { + throw new InvalidArgumentException('non-nullable maySelectEmail cannot be null'); + } + $this->container['maySelectEmail'] = $maySelectEmail; + + return $this; + } + + /** + * Gets maySelectDelivery + * + * @return string[]|null + */ + public function getMaySelectDelivery(): ?array + { + return $this->container['maySelectDelivery']; + } + + /** + * Sets maySelectDelivery + * + * @param string[]|null $maySelectDelivery maySelectDelivery + * + * @return $this + */ + public function setMaySelectDelivery(?array $maySelectDelivery): static + { + if (is_null($maySelectDelivery)) { + throw new InvalidArgumentException('non-nullable maySelectDelivery cannot be null'); + } + $this->container['maySelectDelivery'] = $maySelectDelivery; + + return $this; + } + + /** + * Gets twoStep + * + * @return bool|null + */ + public function getTwoStep(): ?bool + { + return $this->container['twoStep']; + } + + /** + * Sets twoStep + * + * @param bool|null $twoStep twoStep + * + * @return $this + */ + public function setTwoStep(?bool $twoStep): static + { + if (is_null($twoStep)) { + throw new InvalidArgumentException('non-nullable twoStep cannot be null'); + } + $this->container['twoStep'] = $twoStep; + + return $this; + } + + /** + * Gets onlyCardReg + * + * @return bool|null + */ + public function getOnlyCardReg(): ?bool + { + return $this->container['onlyCardReg']; + } + + /** + * Sets onlyCardReg + * + * @param bool|null $onlyCardReg onlyCardReg + * + * @return $this + */ + public function setOnlyCardReg(?bool $onlyCardReg): static + { + if (is_null($onlyCardReg)) { + throw new InvalidArgumentException('non-nullable onlyCardReg cannot be null'); + } + $this->container['onlyCardReg'] = $onlyCardReg; + + return $this; + } + + /** + * Gets url + * + * @return string|null + */ + public function getUrl(): ?string + { + return $this->container['url']; + } + + /** + * Sets url + * + * @param string|null $url url + * + * @return $this + */ + public function setUrl(?string $url): static + { + if (is_null($url)) { + throw new InvalidArgumentException('non-nullable url cannot be null'); + } + $this->container['url'] = $url; + + return $this; + } + + /** + * Gets urls + * + * @return \Cone\SimplePay\Model\TransactionUrls|null + */ + public function getUrls(): ?\Cone\SimplePay\Model\TransactionUrls + { + return $this->container['urls']; + } + + /** + * Sets urls + * + * @param \Cone\SimplePay\Model\TransactionUrls|null $urls urls + * + * @return $this + */ + public function setUrls(?\Cone\SimplePay\Model\TransactionUrls $urls): static + { + if (is_null($urls)) { + throw new InvalidArgumentException('non-nullable urls cannot be null'); + } + $this->container['urls'] = $urls; + + return $this; + } + + /** + * Gets language + * + * @return \Cone\SimplePay\Model\Language|null + */ + public function getLanguage(): ?\Cone\SimplePay\Model\Language + { + return $this->container['language']; + } + + /** + * Sets language + * + * @param \Cone\SimplePay\Model\Language|null $language language + * + * @return $this + */ + public function setLanguage(?\Cone\SimplePay\Model\Language $language): static + { + if (is_null($language)) { + throw new InvalidArgumentException('non-nullable language cannot be null'); + } + $this->container['language'] = $language; + + return $this; + } + + /** + * Gets discount + * + * @return float|null + */ + public function getDiscount(): ?float + { + return $this->container['discount']; + } + + /** + * Sets discount + * + * @param float|null $discount discount + * + * @return $this + */ + public function setDiscount(?float $discount): static + { + if (is_null($discount)) { + throw new InvalidArgumentException('non-nullable discount cannot be null'); + } + + if (($discount < 0)) { + throw new InvalidArgumentException('invalid value for $discount when calling Transaction., must be bigger than or equal to 0.'); + } + + $this->container['discount'] = $discount; + + return $this; + } + + /** + * Gets shippingCost + * + * @return float|null + */ + public function getShippingCost(): ?float + { + return $this->container['shippingCost']; + } + + /** + * Sets shippingCost + * + * @param float|null $shippingCost shippingCost + * + * @return $this + */ + public function setShippingCost(?float $shippingCost): static + { + if (is_null($shippingCost)) { + throw new InvalidArgumentException('non-nullable shippingCost cannot be null'); + } + + if (($shippingCost < 0)) { + throw new InvalidArgumentException('invalid value for $shippingCost when calling Transaction., must be bigger than or equal to 0.'); + } + + $this->container['shippingCost'] = $shippingCost; + + return $this; + } + + /** + * Gets total + * + * @return float|null + */ + public function getTotal(): ?float + { + return $this->container['total']; + } + + /** + * Sets total + * + * @param float|null $total total + * + * @return $this + */ + public function setTotal(?float $total): static + { + if (is_null($total)) { + throw new InvalidArgumentException('non-nullable total cannot be null'); + } + + if (($total <= 0)) { + throw new InvalidArgumentException('invalid value for $total when calling Transaction., must be bigger than 0.'); + } + + $this->container['total'] = $total; + + return $this; + } + + /** + * Gets delivery + * + * @return \Cone\SimplePay\Model\Delivery|null + */ + public function getDelivery(): ?\Cone\SimplePay\Model\Delivery + { + return $this->container['delivery']; + } + + /** + * Sets delivery + * + * @param \Cone\SimplePay\Model\Delivery|null $delivery delivery + * + * @return $this + */ + public function setDelivery(?\Cone\SimplePay\Model\Delivery $delivery): static + { + if (is_null($delivery)) { + throw new InvalidArgumentException('non-nullable delivery cannot be null'); + } + $this->container['delivery'] = $delivery; + + return $this; + } + + /** + * Gets invoice + * + * @return \Cone\SimplePay\Model\Invoice|null + */ + public function getInvoice(): ?\Cone\SimplePay\Model\Invoice + { + return $this->container['invoice']; + } + + /** + * Sets invoice + * + * @param \Cone\SimplePay\Model\Invoice|null $invoice invoice + * + * @return $this + */ + public function setInvoice(?\Cone\SimplePay\Model\Invoice $invoice): static + { + if (is_null($invoice)) { + throw new InvalidArgumentException('non-nullable invoice cannot be null'); + } + $this->container['invoice'] = $invoice; + + return $this; + } + + /** + * Gets items + * + * @return \Cone\SimplePay\Model\Item[]|null + */ + public function getItems(): ?array + { + return $this->container['items']; + } + + /** + * Sets items + * + * @param \Cone\SimplePay\Model\Item[]|null $items items + * + * @return $this + */ + public function setItems(?array $items): static + { + if (is_null($items)) { + throw new InvalidArgumentException('non-nullable items cannot be null'); + } + $this->container['items'] = $items; + + return $this; + } + + /** + * Gets methods + * + * @return \Cone\SimplePay\Model\Method[]|null + */ + public function getMethods(): ?array + { + return $this->container['methods']; + } + + /** + * Sets methods + * + * @param \Cone\SimplePay\Model\Method[]|null $methods Possible valies: CARD, WIRE or EAM. + * + * @return $this + */ + public function setMethods(?array $methods): static + { + if (is_null($methods)) { + throw new InvalidArgumentException('non-nullable methods cannot be null'); + } + $this->container['methods'] = $methods; + + return $this; + } + + /** + * Gets timeout + * + * @return string|null + */ + public function getTimeout(): ?string + { + return $this->container['timeout']; + } + + /** + * Sets timeout + * + * @param string|null $timeout The ISO 8601 format of the timeout date. + * + * @return $this + */ + public function setTimeout(?string $timeout): static + { + if (is_null($timeout)) { + throw new InvalidArgumentException('non-nullable timeout cannot be null'); + } + $this->container['timeout'] = $timeout; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param int $offset Offset + * + * @return bool + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param int $offset Offset + * + * @return mixed|null + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset): mixed + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet(mixed $offset, mixed $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param int $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[ReturnTypeWillChange] + public function jsonSerialize(): mixed + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString(): string + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue(): string + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} diff --git a/src/Model/TransactionUrls.php b/src/Model/TransactionUrls.php new file mode 100644 index 0000000..6fbc668 --- /dev/null +++ b/src/Model/TransactionUrls.php @@ -0,0 +1,507 @@ + + */ +class TransactionUrls implements ModelInterface, ArrayAccess, JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static string $openAPIModelName = 'Transaction_urls'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPITypes = [ + 'success' => 'string', + 'fail' => 'string', + 'cancel' => 'string', + 'timeout' => 'string', + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var array + */ + protected static array $openAPIFormats = [ + 'success' => null, + 'fail' => null, + 'cancel' => null, + 'timeout' => null, + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var array + */ + protected static array $openAPINullables = [ + 'success' => false, + 'fail' => false, + 'cancel' => false, + 'timeout' => false, + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var array + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes(): array + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats(): array + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return array + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param array $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var array + */ + protected static array $attributeMap = [ + 'success' => 'success', + 'fail' => 'fail', + 'cancel' => 'cancel', + 'timeout' => 'timeout', + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var array + */ + protected static array $setters = [ + 'success' => 'setSuccess', + 'fail' => 'setFail', + 'cancel' => 'setCancel', + 'timeout' => 'setTimeout', + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var array + */ + protected static array $getters = [ + 'success' => 'getSuccess', + 'fail' => 'getFail', + 'cancel' => 'getCancel', + 'timeout' => 'getTimeout', + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap(): array + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters(): array + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters(): array + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName(): string + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var array + */ + protected array $container = []; + + /** + * Constructor + * + * @param array $data Associated array of property values initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('success', $data ?? [], null); + $this->setIfExists('fail', $data ?? [], null); + $this->setIfExists('cancel', $data ?? [], null); + $this->setIfExists('timeout', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, mixed $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return string[] invalid properties with reasons + */ + public function listInvalidProperties(): array + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid(): bool + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets success + * + * @return string|null + */ + public function getSuccess(): ?string + { + return $this->container['success']; + } + + /** + * Sets success + * + * @param string|null $success success + * + * @return $this + */ + public function setSuccess(?string $success): static + { + if (is_null($success)) { + throw new InvalidArgumentException('non-nullable success cannot be null'); + } + $this->container['success'] = $success; + + return $this; + } + + /** + * Gets fail + * + * @return string|null + */ + public function getFail(): ?string + { + return $this->container['fail']; + } + + /** + * Sets fail + * + * @param string|null $fail fail + * + * @return $this + */ + public function setFail(?string $fail): static + { + if (is_null($fail)) { + throw new InvalidArgumentException('non-nullable fail cannot be null'); + } + $this->container['fail'] = $fail; + + return $this; + } + + /** + * Gets cancel + * + * @return string|null + */ + public function getCancel(): ?string + { + return $this->container['cancel']; + } + + /** + * Sets cancel + * + * @param string|null $cancel cancel + * + * @return $this + */ + public function setCancel(?string $cancel): static + { + if (is_null($cancel)) { + throw new InvalidArgumentException('non-nullable cancel cannot be null'); + } + $this->container['cancel'] = $cancel; + + return $this; + } + + /** + * Gets timeout + * + * @return string|null + */ + public function getTimeout(): ?string + { + return $this->container['timeout']; + } + + /** + * Sets timeout + * + * @param string|null $timeout timeout + * + * @return $this + */ + public function setTimeout(?string $timeout): static + { + if (is_null($timeout)) { + throw new InvalidArgumentException('non-nullable timeout cannot be null'); + } + $this->container['timeout'] = $timeout; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param int $offset Offset + * + * @return bool + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param int $offset Offset + * + * @return mixed|null + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset): mixed + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet(mixed $offset, mixed $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param int $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[ReturnTypeWillChange] + public function jsonSerialize(): mixed + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString(): string + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue(): string + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} diff --git a/src/ObjectSerializer.php b/src/ObjectSerializer.php new file mode 100644 index 0000000..f45f253 --- /dev/null +++ b/src/ObjectSerializer.php @@ -0,0 +1,594 @@ +format('Y-m-d') : $data->format(self::$dateTimeFormat); + } + + if ($data instanceof \BackedEnum) { + return $data->value; + } + + if (is_array($data)) { + foreach ($data as $property => $value) { + $data[$property] = self::sanitizeForSerialization($value); + } + return $data; + } + + if (is_object($data)) { + $values = []; + if ($data instanceof ModelInterface) { + $formats = $data::openAPIFormats(); + foreach ($data::openAPITypes() as $property => $openAPIType) { + $getter = $data::getters()[$property]; + $value = $data->$getter(); + if ($value !== null && !in_array($openAPIType, ['\DateTime', '\SplFileObject', 'array', 'bool', 'boolean', 'byte', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) { + if (is_subclass_of($openAPIType, '\BackedEnum')) { + if (is_scalar($value)) { + $value = $openAPIType::tryFrom($value); + if ($value === null) { + $imploded = implode("', '", array_map(fn ($case) => $case->value, $openAPIType::cases())); + throw new \InvalidArgumentException( + sprintf( + "Invalid value for enum '%s', must be one of: '%s'", + $openAPIType::class, + $imploded + ) + ); + } + } + } + } + if (($data::isNullable($property) && $data->isNullableSetToNull($property)) || $value !== null) { + $values[$data::attributeMap()[$property]] = self::sanitizeForSerialization($value, $openAPIType, $formats[$property]); + } + } + } else { + foreach ($data as $property => $value) { + $values[$property] = self::sanitizeForSerialization($value); + } + } + return (object)$values; + } else { + return (string)$data; + } + } + + /** + * Sanitize filename by removing path. + * e.g. ../../sun.gif becomes sun.gif + * + * @param string $filename filename to be sanitized + * + * @return string the sanitized filename + */ + public static function sanitizeFilename(string $filename): string + { + if (preg_match("/.*[\/\\\\](.*)$/", $filename, $match)) { + return $match[1]; + } else { + return $filename; + } + } + + /** + * Shorter timestamp microseconds to 6 digits length. + * + * @param string $timestamp Original timestamp + * + * @return string the shorten timestamp + */ + public static function sanitizeTimestamp(string $timestamp): string + { + return preg_replace('/(:\d{2}.\d{6})\d*/', '$1', $timestamp); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the path, by url-encoding. + * + * @param string $value a string which will be part of the path + * + * @return string the serialized object + */ + public static function toPathValue(string $value): string + { + return rawurlencode(self::toString($value)); + } + + /** + * Checks if a value is empty, based on its OpenAPI type. + * + * @param mixed $value + * @param string $openApiType + * + * @return bool true if $value is empty + */ + private static function isEmptyValue(mixed $value, string $openApiType): bool + { + // If empty() returns false, it is not empty regardless of its type. + if (!empty($value)) { + return false; + } + + // Null is always empty, as we cannot send a real "null" value in a query parameter. + if ($value === null) { + return true; + } + + return match ($openApiType) { + // For numeric values, false and '' are considered empty. + // This comparison is safe for floating point values, since the previous call to empty() will + // filter out values that don't match 0. + 'int','integer' => $value !== 0, + 'number' | 'float' => $value !== 0 && $value !== 0.0, + + // For boolean values, '' is considered empty + 'bool','boolean' => !in_array($value, [false, 0], true), + + // For string values, '' is considered empty. + 'string' => $value === '', + + // For all the other types, any value at this point can be considered empty. + default => true + }; + } + + /** + * Take query parameter properties and turn it into an array suitable for + * native http_build_query or GuzzleHttp\Psr7\Query::build. + * + * @param mixed $value Parameter value + * @param string $paramName Parameter name + * @param string $openApiType OpenAPIType e.g. array or object + * @param string $style Parameter serialization style + * @param bool $explode Parameter explode option + * @param bool $required Whether query param is required or not + * + * @return array + */ + public static function toQueryValue( + mixed $value, + string $paramName, + string $openApiType = 'string', + string $style = 'form', + bool $explode = true, + bool $required = true + ): array { + + // Check if we should omit this parameter from the query. This should only happen when: + // - Parameter is NOT required; AND + // - its value is set to a value that is equivalent to "empty", depending on its OpenAPI type. For + // example, 0 as "int" or "boolean" is NOT an empty value. + if (self::isEmptyValue($value, $openApiType)) { + if ($required) { + return ["{$paramName}" => '']; + } else { + return []; + } + } + + // Handle DateTime objects in query + if ($openApiType === "\DateTime" && $value instanceof DateTime) { + return ["{$paramName}" => $value->format(self::$dateTimeFormat)]; + } + + $query = []; + $value = (in_array($openApiType, ['object', 'array'], true)) ? (array)$value : $value; + + // since \GuzzleHttp\Psr7\Query::build fails with nested arrays + // need to flatten array first + $flattenArray = function ($arr, $name, &$result = []) use (&$flattenArray, $style, $explode) { + if (!is_array($arr)) { + return $arr; + } + + foreach ($arr as $k => $v) { + $prop = ($style === 'deepObject') ? "{$name}[{$k}]" : $k; + + if (is_array($v)) { + $flattenArray($v, $prop, $result); + } else { + if ($style !== 'deepObject' && !$explode) { + // push key itself + $result[] = $prop; + } + $result[$prop] = $v; + } + } + return $result; + }; + + $value = $flattenArray($value, $paramName); + + // https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values + if ($openApiType === 'array' && $style === 'deepObject' && $explode) { + return $value; + } + + if ($openApiType === 'object' && ($style === 'deepObject' || $explode)) { + return $value; + } + + if ('boolean' === $openApiType && is_bool($value)) { + $value = self::convertBoolToQueryStringFormat($value); + } + + // handle style in serializeCollection + $query[$paramName] = ($explode) ? $value : self::serializeCollection((array)$value, $style); + + return $query; + } + + /** + * Convert boolean value to format for query string. + * + * @param bool $value Boolean value + * + * @return int|string Boolean value in format + */ + public static function convertBoolToQueryStringFormat(bool $value): int|string + { + if (Configuration::BOOLEAN_FORMAT_STRING === Configuration::getDefaultConfiguration()->getBooleanFormatForQueryString()) { + return $value ? 'true' : 'false'; + } + + return (int) $value; + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the header. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * + * @param string $value a string which will be part of the header + * + * @return string the header string + */ + public static function toHeaderValue(string $value): string + { + $callable = [$value, 'toHeaderValue']; + if (is_callable($callable)) { + return $callable(); + } + + return self::toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the parameter. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * If it's a boolean, convert it to "true" or "false". + * + * @param string|bool|DateTime $value the value of the parameter + * + * @return string the header string + */ + public static function toString(string|bool|DateTime $value): string + { + if ($value instanceof DateTime) { // datetime in ISO8601 format + return $value->format(self::$dateTimeFormat); + } elseif (is_bool($value)) { + return $value ? 'true' : 'false'; + } else { + return (string) $value; + } + } + + /** + * Serialize an array to a string. + * + * @param array $collection collection to serialize to a string + * @param string $style the format use for serialization (csv, + * ssv, tsv, pipes, multi) + * @param bool $allowCollectionFormatMulti allow collection format to be a multidimensional array + * + * @return string + */ + public static function serializeCollection(array $collection, string $style, bool $allowCollectionFormatMulti = false): string + { + if ($allowCollectionFormatMulti && ('multi' === $style)) { + // http_build_query() almost does the job for us. We just + // need to fix the result of multidimensional arrays. + return preg_replace('/%5B[0-9]+%5D=/', '=', http_build_query($collection, '', '&')); + } + return match ($style) { + 'pipeDelimited', 'pipes' => implode('|', $collection), + 'tsv' => implode("\t", $collection), + 'spaceDelimited', 'ssv' => implode(' ', $collection), + default => implode(',', $collection), + }; + } + + /** + * Deserialize a JSON string into an object + * + * @param mixed $data object or primitive to be deserialized + * @param string $class class name is passed as a string + * @param string[]|null $httpHeaders HTTP headers + * + * @return mixed a single or an array of $class instances + */ + public static function deserialize(mixed $data, string $class, ?array $httpHeaders = null): mixed + { + if (null === $data) { + return null; + } + + if (strcasecmp(substr($class, -2), '[]') === 0) { + $data = is_string($data) ? json_decode($data) : $data; + + if (!is_array($data)) { + throw new \InvalidArgumentException("Invalid array '$class'"); + } + + $subClass = substr($class, 0, -2); + $values = []; + foreach ($data as $key => $value) { + $values[] = self::deserialize($value, $subClass, null); + } + return $values; + } + + if (preg_match('/^(array<|map\[)/', $class)) { // for associative array e.g. array + $data = is_string($data) ? json_decode($data) : $data; + settype($data, 'array'); + $inner = substr($class, 4, -1); + $deserialized = []; + if (strrpos($inner, ",") !== false) { + $subClass_array = explode(',', $inner, 2); + $subClass = $subClass_array[1]; + foreach ($data as $key => $value) { + $deserialized[$key] = self::deserialize($value, $subClass, null); + } + } + return $deserialized; + } + + if ($class === 'mixed') { + settype($data, gettype($data)); + return $data; + } + + if ($class === '\DateTime') { + // Some APIs return an invalid, empty string as a + // date-time property. DateTime::__construct() will return + // the current time for empty input which is probably not + // what is meant. The invalid empty string is probably to + // be interpreted as a missing field/value. Let's handle + // this graceful. + if (!empty($data)) { + try { + return new DateTime($data); + } catch (\Exception $exception) { + // Some APIs return a date-time with too high nanosecond + // precision for php's DateTime to handle. + // With provided regexp 6 digits of microseconds saved + return new DateTime(self::sanitizeTimestamp($data)); + } + } else { + return null; + } + } + + if ($class === '\Psr\Http\Message\StreamInterface') { + return Utils::streamFor($data); + } + + if ($class === '\SplFileObject') { + $data = Utils::streamFor($data); + + /** @var \Psr\Http\Message\StreamInterface $data */ + + // determine file name + if ( + is_array($httpHeaders) + && array_key_exists('Content-Disposition', $httpHeaders) + && preg_match('/inline; filename=[\'"]?([^\'"\s]+)[\'"]?$/i', $httpHeaders['Content-Disposition'], $match) + ) { + $filename = Configuration::getDefaultConfiguration()->getTempFolderPath() . DIRECTORY_SEPARATOR . self::sanitizeFilename($match[1]); + } else { + $filename = tempnam(Configuration::getDefaultConfiguration()->getTempFolderPath(), ''); + } + + $file = fopen($filename, 'w'); + while ($chunk = $data->read(200)) { + fwrite($file, $chunk); + } + fclose($file); + + return new \SplFileObject($filename, 'r'); + } + + /** @psalm-suppress ParadoxicalCondition */ + // handle primitive types + if (in_array($class, ['\DateTime', '\SplFileObject'], true)) { + return $data; + } elseif (in_array($class, ['array', 'bool', 'boolean', 'float', 'double', 'int', 'integer', 'object', 'string', 'null'], true)) { + // type ref: https://www.php.net/manual/en/function.settype.php + // byte, mixed, void in the old php client were removed + settype($data, $class); + return $data; + } + + + if (is_subclass_of($class, '\BackedEnum')) { + $data = $class::tryFrom($data); + if ($data === null) { + $imploded = implode("', '", array_map(fn ($case) => $case->value, $class::cases())); + throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'"); + } + return $data; + } else { + $data = is_string($data) ? json_decode($data) : $data; + + if (is_array($data)) { + $data = (object)$data; + } + + // If a discriminator is defined and points to a valid subclass, use it. + $discriminator = $class::DISCRIMINATOR; + if (!empty($discriminator) && isset($data->{$discriminator}) && is_string($data->{$discriminator})) { + $subclass = '\Cone\SimplePay\Model\\' . $data->{$discriminator}; + if (is_subclass_of($subclass, $class)) { + $class = $subclass; + } + } + + /** @var ModelInterface $instance */ + $instance = new $class(); + foreach ($instance::openAPITypes() as $property => $type) { + $propertySetter = $instance::setters()[$property]; + + if (!isset($propertySetter)) { + continue; + } + + if (!isset($data->{$instance::attributeMap()[$property]})) { + if ($instance::isNullable($property)) { + $instance->$propertySetter(null); + } + + continue; + } + + if (isset($data->{$instance::attributeMap()[$property]})) { + $propertyValue = $data->{$instance::attributeMap()[$property]}; + $instance->$propertySetter(self::deserialize($propertyValue, $type, null)); + } + } + return $instance; + } + } + + /** + * Build a query string from an array of key value pairs. + * + * This function can use the return value of `parse()` to build a query + * string. This function does not modify the provided keys when an array is + * encountered (like `http_build_query()` would). + * + * @param array $params Query string parameters. + * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 + * to encode using RFC3986, or PHP_QUERY_RFC1738 + * to encode using RFC1738. + */ + public static function buildQuery(array $params, $encoding = PHP_QUERY_RFC3986): string + { + if (!$params) { + return ''; + } + + if ($encoding === false) { + $encoder = function (string $str): string { + return $str; + }; + } elseif ($encoding === PHP_QUERY_RFC3986) { + $encoder = 'rawurlencode'; + } elseif ($encoding === PHP_QUERY_RFC1738) { + $encoder = 'urlencode'; + } else { + throw new \InvalidArgumentException('Invalid type'); + } + + $castBool = Configuration::BOOLEAN_FORMAT_INT === Configuration::getDefaultConfiguration()->getBooleanFormatForQueryString() + ? function ($v) { return (int) $v; } + : function ($v) { return $v ? 'true' : 'false'; }; + + $qs = ''; + foreach ($params as $k => $v) { + $k = $encoder((string) $k); + if (!is_array($v)) { + $qs .= $k; + $v = is_bool($v) ? $castBool($v) : $v; + if ($v !== null) { + $qs .= '='.$encoder((string) $v); + } + $qs .= '&'; + } else { + foreach ($v as $vv) { + $qs .= $k; + $vv = is_bool($vv) ? $castBool($vv) : $vv; + if ($vv !== null) { + $qs .= '='.$encoder((string) $vv); + } + $qs .= '&'; + } + } + } + + return $qs ? (string) substr($qs, 0, -1) : ''; + } +} diff --git a/tests/Api/TransactionApiTest.php b/tests/Api/TransactionApiTest.php new file mode 100644 index 0000000..60dc101 --- /dev/null +++ b/tests/Api/TransactionApiTest.php @@ -0,0 +1,82 @@ +