[PHP] Fix converting objects to formdata (#20888)

* Output of CLI commands per PR comments

* Rebuilding PHP examples, PSR-18

* Rebuilding PHP examples

* Adds explanation for ::flatten_array(); optimized array_is_list pollyfill

* [PHP] Fix converting objects to formdata

* flatten_array -> flattenArray to match code style

* Adds unit test

* Revert "Output of CLI commands per PR comments"

This reverts commit 2eaa93731c.

* Includes php-nextgen; tightens up ::toFormValue()

* Missing ArrayAccess import

* Adds test for refactored ObjectSerializer::toFormValue()
This commit is contained in:
Juan Treminio
2025-03-19 02:39:57 -05:00
committed by GitHub
parent 8a8bacd0d5
commit 8f24df4165
27 changed files with 1877 additions and 151 deletions

View File

@@ -28,6 +28,7 @@
namespace OpenAPI\Client;
use ArrayAccess;
use DateTimeInterface;
use DateTime;
use GuzzleHttp\Psr7\Utils;
@@ -326,20 +327,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)];
}
}
@@ -608,4 +622,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;
}
}
}