Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

namespace {{invokerPackage}};

use ArrayAccess;
use DateTimeInterface;
use DateTime;
use GuzzleHttp\Psr7\Utils;
Expand Down Expand Up @@ -316,20 +317,33 @@ class ObjectSerializer
}

/**
* Take value and turn it into a string suitable for inclusion in
* Take value and turn it into an array 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
* @param string|bool|array|DateTime|ArrayAccess|\SplFileObject $value the value of the form parameter
*
* @return string the form string
* @return array [key => value] of formdata
*/
public static function toFormValue(string|\SplFileObject $value): string
{
public static function toFormValue(
string $key,
string|bool|array|DateTime|ArrayAccess|\SplFileObject $value,
): array {
if ($value instanceof \SplFileObject) {
return $value->getRealPath();
return [$key => $value->getRealPath()];
} elseif (is_array($value) || $value instanceof ArrayAccess) {
$flattened = [];
$result = [];

self::flattenArray(json_decode(json_encode($value), true), $flattened);

foreach ($flattened as $k => $v) {
$result["{$key}{$k}"] = self::toString($v);
}

return $result;
} else {
return self::toString($value);
return [$key => self::toString($value)];
}
}

Expand Down Expand Up @@ -598,4 +612,58 @@ class ObjectSerializer

return $qs ? (string) substr($qs, 0, -1) : '';
}

/**
* Flattens an array of Model object and generates an array compatible
* with formdata - a single-level array where the keys use bracket
* notation to signify nested data.
*
* credit: https://github.com/FranBar1966/FlatPHP
*/
private static function flattenArray(
ArrayAccess|array $source,
array &$destination,
string $start = '',
) {
$opt = [
'prefix' => '[',
'suffix' => ']',
'suffix-end' => true,
'prefix-list' => '[',
'suffix-list' => ']',
'suffix-list-end' => true,
];

if (!is_array($source)) {
$source = (array) $source;
}

if (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;

foreach ($source as $key => $val) {
$currentName .= $currentPrefix.$key;

if (is_array($val) && !empty($val)) {
$currentName .= "{$currentSuffix}";
self::flattenArray($val, $destination, $currentName);
} else {
if ($currentSuffixEnd) {
$currentName .= $currentSuffix;
}
$destination[$currentName] = self::toString($val);
}

$currentName = $start;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -759,13 +759,13 @@ use {{invokerPackage}}\ObjectSerializer;
$formParams['{{baseName}}'][] = $paramFile instanceof \Psr\Http\Message\StreamInterface
? $paramFile
: \GuzzleHttp\Psr7\Utils::tryFopen(
ObjectSerializer::toFormValue($paramFile),
ObjectSerializer::toFormValue('{{baseName}}', $paramFile)['{{baseName}}'],
'rb'
);
}
{{/isFile}}
{{^isFile}}
$formParams['{{baseName}}'] = ObjectSerializer::toFormValue(${{paramName}});
$formParams = array_merge($formParams, ObjectSerializer::toFormValue('{{baseName}}', ${{paramName}}));
{{/isFile}}
}
{{/formParams}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace {{invokerPackage}};

use ArrayAccess;
use GuzzleHttp\Psr7\Utils;
use {{modelPackage}}\ModelInterface;

Expand Down Expand Up @@ -315,20 +316,31 @@ class ObjectSerializer
}

/**
* Take value and turn it into a string suitable for inclusion in
* Take value and turn it into an array 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
* @param string|bool|array|DateTime|ArrayAccess|\SplFileObject $value the value of the form parameter
*
* @return string the form string
* @return array [key => value] of formdata
*/
public static function toFormValue($value)
public static function toFormValue(string $key, mixed $value)
{
if ($value instanceof \SplFileObject) {
return $value->getRealPath();
return [$key => $value->getRealPath()];
} elseif (is_array($value) || $value instanceof ArrayAccess) {
$flattened = [];
$result = [];

self::flattenArray(json_decode(json_encode($value), true), $flattened);

foreach ($flattened as $k => $v) {
$result["{$key}{$k}"] = self::toString($v);
}

return $result;
} else {
return self::toString($value);
return [$key => self::toString($value)];
}
}

Expand Down Expand Up @@ -605,4 +617,81 @@ class ObjectSerializer

return $qs ? (string) substr($qs, 0, -1) : '';
}

