diff --git a/src/Documentation/Action/DocumentationAction.php b/src/Documentation/Action/DocumentationAction.php index 533f84b3455..221351beebe 100644 --- a/src/Documentation/Action/DocumentationAction.php +++ b/src/Documentation/Action/DocumentationAction.php @@ -21,6 +21,7 @@ use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface; use ApiPlatform\OpenApi\OpenApi; use ApiPlatform\OpenApi\Serializer\ApiGatewayNormalizer; +use ApiPlatform\OpenApi\Serializer\LegacyOpenApiNormalizer; use ApiPlatform\OpenApi\Serializer\OpenApiNormalizer; use ApiPlatform\State\ProcessorInterface; use ApiPlatform\State\ProviderInterface; @@ -60,7 +61,11 @@ public function __invoke(Request $request = null) return new Documentation($this->resourceNameCollectionFactory->create(), $this->title, $this->description, $this->version); } - $context = ['api_gateway' => $request->query->getBoolean(ApiGatewayNormalizer::API_GATEWAY), 'base_url' => $request->getBaseUrl()]; + $context = [ + 'api_gateway' => $request->query->getBoolean(ApiGatewayNormalizer::API_GATEWAY), + 'base_url' => $request->getBaseUrl(), + 'spec_version' => $request->query->getString(LegacyOpenApiNormalizer::SPEC_VERSION), + ]; $request->attributes->set('_api_normalization_context', $request->attributes->get('_api_normalization_context', []) + $context); $format = $this->getRequestFormat($request, $this->documentationFormats); @@ -78,7 +83,18 @@ private function getOpenApiDocumentation(array $context, string $format, Request { if ($this->provider && $this->processor) { $context['request'] = $request; - $operation = new Get(class: OpenApi::class, read: true, serialize: true, provider: fn () => $this->openApiFactory->__invoke($context), normalizationContext: [ApiGatewayNormalizer::API_GATEWAY => $context['api_gateway'] ?? null], outputFormats: $this->documentationFormats); + $operation = new Get( + class: OpenApi::class, + read: true, + serialize: true, + provider: fn () => $this->openApiFactory->__invoke($context), + normalizationContext: [ + ApiGatewayNormalizer::API_GATEWAY => $context['api_gateway'] ?? null, + LegacyOpenApiNormalizer::SPEC_VERSION => $context['spec_version'] ?? null, + ], + outputFormats: $this->documentationFormats + ); + if ('html' === $format) { $operation = $operation->withProcessor('api_platform.swagger_ui.processor')->withWrite(true); } diff --git a/src/OpenApi/Serializer/LegacyOpenApiNormalizer.php b/src/OpenApi/Serializer/LegacyOpenApiNormalizer.php new file mode 100644 index 00000000000..8bbcd77b3ed --- /dev/null +++ b/src/OpenApi/Serializer/LegacyOpenApiNormalizer.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\OpenApi\Serializer; + +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; + +final class LegacyOpenApiNormalizer implements NormalizerInterface +{ + public const SPEC_VERSION = 'spec_version'; + private array $defaultContext = [ + self::SPEC_VERSION => '3.1.0', + ]; + + public function __construct(private readonly NormalizerInterface $decorated, $defaultContext = []) + { + $this->defaultContext = array_merge($this->defaultContext, $defaultContext); + } + + public function normalize(mixed $object, string $format = null, array $context = []): array + { + $openapi = $this->decorated->normalize($object, $format, $context); + + if ('3.0' !== $context['spec_version']) { + return $openapi; + } + + foreach ($openapi['components']['schemas'] as &$schema) { + foreach ($schema['properties'] ?? [] as &$property) { + if (isset($property['type']) && \is_array($property['type'])) { + $property['type'] = $property['type'][0]; + } + + if (isset($property['type']['owl:maxCardinality'])) { + unset($proprety['type']['owl:maxCardinality']); + } + } + } + + return $openapi; + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization(mixed $data, string $format = null, array $context = []): bool + { + return $this->decorated->supportsNormalization($data, $format, $context); + } + + public function getSupportedTypes($format): array + { + return $this->decorated->getSupportedTypes($format); + } +} diff --git a/src/Symfony/Bundle/Resources/config/openapi.xml b/src/Symfony/Bundle/Resources/config/openapi.xml index 358c48fe5c8..3c53659a5cb 100644 --- a/src/Symfony/Bundle/Resources/config/openapi.xml +++ b/src/Symfony/Bundle/Resources/config/openapi.xml @@ -58,7 +58,12 @@ - + + + + + +