diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f5defe04968..4b47ebb7e25 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -104,12 +104,6 @@ parameters: - src/Serializer/AbstractConstraintViolationListNormalizer.php - src/Symfony/Validator/Serializer/ValidationExceptionNormalizer.php - # See https://github.com/phpstan/phpstan-symfony/issues/27 - - - message: '#^Service "[^"]+" is private.$#' - path: src - - # Allow extra assertions in tests: https://github.com/phpstan/phpstan-strict-rules/issues/130 - '#^Call to (static )?method PHPUnit\\Framework\\Assert::.* will always evaluate to true\.$#' diff --git a/src/State/SerializerAwareProviderInterface.php b/src/State/SerializerAwareProviderInterface.php deleted file mode 100644 index e213176dc4a..00000000000 --- a/src/State/SerializerAwareProviderInterface.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * 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\State; - -use Psr\Container\ContainerInterface; - -/** - * Injects serializer in providers. - * - * @author Vincent Chalamon - */ -interface SerializerAwareProviderInterface -{ - /** - * @return void - */ - public function setSerializerLocator(ContainerInterface $serializerLocator); -} diff --git a/src/State/SerializerAwareProviderTrait.php b/src/State/SerializerAwareProviderTrait.php deleted file mode 100644 index dfe28b55606..00000000000 --- a/src/State/SerializerAwareProviderTrait.php +++ /dev/null @@ -1,40 +0,0 @@ - - * - * 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\State; - -use Psr\Container\ContainerInterface; -use Symfony\Component\Serializer\SerializerInterface; - -/** - * Injects serializer in providers. - * - * @author Vincent Chalamon - */ -trait SerializerAwareProviderTrait -{ - /** - * @internal - */ - private ContainerInterface $serializerLocator; - - public function setSerializerLocator(ContainerInterface $serializerLocator): void - { - $this->serializerLocator = $serializerLocator; - } - - private function getSerializer(): SerializerInterface - { - return $this->serializerLocator->get('serializer'); - } -} diff --git a/src/Symfony/Bundle/ApiPlatformBundle.php b/src/Symfony/Bundle/ApiPlatformBundle.php index 8a3eb9021bf..1754078407e 100644 --- a/src/Symfony/Bundle/ApiPlatformBundle.php +++ b/src/Symfony/Bundle/ApiPlatformBundle.php @@ -16,7 +16,6 @@ use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\AttributeFilterPass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\AttributeResourcePass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\AuthenticatorManagerPass; -use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\DataProviderPass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\ElasticsearchClientPass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\FilterPass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\GraphQlResolverPass; @@ -43,7 +42,6 @@ public function build(ContainerBuilder $container): void { parent::build($container); - $container->addCompilerPass(new DataProviderPass()); // Run the compiler pass before the {@see ResolveInstanceofConditionalsPass} to allow autoconfiguration of generated filter definitions. $container->addCompilerPass(new AttributeFilterPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 101); $container->addCompilerPass(new AttributeResourcePass()); diff --git a/src/Symfony/Bundle/DependencyInjection/Compiler/DataProviderPass.php b/src/Symfony/Bundle/DependencyInjection/Compiler/DataProviderPass.php deleted file mode 100644 index 3d9567a1696..00000000000 --- a/src/Symfony/Bundle/DependencyInjection/Compiler/DataProviderPass.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * 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\Symfony\Bundle\DependencyInjection\Compiler; - -use ApiPlatform\State\SerializerAwareProviderInterface; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; - -/** - * Registers data providers. - * - * @internal - * - * @author Kévin Dunglas - * @author Vincent Chalamon - */ -final class DataProviderPass implements CompilerPassInterface -{ - /** - * {@inheritdoc} - */ - public function process(ContainerBuilder $container): void - { - $services = $container->findTaggedServiceIds('api_platform.state_provider', true); - - foreach ($services as $id => $tags) { - $definition = $container->getDefinition((string) $id); - if (is_a($definition->getClass(), SerializerAwareProviderInterface::class, true)) { - $definition->addMethodCall('setSerializerLocator', [new Reference('api_platform.serializer_locator')]); - } - } - } -} diff --git a/tests/Fixtures/TestBundle/State/SerializableProvider.php b/tests/Fixtures/TestBundle/State/SerializableProvider.php index 02c257266eb..3cf2de0384a 100644 --- a/tests/Fixtures/TestBundle/State/SerializableProvider.php +++ b/tests/Fixtures/TestBundle/State/SerializableProvider.php @@ -15,15 +15,26 @@ use ApiPlatform\Metadata\Operation; use ApiPlatform\State\ProviderInterface; -use ApiPlatform\State\SerializerAwareProviderInterface; -use ApiPlatform\State\SerializerAwareProviderTrait; +use Psr\Container\ContainerInterface; +use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Contracts\Service\ServiceSubscriberInterface; /** * @author Vincent Chalamon */ -class SerializableProvider implements ProviderInterface, SerializerAwareProviderInterface +readonly class SerializableProvider implements ProviderInterface, ServiceSubscriberInterface { - use SerializerAwareProviderTrait; + public function __construct(private ContainerInterface $container) + { + } + + /** + * @return array + */ + public static function getSubscribedServices(): array + { + return ['serializer' => SerializerInterface::class]; + } /** * {@inheritDoc} @@ -39,4 +50,13 @@ public function provide(Operation $operation, array $uriVariables = [], array $c JSON , $operation->getClass(), 'json'); } + + private function getSerializer(): SerializerInterface + { + if (!$this->container->has('serializer')) { + throw new \LogicException('The serializer service is not available. Did you forget to install symfony/serializer?'); + } + + return $this->container->get('serializer'); + } } diff --git a/tests/Fixtures/app/config/config_common.yml b/tests/Fixtures/app/config/config_common.yml index f9d2cd2afba..3cfdd7e1cf3 100644 --- a/tests/Fixtures/app/config/config_common.yml +++ b/tests/Fixtures/app/config/config_common.yml @@ -138,6 +138,9 @@ services: class: 'ApiPlatform\Tests\Fixtures\TestBundle\State\SerializableProvider' tags: - name: 'api_platform.state_provider' + arguments: + - !service_locator + serializer: '@Symfony\Component\Serializer\SerializerInterface' ApiPlatform\Tests\Fixtures\TestBundle\State\FakeProvider: class: 'ApiPlatform\Tests\Fixtures\TestBundle\State\FakeProvider' diff --git a/tests/Symfony/Bundle/ApiPlatformBundleTest.php b/tests/Symfony/Bundle/ApiPlatformBundleTest.php index 070a6b35af0..6e4ac45f3c0 100644 --- a/tests/Symfony/Bundle/ApiPlatformBundleTest.php +++ b/tests/Symfony/Bundle/ApiPlatformBundleTest.php @@ -17,7 +17,6 @@ use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\AttributeFilterPass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\AttributeResourcePass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\AuthenticatorManagerPass; -use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\DataProviderPass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\ElasticsearchClientPass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\FilterPass; use ApiPlatform\Symfony\Bundle\DependencyInjection\Compiler\GraphQlResolverPass; @@ -42,7 +41,6 @@ class ApiPlatformBundleTest extends TestCase public function testBuild(): void { $containerProphecy = $this->prophesize(ContainerBuilder::class); - $containerProphecy->addCompilerPass(Argument::type(DataProviderPass::class))->willReturn($containerProphecy->reveal())->shouldBeCalled(); $containerProphecy->addCompilerPass(Argument::type(AttributeFilterPass::class), PassConfig::TYPE_BEFORE_OPTIMIZATION, 101)->willReturn($containerProphecy->reveal())->shouldBeCalled(); $containerProphecy->addCompilerPass(Argument::type(AttributeResourcePass::class))->shouldBeCalled()->willReturn($containerProphecy->reveal())->shouldBeCalled(); $containerProphecy->addCompilerPass(Argument::type(FilterPass::class))->willReturn($containerProphecy->reveal())->shouldBeCalled();