Skip to content

Commit

Permalink
bug #34032 [Mime] Fixing multidimensional array structure with FormDa…
Browse files Browse the repository at this point in the history
…taPart (jvahldick)

This PR was merged into the 4.4 branch.

Discussion
----------

[Mime] Fixing multidimensional array structure with FormDataPart

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #33063 #34031
| License       | MIT
| Doc PR        | -

The issue is pretty much described on #34031
The current structure of the raw body build on FormDataPart is not well recognized by the server. It considers all the fields as a root type, when actually it is possible to send arrays by html forms.

Lets the following structure on the html
```html
<input type="text" name="names[]" value="John" />
<input type="text" name="names[]" value="Doe" />
```

It creates the following raw body:
```
----------------------------466490401959219490193856
Content-Disposition: form-data; name="names[]"

John
----------------------------466490401959219490193856
Content-Disposition: form-data; name="names[]"

Doe
----------------------------466490401959219490193856--
```

Meanwhile, the FormDataPart on Mime component generates the following body:
```
--_=_symfony_1571410799_b7846b3b4e86d821cdec4379e62b4068_=_
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data

John
--_=_symfony_1571410799_b7846b3b4e86d821cdec4379e62b4068_=_
Content-Type: text/plain; charset=utf-8; name=1
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name=1

Doe
--_=_symfony_1571410799_b7846b3b4e86d821cdec4379e62b4068_=_--
```

For more complex structures, the $_POST doesn't even recognize properly the field names and values.

Commits
-------

ca630e5351 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
  • Loading branch information
fabpot committed Nov 30, 2019
2 parents 89da7b6 + 51d5b0e commit 010cc48
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
17 changes: 13 additions & 4 deletions Part/Multipart/FormDataPart.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
28 changes: 28 additions & 0 deletions Tests/Part/Multipart/FormDataPartTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down

0 comments on commit 010cc48

Please sign in to comment.