[php-symfony] fix handling of endpoints with "text/plain" or "image/png" response type (#21261)

* [php-symfony] Never return 406 when user accepts */*

When a query has header "Accept" set to "*/*" it means it accepts
everything. It is hence weird to return a 406.
This patch ensures it does not occur: when the query accepts everything
then we take any produced type.

This fixes #13334. This also partly makes the open PR #15560 obsolete
(or at least, it provides a workaround)

* [php-symfony] Don't crash at runtime on null convertFormat

$this->convertFormat may return "null". When it's the case we end up
calling

    ...->serialize($data, null);

but this crashes at runtime because that serialize method declares that
the 2nd parameter is of type "string" (so null is not accepted).

With this patch we avoid having an error 500. Instead we return something
that makes perfect sense when the OpenApi specification declares a content
of type "text/plain" and that the returned value is for instance a string,
an int, or a boolean.

* [php Symfony] fix return type for non json/xml api

This fixes the generated returned type of controller methods for
endpoint with a response declared like

    content:
      text/plain:
        schema:
          type: <boolean|string|integer|number>

or for

    content:
      image/png:
        schema:
          type: string
          format: binary

Without this commit the generated method *had to* return a value that
matched "array|object|null", which does not work in this case.
This commit makes it possible to return the proper type.
This commit is contained in:
Guillaume Turri
2025-05-14 15:11:39 +02:00
committed by GitHub
parent 429da9860b
commit 40894382fc
5 changed files with 43 additions and 5 deletions

View File

@@ -214,6 +214,10 @@ class Controller extends AbstractController
return 'application/xml';
}
if (in_array('*/*', $accept)) {
return $produced[0];
}
// If we reach this point, we don't have a common ground between server and client
return null;
}

View File

@@ -29,7 +29,13 @@ class JmsSerializer implements SerializerInterface
*/
public function serialize($data, string $format): string
{
return SerializerBuilder::create()->build()->serialize($data, $this->convertFormat($format));
$convertFormat = $this->convertFormat($format);
if ($convertFormat !== null) {
return SerializerBuilder::create()->build()->serialize($data, $convertFormat);
} else {
// don't use var_export if $data is already a string: it may corrupt binary strings
return is_string($data) ? $data : var_export($data, true);
}
}
/**