diff --git a/composer.json b/composer.json
index 6517db4..4d8ef98 100644
--- a/composer.json
+++ b/composer.json
@@ -38,4 +38,4 @@
"autoload-dev": {
"psr-4": { "Squidex\\Client\\Test\\" : "tests/" }
}
-}
\ No newline at end of file
+}
diff --git a/lib/Configuration.php b/lib/Configuration.php
index 7429e90..3903a58 100644
--- a/lib/Configuration.php
+++ b/lib/Configuration.php
@@ -42,82 +42,96 @@ class Configuration
{
public const BOOLEAN_FORMAT_INT = 'int';
public const BOOLEAN_FORMAT_STRING = 'string';
+
/**
* @var Configuration
*/
private static $defaultConfiguration;
+
/**
* Client ID for OAuth/Bearer authentication
*
* @var string
*/
protected $clientId = '';
+
/**
* Client Secret for OAuth/Bearer authentication
*
* @var string
*/
protected $clientSecret = '';
+
/**
* App Name
*
* @var string
*/
protected $appName = '';
+
/**
* Boolean format for query string
*
* @var string
*/
protected $booleanFormatForQueryString = self::BOOLEAN_FORMAT_STRING;
+
/**
* The host
*
* @var string
*/
protected $host = 'https://cloud.squidex.io';
+
/**
* The timeout in seconds
*
* @var float
*/
protected $timeout = 30.0;
+
/**
* The token store.
*
* @var SquidexTokenStore
*/
protected $tokenStore = null;
+
/**
* User agent of the HTTP request, set to "OpenAPI-Generator/{version}/PHP" by default
*
* @var string
*/
protected $userAgent = 'OpenAPI-Generator/1.0.0/PHP';
+
/**
* Ignore the validation of certificates.
*
* @var boolean
*/
protected $ignoreCertificates = false;
+
/**
* Debug switch (default set to false)
*
* @var bool
*/
protected $debug = false;
+
/**
* Debug file location (log to STDOUT by default)
*
* @var string
*/
protected $debugFile = 'php://output';
+
/**
* Debug file location (log to STDOUT by default)
*
* @var string
*/
protected $tempFolderPath;
+
/**
* Constructor
*/
@@ -545,8 +559,10 @@ public static function getHostString(array $hostsSettings, $hostIndex, array $va
$url = str_replace("{".$name."}", $variable["default_value"], $url);
}
}
+
return $url;
}
+
/**
* Returns URL based on the index and variables
*
@@ -558,4 +574,4 @@ public function getHostFromSettings($index, $variables = null)
{
return self::getHostString($this->getHostSettings(), $index, $variables);
}
-}
\ No newline at end of file
+}
diff --git a/lib/ObjectSerializer.php b/lib/ObjectSerializer.php
index 551c16d..7cf7c89 100644
--- a/lib/ObjectSerializer.php
+++ b/lib/ObjectSerializer.php
@@ -265,11 +265,6 @@ public static function toQueryValue(
$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;
}
@@ -343,7 +338,7 @@ public static function toFormValue($value)
* If it's a datetime object, format it in ISO8601
* If it's a boolean, convert it to "true" or "false".
*
- * @param float|int|bool|\DateTime $value the value of the parameter
+ * @param string|bool|\DateTime $value the value of the parameter
*
* @return string the header string
*/
@@ -401,6 +396,7 @@ public static function serializeCollection(array $collection, $style, $allowColl
* @param mixed $data object or primitive to be deserialized
* @param string $class class name is passed as a string
* @param string[] $httpHeaders HTTP headers
+ * @param string $discriminator discriminator if polymorphism is used
*
* @return object|array|null a single or an array of $class instances
*/
@@ -477,7 +473,7 @@ public static function deserialize($data, $class, $httpHeaders = null)
// determine file name
if (
is_array($httpHeaders)
- && array_key_exists('Content-Disposition', $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]);
@@ -516,10 +512,17 @@ public static function deserialize($data, $class, $httpHeaders = null)
// 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 = '\Squidex\Client\Model\\' . $data->{$discriminator};
- if (is_subclass_of($subclass, $class)) {
- $class = $subclass;
+ if (!empty($discriminator)) {
+ $discriminatorProperty = $class::attributeMap()[$discriminator];
+
+ if (isset($data->{$discriminatorProperty}) && is_string($data->{$discriminatorProperty})) {
+ $discriminatorValue = $data->{$discriminatorProperty};
+ $discriminatorType = $class::openAPIMAppings()[$discriminatorValue];
+
+ $subclass = '\Squidex\Client\Model\\' . $discriminatorType;
+ if (is_subclass_of($subclass, $class)) {
+ $class = $subclass;
+ }
}
}
@@ -550,64 +553,22 @@ public static function deserialize($data, $class, $httpHeaders = null)
}
/**
- * 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).
- *
- * The function is copied from https://github.com/guzzle/psr7/blob/a243f80a1ca7fe8ceed4deee17f12c1930efe662/src/Query.php#L59-L112
- * with a modification which is described in https://github.com/guzzle/psr7/pull/603
- *
- * @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) : '';
+ * Native `http_build_query` wrapper.
+ * @see https://www.php.net/manual/en/function.http-build-query
+ *
+ * @param array|object $data May be an array or object containing properties.
+ * @param string $numeric_prefix If numeric indices are used in the base array and this parameter is provided, it will be prepended to the numeric index for elements in the base array only.
+ * @param string|null $arg_separator arg_separator.output is used to separate arguments but may be overridden by specifying this parameter.
+ * @param int $encoding_type Encoding type. By default, PHP_QUERY_RFC1738.
+ *
+ * @return string
+ */
+ public static function buildQuery(
+ $data,
+ string $numeric_prefix = '',
+ ?string $arg_separator = null,
+ int $encoding_type = \PHP_QUERY_RFC3986
+ ): string {
+ return \GuzzleHttp\Psr7\Query::build($data, $encoding_type);
}
}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 381d8e4..00d883b 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -9,4 +9,4 @@
-
\ No newline at end of file
+
diff --git a/templates/Configuration.mustache b/templates/Configuration.mustache
index 81a5a00..ccaf2c6 100644
--- a/templates/Configuration.mustache
+++ b/templates/Configuration.mustache
@@ -33,82 +33,96 @@ class Configuration
{
public const BOOLEAN_FORMAT_INT = 'int';
public const BOOLEAN_FORMAT_STRING = 'string';
+
/**
* @var Configuration
*/
private static $defaultConfiguration;
+
/**
* Client ID for OAuth/Bearer authentication
*
* @var string
*/
protected $clientId = '';
+
/**
* Client Secret for OAuth/Bearer authentication
*
* @var string
*/
protected $clientSecret = '';
+
/**
* App Name
*
* @var string
*/
protected $appName = '';
+
/**
* Boolean format for query string
*
* @var string
*/
protected $booleanFormatForQueryString = self::BOOLEAN_FORMAT_STRING;
+
/**
* The host
*
* @var string
*/
protected $host = '{{basePath}}';
+
/**
* The timeout in seconds
*
* @var float
*/
protected $timeout = 30.0;
+
/**
* The token store.
*
* @var SquidexTokenStore
*/
protected $tokenStore = null;
+
/**
* User agent of the HTTP request, set to "OpenAPI-Generator/{version}/PHP" by default
*
* @var string
*/
protected $userAgent = '{{{httpUserAgent}}}{{^httpUserAgent}}OpenAPI-Generator/{{{artifactVersion}}}{{^artifactVersion}}1.0.0{{/artifactVersion}}/PHP{{/httpUserAgent}}';
+
/**
* Ignore the validation of certificates.
*
* @var boolean
*/
protected $ignoreCertificates = false;
+
/**
* Debug switch (default set to false)
*
* @var bool
*/
protected $debug = false;
+
/**
* Debug file location (log to STDOUT by default)
*
* @var string
*/
protected $debugFile = 'php://output';
+
/**
* Debug file location (log to STDOUT by default)
*
* @var string
*/
protected $tempFolderPath;
+
/**
* Constructor
*/
@@ -562,8 +576,10 @@ class Configuration
$url = str_replace("{".$name."}", $variable["default_value"], $url);
}
}
+
return $url;
}
+
/**
* Returns URL based on the index and variables
*
@@ -575,4 +591,4 @@ class Configuration
{
return self::getHostString($this->getHostSettings(), $index, $variables);
}
-}
\ No newline at end of file
+}
diff --git a/templates/ObjectSerializer.mustache b/templates/ObjectSerializer.mustache
new file mode 100644
index 0000000..186a13a
--- /dev/null
+++ b/templates/ObjectSerializer.mustache
@@ -0,0 +1,565 @@
+partial_header}}
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+namespace {{invokerPackage}};
+
+use GuzzleHttp\Psr7\Utils;
+use {{modelPackage}}\ModelInterface;
+
+/**
+ * ObjectSerializer Class Doc Comment
+ *
+ * @category Class
+ * @package {{invokerPackage}}
+ * @author OpenAPI Generator team
+ * @link https://openapi-generator.tech
+ */
+class ObjectSerializer
+{
+ /** @var string */
+ private static $dateTimeFormat = \DateTime::ATOM;
+
+ /**
+ * Change the date format
+ *
+ * @param string $format the new date format to use
+ */
+ public static function setDateTimeFormat($format)
+ {
+ self::$dateTimeFormat = $format;
+ }
+
+ /**
+ * Serialize data
+ *
+ * @param mixed $data the data to serialize
+ * @param string $type the OpenAPIToolsType of the data
+ * @param string $format the format of the OpenAPITools type of the data
+ *
+ * @return scalar|object|array|null serialized form of $data
+ */
+ public static function sanitizeForSerialization($data, $type = null, $format = null)
+ {
+ if (is_scalar($data) || null === $data) {
+ return $data;
+ }
+
+ if ($data instanceof \DateTime) {
+ return ($format === 'date') ? $data->format('Y-m-d') : $data->format(self::$dateTimeFormat);
+ }
+
+ 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, [{{&primitives}}], true)) {
+ $callable = [$openAPIType, 'getAllowableEnumValues'];
+ if (is_callable($callable)) {
+ /** array $callable */
+ $allowedEnumTypes = $callable();
+ if (!in_array($value, $allowedEnumTypes, true)) {
+ $imploded = implode("', '", $allowedEnumTypes);
+ throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$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($filename)
+ {
+ 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($timestamp)
+ {
+ if (!is_string($timestamp)) return $timestamp;
+
+ 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($value)
+ {
+ 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($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;
+ }
+
+ switch ($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.
+ case 'int':
+ case 'integer':
+ return $value !== 0;
+
+ case 'number':
+ case 'float':
+ return $value !== 0 && $value !== 0.0;
+
+ # For boolean values, '' is considered empty
+ case 'bool':
+ case 'boolean':
+ return !in_array($value, [false, 0], true);
+
+ # For all the other types, any value at this point can be considered empty.
+ default:
+ return 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 eg. 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(
+ $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') ? $prop = "{$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);
+
+ 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)
+ {
+ 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($value)
+ {
+ $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 http body (form parameter). If it's a string, pass through unchanged
+ * If it's a datetime object, format it in ISO8601
+ *
+ * @param string|\SplFileObject $value the value of the form parameter
+ *
+ * @return string the form string
+ */
+ public static function toFormValue($value)
+ {
+ if ($value instanceof \SplFileObject) {
+ return $value->getRealPath();
+ } else {
+ 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($value)
+ {
+ 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, $style, $allowCollectionFormatMulti = false)
+ {
+ 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, '', '&'));
+ }
+ switch ($style) {
+ case 'pipeDelimited':
+ case 'pipes':
+ return implode('|', $collection);
+
+ case 'tsv':
+ return implode("\t", $collection);
+
+ case 'spaceDelimited':
+ case 'ssv':
+ return implode(' ', $collection);
+
+ case 'simple':
+ case 'csv':
+ // Deliberate fall through. CSV is default format.
+ default:
+ return 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[] $httpHeaders HTTP headers
+ * @param string $discriminator discriminator if polymorphism is used
+ *
+ * @return object|array|null a single or an array of $class instances
+ */
+ public static function deserialize($data, $class, $httpHeaders = null)
+ {
+ 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 === 'object') {
+ settype($data, 'array');
+ return $data;
+ } elseif ($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 === '\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 */
+ if (in_array($class, [{{&primitives}}], true)) {
+ settype($data, $class);
+ return $data;
+ }
+
+
+ if (method_exists($class, 'getAllowableEnumValues')) {
+ if (!in_array($data, $class::getAllowableEnumValues(), true)) {
+ $imploded = implode("', '", $class::getAllowableEnumValues());
+ 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)) {
+ $discriminatorProperty = $class::attributeMap()[$discriminator];
+
+ if (isset($data->{$discriminatorProperty}) && is_string($data->{$discriminatorProperty})) {
+ $discriminatorValue = $data->{$discriminatorProperty};
+ $discriminatorType = $class::openAPIMAppings()[$discriminatorValue];
+
+ $subclass = '\{{invokerPackage}}\Model\\' . $discriminatorType;
+ 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;
+ }
+ }
+
+ /**
+ * Native `http_build_query` wrapper.
+ * @see https://www.php.net/manual/en/function.http-build-query
+ *
+ * @param array|object $data May be an array or object containing properties.
+ * @param string $numeric_prefix If numeric indices are used in the base array and this parameter is provided, it will be prepended to the numeric index for elements in the base array only.
+ * @param string|null $arg_separator arg_separator.output is used to separate arguments but may be overridden by specifying this parameter.
+ * @param int $encoding_type Encoding type. By default, PHP_QUERY_RFC1738.
+ *
+ * @return string
+ */
+ public static function buildQuery(
+ $data,
+ string $numeric_prefix = '',
+ ?string $arg_separator = null,
+ int $encoding_type = \PHP_QUERY_RFC3986
+ ): string {
+ return \GuzzleHttp\Psr7\Query::build($data, $encoding_type);
+ }
+}
diff --git a/templates/README.mustache b/templates/README.mustache
new file mode 100644
index 0000000..20b4c3e
--- /dev/null
+++ b/templates/README.mustache
@@ -0,0 +1,150 @@
+# {{packageName}}
+
+{{#appDescriptionWithNewLines}}
+{{{.}}}
+{{/appDescriptionWithNewLines}}
+
+{{#infoUrl}}
+For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}).
+{{/infoUrl}}
+
+## Installation & Usage
+
+### Requirements
+
+PHP 7.4 and later.
+Should also work with PHP 8.0.
+
+### Composer
+
+To install the bindings via [Composer](https://getcomposer.org/), add the following to `composer.json`:
+
+```json
+{
+ "repositories": [
+ {
+ "type": "vcs",
+ "url": "https://{{gitHost}}/{{gitUserId}}/{{gitRepoId}}.git"
+ }
+ ],
+ "require": {
+ "{{gitUserId}}/{{gitRepoId}}": "*@dev"
+ }
+}
+```
+
+Then run `composer install`
+
+### Manual Installation
+
+Download the files and include `autoload.php`:
+
+```php
+ php_doc_auth_partial}}
+$apiInstance = new {{invokerPackage}}\Api\{{classname}}(
+ // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`.
+ // This is optional, `GuzzleHttp\Client` will be used as default.
+ new GuzzleHttp\Client(){{#hasAuthMethods}},
+ $config{{/hasAuthMethods}}
+);
+{{#allParams}}${{paramName}} = {{{example}}}; // {{{dataType}}}{{#description}} | {{{.}}}{{/description}}
+{{/allParams}}
+
+try {
+ {{#returnType}}$result = {{/returnType}}$apiInstance->{{{operationId}}}({{#allParams}}${{paramName}}{{^-last}}, {{/-last}}{{/allParams}});{{#returnType}}
+ print_r($result);{{/returnType}}
+} catch (Exception $e) {
+ echo 'Exception when calling {{classname}}->{{operationId}}: ', $e->getMessage(), PHP_EOL;
+}
+{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
+```
+
+## API Endpoints
+
+All URIs are relative to *{{basePath}}*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}/{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{summary}}
+{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
+## Models
+
+{{#models}}{{#model}}- [{{{classname}}}]({{modelDocPath}}/{{{classname}}}.md){{/model}}
+{{/models}}
+
+## Authorization
+{{^authMethods}}Endpoints do not require authorization.{{/authMethods}}
+{{#hasAuthMethods}}Authentication schemes defined for the API:{{/hasAuthMethods}}
+{{#authMethods}}
+### {{{name}}}
+{{#isApiKey}}
+
+- **Type**: API key
+- **API key parameter name**: {{{keyParamName}}}
+- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
+
+{{/isApiKey}}
+{{#isBasic}}
+{{#isBasicBasic}}
+
+- **Type**: HTTP basic authentication
+{{/isBasicBasic}}
+{{#isBasicBearer}}
+
+- **Type**: Bearer authentication{{#bearerFormat}} ({{{.}}}){{/bearerFormat}}
+{{/isBasicBearer}}
+{{#isHttpSignature}}
+
+- **Type**: HTTP signature authentication
+{{/isHttpSignature}}
+{{/isBasic}}
+{{#isOAuth}}
+
+- **Type**: `OAuth`
+- **Flow**: `{{{flow}}}`
+- **Authorization URL**: `{{{authorizationUrl}}}`
+- **Scopes**: {{^scopes}}N/A{{/scopes}}
+{{#scopes}}
+ - **{{{scope}}}**: {{{description}}}
+{{/scopes}}
+{{/isOAuth}}
+
+{{/authMethods}}
+## Tests
+
+To run the tests, use:
+
+```bash
+composer install
+vendor/bin/phpunit
+```
+
+## Author
+
+{{#apiInfo}}{{#apis}}{{#-last}}{{infoEmail}}
+{{/-last}}{{/apis}}{{/apiInfo}}
+## About this package
+
+This PHP package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
+
+- API version: `{{appVersion}}`
+{{#artifactVersion}}
+ - Package version: `{{.}}`
+{{/artifactVersion}}
+{{^hideGenerationTimestamp}}
+ - Build date: `{{generatedDate}}`
+{{/hideGenerationTimestamp}}
+- Build package: `{{generatorClass}}`
diff --git a/templates/composer.mustache b/templates/composer.mustache
index cb60bbd..0aa4bb6 100644
--- a/templates/composer.mustache
+++ b/templates/composer.mustache
@@ -43,4 +43,4 @@
"autoload-dev": {
"psr-4": { "{{escapedInvokerPackage}}\\Test\\" : "tests/" }
}
-}
\ No newline at end of file
+}
diff --git a/templates/phpunit.xml.mustache b/templates/phpunit.xml.mustache
index 381d8e4..00d883b 100644
--- a/templates/phpunit.xml.mustache
+++ b/templates/phpunit.xml.mustache
@@ -9,4 +9,4 @@
-
\ No newline at end of file
+
diff --git a/tests/ContentsTest.php b/tests/ContentsTest.php
index e310a4a..3fdc193 100644
--- a/tests/ContentsTest.php
+++ b/tests/ContentsTest.php
@@ -69,7 +69,7 @@ public function testCreateAndFetchUnpublishedContent()
]
]);
- $content = $this->client->contents()->getContent(static::$schema->getName(), $createdContent->getId(), -2, null, null, true);
+ $content = $this->client->contents()->getContent(static::$schema->getName(), $createdContent->getId(), -2, null, null, null, true);
$this->assertEquals($value, $content->getData()->field1->iv);
$this->assertTrue($content->getLastModified() != null);
$this->assertTrue($content->getLastModifiedBy() != null);