Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public function load(array $configs, ContainerBuilder $container): void
}

$this->registerCommonConfiguration($container, $config, $loader, $formats, $patchFormats, $errorFormats);
$this->registerRestListenerConfiguration($container, $config, $loader);
$this->registerMetadataConfiguration($container, $config, $loader);
$this->registerOAuthConfiguration($container, $config);
$this->registerSwaggerConfiguration($container, $config, $loader);
Expand Down Expand Up @@ -370,6 +371,18 @@ private function registerJsonProblemConfiguration(array $errorFormats, XmlFileLo
$loader->load('problem.xml');
}

private function registerRestListenerConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
{
$container->setParameter('api_platform.rest.disable_rest', $config['disable_rest']);

if ($config['disable_rest']) {
return;
}

$loader->load('rest_event_listener.xml');

}

private function registerGraphQlConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
{
$enabled = $this->isConfigEnabled($container, $config['graphql']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public function getConfigTreeBuilder()
->booleanNode('force_eager')->defaultTrue()->info('Force join on every relation. If disabled, it will only join relations having the EAGER fetch mode.')->end()
->end()
->end()
->booleanNode('disable_rest')->defaultFalse()->info('Disable the rest listeners')->end()
->booleanNode('enable_fos_user')->defaultValue(class_exists(FOSUserBundle::class))->info('Enable the FOSUserBundle integration.')->end()
->booleanNode('enable_nelmio_api_doc')
->defaultFalse()
Expand Down
51 changes: 1 addition & 50 deletions src/Bridge/Symfony/Bundle/Resources/config/api.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<argument>%api_platform.enable_docs%</argument>
<argument>%api_platform.graphql.graphiql.enabled%</argument>
<argument>%api_platform.graphql.graphql_playground.enabled%</argument>
<argument>%api_platform.rest.disable_rest%</argument>

<tag name="routing.loader" />
</service>
Expand Down Expand Up @@ -155,56 +156,6 @@

<!-- Event listeners -->

<!-- kernel.request priority must be < 8 to be executed after the Firewall -->
<service id="api_platform.listener.request.add_format" class="ApiPlatform\Core\EventListener\AddFormatListener">
<argument type="service" id="api_platform.negotiator" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
<argument>%api_platform.formats%</argument>

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="7" />
</service>

<service id="api_platform.listener.request.read" class="ApiPlatform\Core\EventListener\ReadListener">
<argument type="service" id="api_platform.collection_data_provider" />
<argument type="service" id="api_platform.item_data_provider" />
<argument type="service" id="api_platform.subresource_data_provider" />
<argument type="service" id="api_platform.serializer.context_builder" />
<argument type="service" id="api_platform.identifier.converter" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="4" />
</service>

<service id="api_platform.listener.view.write" class="ApiPlatform\Core\EventListener\WriteListener">
<argument type="service" id="api_platform.data_persister" />
<argument type="service" id="api_platform.iri_converter" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
<argument type="service" id="api_platform.resource_class_resolver" />

<tag name="kernel.event_listener" event="kernel.view" method="onKernelView" priority="32" />
</service>

<service id="api_platform.listener.request.deserialize" class="ApiPlatform\Core\EventListener\DeserializeListener">
<argument type="service" id="api_platform.serializer" />
<argument type="service" id="api_platform.serializer.context_builder" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="2" />
</service>

<service id="api_platform.listener.view.serialize" class="ApiPlatform\Core\EventListener\SerializeListener">
<argument type="service" id="api_platform.serializer" />
<argument type="service" id="api_platform.serializer.context_builder" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />

<tag name="kernel.event_listener" event="kernel.view" method="onKernelView" priority="16" />
</service>

<service id="api_platform.listener.view.respond" class="ApiPlatform\Core\EventListener\RespondListener">
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
<tag name="kernel.event_listener" event="kernel.view" method="onKernelView" priority="8" />
</service>

<service id="api_platform.listener.exception.validation" class="ApiPlatform\Core\Bridge\Symfony\Validator\EventListener\ValidationExceptionListener">
<argument type="service" id="api_platform.serializer" />
<argument>%api_platform.error_formats%</argument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<service id="api_platform.metadata.resource.metadata_factory.operation" class="ApiPlatform\Core\Metadata\Resource\Factory\OperationResourceMetadataFactory" decorates="api_platform.metadata.resource.metadata_factory" decoration-priority="10" public="false">
<argument type="service" id="api_platform.metadata.resource.metadata_factory.operation.inner" />
<argument>%api_platform.patch_formats%</argument>
<argument>%api_platform.rest.disable_rest%%</argument>
</service>

<service id="api_platform.metadata.resource.metadata_factory.formats" class="ApiPlatform\Core\Metadata\Resource\Factory\FormatsResourceMetadataFactory" decorates="api_platform.metadata.resource.metadata_factory" decoration-priority="5" public="false">
Expand Down
58 changes: 58 additions & 0 deletions src/Bridge/Symfony/Bundle/Resources/config/rest_event_listener.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<!-- kernel.request priority must be < 8 to be executed after the Firewall -->
<service id="api_platform.listener.request.add_format" class="ApiPlatform\Core\EventListener\AddFormatListener">
<argument type="service" id="api_platform.negotiator" />
<argument type="service" id="api_platform.formats_provider" />

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="7" />
</service>

<service id="api_platform.listener.request.read" class="ApiPlatform\Core\EventListener\ReadListener">
<argument type="service" id="api_platform.collection_data_provider" />
<argument type="service" id="api_platform.item_data_provider" />
<argument type="service" id="api_platform.subresource_data_provider" />
<argument type="service" id="api_platform.serializer.context_builder" />
<argument type="service" id="api_platform.identifier.converter" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="4" />
</service>

<service id="api_platform.listener.view.write" class="ApiPlatform\Core\EventListener\WriteListener">
<argument type="service" id="api_platform.data_persister" />
<argument type="service" id="api_platform.iri_converter" on-invalid="null" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />

<tag name="kernel.event_listener" event="kernel.view" method="onKernelView" priority="32" />
</service>

<service id="api_platform.listener.request.deserialize" class="ApiPlatform\Core\EventListener\DeserializeListener">
<argument type="service" id="api_platform.serializer" />
<argument type="service" id="api_platform.serializer.context_builder" />
<argument type="service" id="api_platform.formats_provider" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="2" />
</service>

<service id="api_platform.listener.view.serialize" class="ApiPlatform\Core\EventListener\SerializeListener">
<argument type="service" id="api_platform.serializer" />
<argument type="service" id="api_platform.serializer.context_builder" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />

<tag name="kernel.event_listener" event="kernel.view" method="onKernelView" priority="16" />
</service>

<service id="api_platform.listener.view.respond" class="ApiPlatform\Core\EventListener\RespondListener">
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
<tag name="kernel.event_listener" event="kernel.view" method="onKernelView" priority="8" />
</service>
</services>

</container>
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ final class OperationResourceMetadataFactory implements ResourceMetadataFactoryI

private $decorated;
private $patchFormats;
private $disableRest;

public function __construct(ResourceMetadataFactoryInterface $decorated, array $patchFormats = [])
public function __construct(ResourceMetadataFactoryInterface $decorated, array $patchFormats = [], $disableRest = false)
{
$this->decorated = $decorated;
$this->patchFormats = $patchFormats;
$this->disableRest = $disableRest;
}

/**
Expand All @@ -59,13 +61,24 @@ public function create(string $resourceClass): ResourceMetadata
$isAbstract = (new \ReflectionClass($resourceClass))->isAbstract();

$collectionOperations = $resourceMetadata->getCollectionOperations();
// If rest is disabled we don't want to add the default operations
// but we want to have the placeholder get operation
if (true === $this->disableRest) {
$collectionOperations = [];
}
if (null === $collectionOperations) {
$resourceMetadata = $resourceMetadata->withCollectionOperations($this->createOperations($isAbstract ? ['GET'] : ['GET', 'POST']));
} else {
$resourceMetadata = $this->normalize(true, $resourceClass, $resourceMetadata, $collectionOperations);
}

$itemOperations = $resourceMetadata->getItemOperations();
// If rest is disabled we don't want to add the default operations
// but we want to have the placeholder get operation
if (true === $this->disableRest) {
$itemOperations = [];
}

if (null === $itemOperations) {
$methods = ['GET', 'DELETE'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ public function testFosUserPriority()
$builder = new ContainerBuilder();

$loader = new XmlFileLoader($builder, new FileLocator(\dirname(__DIR__).'/../../../../src/Bridge/Symfony/Bundle/Resources/config'));
$loader->load('api.xml');
$loader->load('rest_event_listener.xml');
$loader->load('fos_user.xml');

$fosListener = $builder->getDefinition('api_platform.fos_user.event_listener');
Expand Down Expand Up @@ -757,6 +757,26 @@ public function testKeepCachePoolClearerCacheWarmerWithDebug()
$this->extension->load(self::DEFAULT_CONFIG, $containerBuilder);
}

public function testDisableRest()
{
$containerBuilderProphecy = $this->getBaseContainerBuilderProphecy();
$containerBuilderProphecy->setDefinition('api_platform.listener.request.add_format', Argument::type(Definition::class))->shouldNotBeCalled();
$containerBuilderProphecy->setDefinition('api_platform.listener.request.read', Argument::type(Definition::class))->shouldNotBeCalled();
$containerBuilderProphecy->setDefinition('api_platform.listener.view.write', Argument::type(Definition::class))->shouldNotBeCalled();
$containerBuilderProphecy->setDefinition('api_platform.listener.request.deserialize', Argument::type(Definition::class))->shouldNotBeCalled();
$containerBuilderProphecy->setDefinition('api_platform.listener.view.serialize', Argument::type(Definition::class))->shouldNotBeCalled();
$containerBuilderProphecy->setDefinition('api_platform.listener.view.respond', Argument::type(Definition::class))->shouldNotBeCalled();
$containerBuilderProphecy->setParameter('api_platform.rest.disable_rest', false)->shouldNotBeCalled();
$containerBuilderProphecy->setParameter('api_platform.rest.disable_rest', true)->shouldBeCalled();

$containerBuilder = $containerBuilderProphecy->reveal();

$config = self::DEFAULT_CONFIG;
$config['api_platform']['disable_rest'] = true;

$this->extension->load($config, $containerBuilder);
}

private function getPartialContainerBuilderProphecy()
{
$parameterBag = new EnvPlaceholderParameterBag();
Expand Down Expand Up @@ -806,6 +826,7 @@ private function getPartialContainerBuilderProphecy()
'api_platform.http_cache.public' => null,
'api_platform.enable_entrypoint' => true,
'api_platform.enable_docs' => true,
'api_platform.rest.disable_rest' => false,
];

$pagination = [
Expand Down Expand Up @@ -1073,6 +1094,7 @@ private function getBaseContainerBuilderProphecy(array $doctrineIntegrationsToLo
'api_platform.graphql.collection.pagination' => ['enabled' => true],
'api_platform.graphql.graphiql.enabled' => true,
'api_platform.graphql.graphql_playground.enabled' => true,
'api_platform.rest.disable_rest' => false,
'api_platform.resource_class_directories' => Argument::type('array'),
'api_platform.validator.serialize_payload_fields' => [],
'api_platform.elasticsearch.enabled' => false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm
],
'allow_plain_identifiers' => false,
'resource_class_directories' => [],
'disable_rest' => false
], $config);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ class OperationResourceMetadataFactoryTest extends TestCase
/**
* @dataProvider getMetadata
*/
public function testCreateOperation(ResourceMetadata $before, ResourceMetadata $after, array $formats = []): void
public function testCreateOperation(ResourceMetadata $before, ResourceMetadata $after, array $formats = [], $disableRest = false ): void
{
$decoratedProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
$decoratedProphecy->create(Dummy::class)->shouldBeCalled()->willReturn($before);

$this->assertEquals($after, (new OperationResourceMetadataFactory($decoratedProphecy->reveal(), $formats))->create(Dummy::class));
$this->assertEquals($after, (new OperationResourceMetadataFactory($decoratedProphecy->reveal(), $formats, $disableRest))->create(Dummy::class));
}

public function getMetadata(): iterable
Expand All @@ -46,6 +46,7 @@ public function getMetadata(): iterable
yield [new ResourceMetadata(null, null, null, null, [], null, [], []), new ResourceMetadata(null, null, null, $this->getOperations(['get', 'put', 'patch', 'delete']), [], null, [], []), $jsonapi];
yield [new ResourceMetadata(null, null, null, ['get'], [], null, [], []), new ResourceMetadata(null, null, null, $this->getOperations(['get']), [], null, [], [])];
yield [new ResourceMetadata(null, null, null, [], [], null, [], []), new ResourceMetadata(null, null, null, $this->getPlaceholderOperation(), [], null, [], [])];
yield [new ResourceMetadata(null, null, null, null, null, null, [], []), new ResourceMetadata(null, null, null, $this->getPlaceholderOperation(), [], null, [], []), [], true];
yield [new ResourceMetadata(null, null, null, ['put'], [], null, [], []), new ResourceMetadata(null, null, null, $this->getOperations(['put']), [], null, [], [])];
yield [new ResourceMetadata(null, null, null, ['delete'], [], null, [], []), new ResourceMetadata(null, null, null, $this->getOperations(['delete']), [], null, [], [])];
yield [new ResourceMetadata(null, null, null, ['patch' => ['method' => 'PATCH', 'route_name' => 'patch']], [], null, [], []), new ResourceMetadata(null, null, null, array_merge(['patch' => ['method' => 'PATCH', 'route_name' => 'patch']], $this->getPlaceholderOperation()), [], null, [], [])];
Expand Down