From 51d5b0e72f7871f7538411adb11a32d5252454e2 Mon Sep 17 00:00:00 2001 From: Jorge Vahldick Date: Fri, 18 Oct 2019 15:20:21 +0100 Subject: [PATCH] Changing the multipart form-data behavior to use the form name as an array, which makes it recognizable as an array by PHP on the $_POST globals once it is coming from the HttpClient component --- Part/Multipart/FormDataPart.php | 17 ++++++++++---- Tests/Part/Multipart/FormDataPartTest.php | 28 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Part/Multipart/FormDataPart.php b/Part/Multipart/FormDataPart.php index 88aa1a3..6838620 100644 --- a/Part/Multipart/FormDataPart.php +++ b/Part/Multipart/FormDataPart.php @@ -56,11 +56,20 @@ public function getParts(): array private function prepareFields(array $fields): array { $values = []; - array_walk_recursive($fields, function ($item, $key) use (&$values) { - if (!\is_array($item)) { - $values[] = $this->preparePart($key, $item); + + $prepare = function ($item, $key, $root = null) use (&$values, &$prepare) { + $fieldName = $root ? sprintf('%s[%s]', $root, $key) : $key; + + if (\is_array($item)) { + array_walk($item, $prepare, $fieldName); + + return; } - }); + + $values[] = $this->preparePart($fieldName, $item); + }; + + array_walk($fields, $prepare); return $values; } diff --git a/Tests/Part/Multipart/FormDataPartTest.php b/Tests/Part/Multipart/FormDataPartTest.php index 71a03e6..a74ecea 100644 --- a/Tests/Part/Multipart/FormDataPartTest.php +++ b/Tests/Part/Multipart/FormDataPartTest.php @@ -47,6 +47,34 @@ public function testConstructor() $this->assertEquals([$t, $b, $c], $f->getParts()); } + public function testNestedArrayParts() + { + $p1 = new TextPart('content', 'utf-8', 'plain', '8bit'); + $f = new FormDataPart([ + 'foo' => clone $p1, + 'bar' => [ + 'baz' => [ + clone $p1, + 'qux' => clone $p1, + ], + ], + ]); + + $this->assertEquals('multipart', $f->getMediaType()); + $this->assertEquals('form-data', $f->getMediaSubtype()); + + $p1->setName('foo'); + $p1->setDisposition('form-data'); + + $p2 = clone $p1; + $p2->setName('bar[baz][0]'); + + $p3 = clone $p1; + $p3->setName('bar[baz][qux]'); + + $this->assertEquals([$p1, $p2, $p3], $f->getParts()); + } + public function testToString() { $p = DataPart::fromPath($file = __DIR__.'/../../Fixtures/mimetypes/test.gif');