diff --git a/features/hydra/entrypoint.feature b/features/hydra/entrypoint.feature
index b4b008583cc..b2b8f731d27 100644
--- a/features/hydra/entrypoint.feature
+++ b/features/hydra/entrypoint.feature
@@ -4,6 +4,7 @@ Feature: Entrypoint support
I need to access to an entrypoint listing top-level resources
Scenario: Retrieve the Entrypoint
+ When I add "Accept" header equal to "application/ld+json"
When I send a "GET" request to "/"
Then the response status code should be 200
And the response should be in JSON
diff --git a/features/openapi/docs.feature b/features/openapi/docs.feature
index 13b2cba199b..18f09998c8b 100644
--- a/features/openapi/docs.feature
+++ b/features/openapi/docs.feature
@@ -362,3 +362,9 @@ Feature: Documentation support
And I send a "GET" request to "/docs"
Then the response status code should be 200
And the header "Content-Type" should be equal to "application/vnd.openapi+yaml; charset=utf-8"
+
+ Scenario: Retrieve the OpenAPI documentation
+ Given I add "Accept" header equal to "text/html"
+ And I send a "GET" request to "/"
+ Then the response status code should be 200
+ And the header "Content-Type" should be equal to "text/html; charset=utf-8"
diff --git a/src/Documentation/Action/EntrypointAction.php b/src/Documentation/Action/EntrypointAction.php
index 85070b66ba2..ce619e4f52e 100644
--- a/src/Documentation/Action/EntrypointAction.php
+++ b/src/Documentation/Action/EntrypointAction.php
@@ -16,6 +16,7 @@
use ApiPlatform\Documentation\Entrypoint;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
+use ApiPlatform\Metadata\Resource\ResourceNameCollection;
use ApiPlatform\State\ProcessorInterface;
use ApiPlatform\State\ProviderInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -27,6 +28,8 @@
*/
final class EntrypointAction
{
+ private static ResourceNameCollection $resourceNameCollection;
+
public function __construct(
private readonly ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory,
private readonly ProviderInterface $provider,
@@ -35,12 +38,21 @@ public function __construct(
) {
}
- public function __invoke(Request $request = null)
+ public function __invoke(Request $request)
{
+ static::$resourceNameCollection = $this->resourceNameCollectionFactory->create();
$context = ['request' => $request];
- $operation = new Get(outputFormats: $this->documentationFormats, read: true, serialize: true, class: Entrypoint::class, provider: fn () => new Entrypoint($this->resourceNameCollectionFactory->create()));
+ $request->attributes->set('_api_platform_disable_listeners', true);
+ $operation = new Get(outputFormats: $this->documentationFormats, read: true, serialize: true, class: Entrypoint::class, provider: [self::class, 'provide']);
+ $request->attributes->set('_api_operation', $operation);
$body = $this->provider->provide($operation, [], $context);
+ $operation = $request->attributes->get('_api_operation');
return $this->processor->process($body, $operation, [], $context);
}
+
+ public static function provide(): Entrypoint
+ {
+ return new Entrypoint(static::$resourceNameCollection);
+ }
}
diff --git a/src/Symfony/Bundle/Resources/config/api.xml b/src/Symfony/Bundle/Resources/config/api.xml
index 7f3d5324607..2230d6ea31e 100644
--- a/src/Symfony/Bundle/Resources/config/api.xml
+++ b/src/Symfony/Bundle/Resources/config/api.xml
@@ -96,7 +96,7 @@
-
+
diff --git a/src/Symfony/Bundle/Resources/config/legacy/events.xml b/src/Symfony/Bundle/Resources/config/legacy/events.xml
index ef204daf222..09cd273d3be 100644
--- a/src/Symfony/Bundle/Resources/config/legacy/events.xml
+++ b/src/Symfony/Bundle/Resources/config/legacy/events.xml
@@ -10,6 +10,7 @@
%api_platform.formats%
%api_platform.error_formats%
%api_platform.docs_formats%
+ %api_platform.event_listeners_backward_compatibility_layer%
diff --git a/src/Symfony/EventListener/AddFormatListener.php b/src/Symfony/EventListener/AddFormatListener.php
index 75441e8e7d8..fa4c3990582 100644
--- a/src/Symfony/EventListener/AddFormatListener.php
+++ b/src/Symfony/EventListener/AddFormatListener.php
@@ -34,7 +34,7 @@ final class AddFormatListener
{
use OperationRequestInitiatorTrait;
- public function __construct(private readonly Negotiator $negotiator, ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory = null, private readonly array $formats = [], private readonly array $errorFormats = [], private readonly array $docsFormats = [])
+ public function __construct(private readonly Negotiator $negotiator, ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory = null, private readonly array $formats = [], private readonly array $errorFormats = [], private readonly array $docsFormats = [], private readonly bool $eventsBackwardCompatibility = true)
{
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
}
@@ -50,7 +50,7 @@ public function onKernelRequest(RequestEvent $event): void
$request = $event->getRequest();
$operation = $this->initializeOperation($request);
- if ('api_platform.symfony.main_controller' === $operation?->getController()) {
+ if ('api_platform.symfony.main_controller' === $operation?->getController() || ($this->eventsBackwardCompatibility && 'api_platform.action.entrypoint' === $request->attributes->get('_controller')) || $request->attributes->get('_api_platform_disable_listeners')) {
return;
}
diff --git a/src/Symfony/EventListener/AddHeadersListener.php b/src/Symfony/EventListener/AddHeadersListener.php
index 097ff41eab0..02663db3146 100644
--- a/src/Symfony/EventListener/AddHeadersListener.php
+++ b/src/Symfony/EventListener/AddHeadersListener.php
@@ -35,7 +35,7 @@ public function __construct(private readonly bool $etag = false, private readonl
public function onKernelResponse(ResponseEvent $event): void
{
$request = $event->getRequest();
- if (!$request->isMethodCacheable()) {
+ if (!$request->isMethodCacheable() || $request->attributes->get('_api_platform_disable_listeners')) {
return;
}
diff --git a/src/Symfony/EventListener/AddLinkHeaderListener.php b/src/Symfony/EventListener/AddLinkHeaderListener.php
index 2a41c2d53ba..fecd341729f 100644
--- a/src/Symfony/EventListener/AddLinkHeaderListener.php
+++ b/src/Symfony/EventListener/AddLinkHeaderListener.php
@@ -49,7 +49,7 @@ public function onKernelResponse(ResponseEvent $event): void
$operation = $this->initializeOperation($request);
// API Platform 3.2 has a MainController where everything is handled by processors/providers
- if ('api_platform.symfony.main_controller' === $operation?->getController() || $this->isPreflightRequest($request)) {
+ if ('api_platform.symfony.main_controller' === $operation?->getController() || $this->isPreflightRequest($request) || $request->attributes->get('_api_platform_disable_listeners')) {
return;
}
diff --git a/src/Symfony/EventListener/AddTagsListener.php b/src/Symfony/EventListener/AddTagsListener.php
index a3970c77f85..1281ab2bcb8 100644
--- a/src/Symfony/EventListener/AddTagsListener.php
+++ b/src/Symfony/EventListener/AddTagsListener.php
@@ -58,6 +58,7 @@ public function onKernelResponse(ResponseEvent $event): void
!$request->isMethodCacheable()
|| !$response->isCacheable()
|| (!$attributes = RequestAttributesExtractor::extractAttributes($request))
+ || $request->attributes->get('_api_platform_disable_listeners')
) {
return;
}
diff --git a/src/Symfony/EventListener/DenyAccessListener.php b/src/Symfony/EventListener/DenyAccessListener.php
index 4a2b0b6ca21..fdaa9f9a881 100644
--- a/src/Symfony/EventListener/DenyAccessListener.php
+++ b/src/Symfony/EventListener/DenyAccessListener.php
@@ -62,7 +62,7 @@ public function onSecurityPostValidation(ViewEvent $event): void
*/
private function checkSecurity(Request $request, string $attribute, array $extraVariables = []): void
{
- if (!$this->resourceAccessChecker || !$attributes = RequestAttributesExtractor::extractAttributes($request)) {
+ if ($request->attributes->get('_api_platform_disable_listeners') || !$this->resourceAccessChecker || !$attributes = RequestAttributesExtractor::extractAttributes($request)) {
return;
}
diff --git a/src/Symfony/EventListener/DeserializeListener.php b/src/Symfony/EventListener/DeserializeListener.php
index bdde94c2c3b..e4349f899d0 100644
--- a/src/Symfony/EventListener/DeserializeListener.php
+++ b/src/Symfony/EventListener/DeserializeListener.php
@@ -70,6 +70,7 @@ public function onKernelRequest(RequestEvent $event): void
|| $request->isMethodSafe()
|| !($attributes = RequestAttributesExtractor::extractAttributes($request))
|| !$attributes['receive']
+ || $request->attributes->get('_api_platform_disable_listeners')
) {
return;
}
diff --git a/src/Symfony/EventListener/QueryParameterValidateListener.php b/src/Symfony/EventListener/QueryParameterValidateListener.php
index 0adda2e6ac9..ea83890bf95 100644
--- a/src/Symfony/EventListener/QueryParameterValidateListener.php
+++ b/src/Symfony/EventListener/QueryParameterValidateListener.php
@@ -47,6 +47,7 @@ public function onKernelRequest(RequestEvent $event): void
!$request->isMethodSafe()
|| !($attributes = RequestAttributesExtractor::extractAttributes($request))
|| 'GET' !== $request->getMethod()
+ || $request->attributes->get('_api_platform_disable_listeners')
) {
return;
}
diff --git a/src/Symfony/EventListener/ReadListener.php b/src/Symfony/EventListener/ReadListener.php
index 3ba63f0d2db..5e41061aa5e 100644
--- a/src/Symfony/EventListener/ReadListener.php
+++ b/src/Symfony/EventListener/ReadListener.php
@@ -60,7 +60,7 @@ public function onKernelRequest(RequestEvent $event): void
$request = $event->getRequest();
$operation = $this->initializeOperation($request);
- if ('api_platform.symfony.main_controller' === $operation?->getController()) {
+ if ('api_platform.symfony.main_controller' === $operation?->getController() || $request->attributes->get('_api_platform_disable_listeners')) {
return;
}
diff --git a/src/Symfony/EventListener/RespondListener.php b/src/Symfony/EventListener/RespondListener.php
index c1ebc0e667c..cdf2fe0076b 100644
--- a/src/Symfony/EventListener/RespondListener.php
+++ b/src/Symfony/EventListener/RespondListener.php
@@ -54,7 +54,7 @@ public function onKernelView(ViewEvent $event): void
$controllerResult = $event->getControllerResult();
$operation = $this->initializeOperation($request);
- if ('api_platform.symfony.main_controller' === $operation?->getController()) {
+ if ('api_platform.symfony.main_controller' === $operation?->getController() || $request->attributes->get('_api_platform_disable_listeners')) {
return;
}
diff --git a/src/Symfony/EventListener/SerializeListener.php b/src/Symfony/EventListener/SerializeListener.php
index 71c9510713e..72796c4b793 100644
--- a/src/Symfony/EventListener/SerializeListener.php
+++ b/src/Symfony/EventListener/SerializeListener.php
@@ -73,7 +73,7 @@ public function onKernelView(ViewEvent $event): void
$operation = $this->initializeOperation($request);
- if ('api_platform.symfony.main_controller' === $operation?->getController()) {
+ if ('api_platform.symfony.main_controller' === $operation?->getController() || $request->attributes->get('_api_platform_disable_listeners')) {
return;
}
diff --git a/src/Symfony/EventListener/ValidateListener.php b/src/Symfony/EventListener/ValidateListener.php
index 402f620926e..6a69d6f45fe 100644
--- a/src/Symfony/EventListener/ValidateListener.php
+++ b/src/Symfony/EventListener/ValidateListener.php
@@ -46,7 +46,7 @@ public function onKernelView(ViewEvent $event): void
$controllerResult = $event->getControllerResult();
$request = $event->getRequest();
$operation = $this->initializeOperation($request);
- if ('api_platform.symfony.main_controller' === $operation?->getController()) {
+ if ('api_platform.symfony.main_controller' === $operation?->getController() || $request->attributes->get('_api_platform_disable_listeners')) {
return;
}
diff --git a/src/Symfony/EventListener/WriteListener.php b/src/Symfony/EventListener/WriteListener.php
index 0be49176c9b..08c5db56ae5 100644
--- a/src/Symfony/EventListener/WriteListener.php
+++ b/src/Symfony/EventListener/WriteListener.php
@@ -60,7 +60,7 @@ public function onKernelView(ViewEvent $event): void
$operation = $this->initializeOperation($request);
// API Platform 3.2 has a MainController where everything is handled by processors/providers
- if ('api_platform.symfony.main_controller' === $operation?->getController()) {
+ if ('api_platform.symfony.main_controller' === $operation?->getController() || $request->attributes->get('_api_platform_disable_listeners')) {
return;
}
diff --git a/tests/Symfony/Bundle/Twig/ApiPlatformProfilerPanelTest.php b/tests/Symfony/Bundle/Twig/ApiPlatformProfilerPanelTest.php
index 11ae553f35a..27636deb23b 100644
--- a/tests/Symfony/Bundle/Twig/ApiPlatformProfilerPanelTest.php
+++ b/tests/Symfony/Bundle/Twig/ApiPlatformProfilerPanelTest.php
@@ -57,6 +57,11 @@ protected function tearDown(): void
parent::tearDown();
}
+ /**
+ * TODO: remove openapiContext to get rid of the legacy.
+ *
+ * @group legacy
+ */
public function testDebugBarContentNotResourceClass(): void
{
$client = static::createClient();
@@ -94,6 +99,11 @@ public function testDebugBarContent(): void
$this->assertSame('mongodb' === $this->env ? DocumentDummy::class : Dummy::class, $block->filterXPath('//div[@class="sf-toolbar-info-piece"][./b[contains(., "Resource Class")]]/span')->html());
}
+ /**
+ * TODO: remove openapiContext to get rid of the legacy.
+ *
+ * @group legacy
+ */
public function testProfilerGeneralLayoutNotResourceClass(): void
{
$client = static::createClient();