/**
* Flattens an array of Model object and generates an array compatible
* with formdata - a single-level array where the keys use bracket
* notation to signify nested data.
*
* @param \ArrayAccess|array $source
*
* credit: https://github.com/FranBar1966/FlatPHP
*/
private static function flattenArray(
mixed $source,
array &$destination,
string $start = '',
) {
$opt = [
'prefix' => '[',
'suffix' => ']',
'suffix-end' => true,
'prefix-list' => '[',
'suffix-list' => ']',
'suffix-list-end' => true,
];

if (!is_array($source)) {
$source = (array) $source;
}

/**
* array_is_list only in PHP >= 8.1
*
* credit: https://www.php.net/manual/en/function.array-is-list.php#127044
*/
if (!function_exists('array_is_list')) {
function array_is_list(array $array)
{
$i = -1;

foreach ($array as $k => $v) {
++$i;
if ($k !== $i) {
return false;
}
}

return true;
}
}

if (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;

foreach ($source as $key => $val) {
$currentName .= $currentPrefix.$key;

if (is_array($val) && !empty($val)) {
$currentName .= "{$currentSuffix}";
self::flattenArray($val, $destination, $currentName);
} else {
if ($currentSuffixEnd) {
$currentName .= $currentSuffix;
}
$destination[$currentName] = self::toString($val);
}

$currentName = $start;
}
}
}
4 changes: 2 additions & 2 deletions modules/openapi-generator/src/main/resources/php/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -677,13 +677,13 @@ use {{invokerPackage}}\ObjectSerializer;
$paramFiles = is_array(${{paramName}}) ? ${{paramName}} : [${{paramName}}];
foreach ($paramFiles as $paramFile) {
$formParams['{{baseName}}'][] = \GuzzleHttp\Psr7\Utils::tryFopen(
ObjectSerializer::toFormValue($paramFile),
ObjectSerializer::toFormValue('{{baseName}}', $paramFile)['{{baseName}}'],
'rb'
);
}
{{/isFile}}
{{^isFile}}
$formParams['{{baseName}}'] = ObjectSerializer::toFormValue(${{paramName}});
$formParams = array_merge($formParams, ObjectSerializer::toFormValue('{{baseName}}', ${{paramName}}));
{{/isFile}}
}
{{/formParams}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -593,13 +593,13 @@ use function sprintf;
$paramFiles = is_array(${{paramName}}) ? ${{paramName}} : [${{paramName}}];
foreach ($paramFiles as $paramFile) {
$formParams['{{baseName}}'][] = \GuzzleHttp\Psr7\try_fopen(
ObjectSerializer::toFormValue($paramFile),
ObjectSerializer::toFormValue('{{baseName}}', $paramFile)['{{baseName}}'],
'rb'
);
}
{{/isFile}}
{{^isFile}}
$formParams['{{baseName}}'] = ObjectSerializer::toFormValue(${{paramName}});
$formParams = array_merge($formParams, ObjectSerializer::toFormValue('{{baseName}}', ${{paramName}}));
{{/isFile}}
}
{{/formParams}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,37 @@ paths:
description: file to upload
type: string
format: binary
'/pet/{petId}/uploadImageFullFormData':
post:
tags:
- pet
summary: uploads an image attached to a Pet object as formdata
description: ''
operationId: uploadImageFullFormData
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/PetWithFile'
/store/inventory:
get:
tags:
Expand Down Expand Up @@ -1566,6 +1597,54 @@ components:
- sold
xml:
name: Pet
PetWithFile:
type: object
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
x-is-unique: true
category:
$ref: '#/components/schemas/Category'
name:
type: string
example: doggie
photoUrls:
type: array
xml:
name: photoUrl
wrapped: true
items:
type: string
uniqueItems: true
tags:
type: array
xml:
name: tag
wrapped: true
items:
$ref: '#/components/schemas/Tag'
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
file:
description: file to upload
type: string
format: binary
multiple_files:
type: array
items:
type: string
format: binary
xml:
name: PetWithFile
ApiResponse:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,7 @@ public function testBodyMultipartFormdataArrayOfBinaryRequest(
$formParams['files'][] = $paramFile instanceof \Psr\Http\Message\StreamInterface
? $paramFile
: \GuzzleHttp\Psr7\Utils::tryFopen(
ObjectSerializer::toFormValue($paramFile),
ObjectSerializer::toFormValue('files', $paramFile)['files'],
'rb'
);
}
Expand Down Expand Up @@ -1357,7 +1357,7 @@ public function testBodyMultipartFormdataSingleBinaryRequest(
$formParams['my-file'][] = $paramFile instanceof \Psr\Http\Message\StreamInterface
? $paramFile
: \GuzzleHttp\Psr7\Utils::tryFopen(
ObjectSerializer::toFormValue($paramFile),
ObjectSerializer::toFormValue('my-file', $paramFile)['my-file'],
'rb'
);
}
Expand Down
Loading
Loading