diff --git a/.travis.yml b/.travis.yml index 9ead294b1bd..0e30d6d14ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -209,7 +209,7 @@ jobs: - *validate-openapi-v3-yaml - php: '7.3' - env: SYMFONY_DEPRECATIONS_HELPER=0 + env: SYMFONY_DEPRECATIONS_HELPER=max[total]=5 # 5 deprecation notices from FOSUserBundle before_install: - *install-mongodb-php-extension - *disable-xdebug-php-extension @@ -229,5 +229,5 @@ jobs: - *validate-openapi-v3-yaml allow_failures: - - env: SYMFONY_DEPRECATIONS_HELPER=0 + - env: SYMFONY_DEPRECATIONS_HELPER=max[total]=5 # 5 deprecation notices from FOSUserBundle fast_finish: true diff --git a/composer.json b/composer.json index c79f0a187bf..d24cd21e97e 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "guzzlehttp/guzzle": "^6.0", "jangregor/phpstan-prophecy": "^0.3", "justinrainbow/json-schema": "^5.0", - "nelmio/api-doc-bundle": "^2.13.3", + "nelmio/api-doc-bundle": "^2.13.4", "phpdocumentor/reflection-docblock": "^3.0 || ^4.0", "phpdocumentor/type-resolver": "^0.3 || ^0.4", "phpspec/prophecy": "^1.8", @@ -74,7 +74,7 @@ "symfony/framework-bundle": "^4.2", "symfony/mercure-bundle": "*", "symfony/messenger": "^4.2", - "symfony/phpunit-bridge": "^4.3", + "symfony/phpunit-bridge": "^4.3.1", "symfony/routing": "^3.4 || ^4.0", "symfony/security-bundle": "^3.4 || ^4.0", "symfony/security-core": "^3.4 || ^4.0", @@ -86,8 +86,7 @@ }, "conflict": { "doctrine/common": "<2.7", - "doctrine/mongodb-odm": "<2.0", - "symfony/messenger": ">=4.3" + "doctrine/mongodb-odm": "<2.0" }, "suggest": { "doctrine/mongodb-odm-bundle": "To support MongoDB. Only versions 4.0 and later are supported.", diff --git a/features/bootstrap/HydraContext.php b/features/bootstrap/HydraContext.php index 84edc9ff52b..9b995f7c359 100644 --- a/features/bootstrap/HydraContext.php +++ b/features/bootstrap/HydraContext.php @@ -230,7 +230,7 @@ private function getPropertyInfo(string $propertyName, string $className): stdCl } } - throw new \InvalidArgumentException(sprintf('Property "%s" of class "%s" does\'nt exist', $propertyName, $className)); + throw new \InvalidArgumentException(sprintf('Property "%s" of class "%s" doesn\'t exist', $propertyName, $className)); } /** diff --git a/features/graphql/mutation.feature b/features/graphql/mutation.feature index b4fad32664f..0cbe7b46d14 100644 --- a/features/graphql/mutation.feature +++ b/features/graphql/mutation.feature @@ -324,7 +324,7 @@ Feature: GraphQL mutation support When I send the following GraphQL request: """ mutation { - createDummy(input: {_id: 12, name: "", foo: [], clientMutationId: "myId"}) { + createDummy(input: {name: "", foo: [], clientMutationId: "myId"}) { clientMutationId } } diff --git a/features/hydra/docs.feature b/features/hydra/docs.feature index e77d86b4769..9b8fa98f57c 100644 --- a/features/hydra/docs.feature +++ b/features/hydra/docs.feature @@ -56,8 +56,6 @@ Feature: Documentation support And the value of the node "hydra:title" of the Hydra class "Dummy" is "Dummy" And the value of the node "hydra:description" of the Hydra class "Dummy" is "Dummy." # Properties - And "id" property is readable for Hydra class "Dummy" - And "id" property is writable for Hydra class "Dummy" And "name" property is readable for Hydra class "Dummy" And "name" property is writable for Hydra class "Dummy" And "name" property is required for Hydra class "Dummy" diff --git a/features/jsonld/context.feature b/features/jsonld/context.feature index 42bacdca557..45f324a742f 100644 --- a/features/jsonld/context.feature +++ b/features/jsonld/context.feature @@ -41,7 +41,6 @@ Feature: JSON-LD contexts generation "jsonData": "Dummy/jsonData", "arrayData": "Dummy/arrayData", "nameConverted": "Dummy/nameConverted", - "id": "Dummy/id", "name": "http://schema.org/name", "alias": "https://schema.org/alternateName", "foo": "Dummy/foo" diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 83e78a20dcc..bb9f492872a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -32,13 +32,6 @@ parameters: path: %currentWorkingDirectory%/src/GraphQl/Resolver/FieldsToAttributesTrait.php - '#Access to an undefined property Prophecy\\Prophecy\\ObjectProphecy<(\\?[a-zA-Z0-9_]+)+>::\$[a-zA-Z0-9_]+#' - '#Call to an undefined method Doctrine\\Common\\Persistence\\ObjectManager::getConnection\(\)#' - # https://github.com/symfony/symfony/pull/31903 - - - message: '#Access to an undefined property object::\$headers\.#' - path: %currentWorkingDirectory%/tests/Bridge/Symfony/Bundle/Twig/ApiPlatformProfilerPanelTest.php - - - message: '#Call to an undefined method object::getStatusCode\(\)\.#' - path: %currentWorkingDirectory%/tests/Bridge/Symfony/Bundle/Twig/ApiPlatformProfilerPanelTest.php - '#Parameter \#1 \$function of function call_user_func expects callable\(\): mixed, .+ given\.#' - '#Parameter \#1 \$exception of static method Symfony\\Component\\Debug\\Exception\\FlattenException::create\(\) expects Exception, Symfony\\Component\\Serializer\\Exception\\ExceptionInterface given\.#' - '#Parameter \#1 \$classes of class ApiPlatform\\Core\\Metadata\\Resource\\ResourceNameCollection constructor expects array, array given\.#' @@ -75,8 +68,9 @@ parameters: - message: '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Util\\QueryBuilderHelper::mapJoinAliases() should return array\|string> but returns array\.#' path: %currentWorkingDirectory%/src/Bridge/Doctrine/Orm/Util/QueryBuilderHelper.php + # https://github.com/phpstan/phpstan/issues/1482 - - message: "#Call to function method_exists\\(\\) with 'Symfony\\\\\\\\Component.+' and '(removeBindings|addRemovedBindingIds)' will always evaluate to false\\.#" + message: "#Call to function method_exists\\(\\) with 'Symfony\\\\\\\\Component.+' and 'removeBindings' will always evaluate to false\\.#" path: %currentWorkingDirectory%/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php - message: "#Call to function method_exists\\(\\) with 'Symfony\\\\\\\\Component.+' and 'getReachableRoleNam.+' will always evaluate to false\\.#" @@ -85,7 +79,7 @@ parameters: message: "#Call to function method_exists\\(\\) with 'Symfony\\\\\\\\Component.+' and 'getRoleNames' will always evaluate to false\\.#" path: %currentWorkingDirectory%/tests/Security/EventListener/DenyAccessListenerTest.php - "#Call to method PHPUnit\\\\Framework\\\\Assert::assertSame\\(\\) with array\\('(collection_context|item_context|subresource_context)'\\) and array\\|bool\\|float\\|int\\|string\\|null will always evaluate to false\\.#" - # https://github.com/doctrine/doctrine2/pull/7298/files + # https://github.com/doctrine/doctrine2/pull/7298 - '#Strict comparison using === between null and int will always evaluate to false\.#' - message: '#Binary operation "\+" between (float\|int\|)?string and 0 results in an error\.#' diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php b/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php index de1453d25a3..b2f832771ce 100644 --- a/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php +++ b/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php @@ -36,6 +36,7 @@ use Symfony\Component\Config\Resource\DirectoryResource; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; @@ -43,6 +44,8 @@ use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Component\Finder\Finder; use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException; +use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Yaml\Yaml; @@ -521,6 +524,11 @@ private function registerMercureConfiguration(ContainerBuilder $container, array if ($this->isConfigEnabled($container, $config['doctrine'])) { $loader->load('doctrine_orm_mercure_publisher.xml'); + + // BC for Symfony Messenger 4.2 + if (interface_exists(MessageBusInterface::class) && !class_exists(UnrecoverableMessageHandlingException::class)) { + $container->getDefinition('api_platform.doctrine.listener.mercure.publish')->replaceArgument(5, new Reference('message_bus', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)); + } } } @@ -531,6 +539,11 @@ private function registerMessengerConfiguration(ContainerBuilder $container, arr } $loader->load('messenger.xml'); + + // BC for Symfony Messenger 4.2 + if (interface_exists(MessageBusInterface::class) && !class_exists(UnrecoverableMessageHandlingException::class)) { + $container->setAlias('api_platform.message_bus', 'message_bus'); + } } private function registerElasticsearchConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void diff --git a/src/Bridge/Symfony/Bundle/Resources/config/doctrine_orm_mercure_publisher.xml b/src/Bridge/Symfony/Bundle/Resources/config/doctrine_orm_mercure_publisher.xml index 0b4c6e1bdad..54f4f4d1b79 100644 --- a/src/Bridge/Symfony/Bundle/Resources/config/doctrine_orm_mercure_publisher.xml +++ b/src/Bridge/Symfony/Bundle/Resources/config/doctrine_orm_mercure_publisher.xml @@ -14,7 +14,7 @@ %api_platform.formats% - + diff --git a/src/Bridge/Symfony/Bundle/Resources/config/messenger.xml b/src/Bridge/Symfony/Bundle/Resources/config/messenger.xml index 5117f5e9d41..d50ec0e3d69 100644 --- a/src/Bridge/Symfony/Bundle/Resources/config/messenger.xml +++ b/src/Bridge/Symfony/Bundle/Resources/config/messenger.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + diff --git a/src/Bridge/Symfony/Messenger/DataPersister.php b/src/Bridge/Symfony/Messenger/DataPersister.php index fb059983eb5..6d89e5f21b3 100644 --- a/src/Bridge/Symfony/Messenger/DataPersister.php +++ b/src/Bridge/Symfony/Messenger/DataPersister.php @@ -88,6 +88,9 @@ public function persist($data, array $context = []) */ public function remove($data, array $context = []) { - $this->messageBus->dispatch(new Envelope($data, new RemoveStamp())); + $this->messageBus->dispatch( + (new Envelope($data)) + ->with(new RemoveStamp()) + ); } } diff --git a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php index 86877b1b07a..f9796267812 100644 --- a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php +++ b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php @@ -92,6 +92,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException; use Symfony\Component\Serializer\Exception\ExceptionInterface; /** @@ -492,7 +493,10 @@ public function testDisabledSwaggerUIAndRedoc() public function testDisabledMessenger() { $containerBuilderProphecy = $this->getBaseContainerBuilderProphecy(); - $containerBuilderProphecy->setAlias('api_platform.message_bus', 'message_bus')->shouldNotBeCalled(); + $containerBuilderProphecy->setAlias('api_platform.message_bus', 'messenger.default_bus')->shouldNotBeCalled(); + if (!class_exists(UnrecoverableMessageHandlingException::class)) { + $containerBuilderProphecy->setAlias('api_platform.message_bus', 'message_bus')->shouldNotBeCalled(); + } $containerBuilderProphecy->setDefinition('api_platform.messenger.data_persister', Argument::type(Definition::class))->shouldNotBeCalled(); $containerBuilderProphecy->setDefinition('api_platform.messenger.data_transformer', Argument::type(Definition::class))->shouldNotBeCalled(); $containerBuilder = $containerBuilderProphecy->reveal(); @@ -914,15 +918,11 @@ private function getPartialContainerBuilderProphecy() $containerBuilderProphecy->getParameter('kernel.project_dir')->willReturn(__DIR__); $containerBuilderProphecy->getParameter('kernel.debug')->willReturn(false); - $containerBuilderProphecy->getDefinition('api_platform.http_cache.purger.varnish')->willReturn(new Definition()); - // irrelevant, but to prevent errors - // https://github.com/symfony/symfony/pull/29944 + $definitionDummy = $this->prophesize(Definition::class); + $containerBuilderProphecy->getDefinition('api_platform.http_cache.purger.varnish')->willReturn($definitionDummy); if (method_exists(ContainerBuilder::class, 'removeBindings')) { $containerBuilderProphecy->removeBindings(Argument::type('string'))->will(function () {}); - } elseif (method_exists(ContainerBuilder::class, 'addRemovedBindingIds')) { - // remove this once https://github.com/symfony/symfony/pull/31173 is released - $containerBuilderProphecy->addRemovedBindingIds(Argument::type('string'))->will(function () {}); } return $containerBuilderProphecy; @@ -1140,7 +1140,7 @@ private function getBaseContainerBuilderProphecy(array $doctrineIntegrationsToLo $aliases = [ 'api_platform.http_cache.purger' => 'api_platform.http_cache.purger.varnish', - 'api_platform.message_bus' => 'message_bus', + 'api_platform.message_bus' => 'messenger.default_bus', EagerLoadingExtension::class => 'api_platform.doctrine.orm.query_extension.eager_loading', FilterExtension::class => 'api_platform.doctrine.orm.query_extension.filter', FilterEagerLoadingExtension::class => 'api_platform.doctrine.orm.query_extension.filter_eager_loading', @@ -1175,12 +1175,17 @@ private function getBaseContainerBuilderProphecy(array $doctrineIntegrationsToLo $containerBuilderProphecy->setAlias($alias, $service)->shouldBeCalled(); } + if (!class_exists(UnrecoverableMessageHandlingException::class)) { + $containerBuilderProphecy->setAlias('api_platform.message_bus', 'message_bus')->shouldBeCalled(); + } + $containerBuilderProphecy->hasParameter('api_platform.metadata_cache')->willReturn(false); // irrelevant, but to prevent errors + $definitionDummy = $this->prophesize(Definition::class); $containerBuilderProphecy->removeDefinition('api_platform.cache_warmer.cache_pool_clearer')->will(function () {}); - - $containerBuilderProphecy->getDefinition('api_platform.mercure.listener.response.add_link_header')->willReturn(new Definition()); + $containerBuilderProphecy->getDefinition('api_platform.mercure.listener.response.add_link_header')->willReturn($definitionDummy); + $containerBuilderProphecy->getDefinition('api_platform.doctrine.listener.mercure.publish')->willReturn($definitionDummy); return $containerBuilderProphecy; } diff --git a/tests/Bridge/Symfony/Messenger/DataPersisterTest.php b/tests/Bridge/Symfony/Messenger/DataPersisterTest.php index fc7bef5ffdb..2ff2d0dba05 100644 --- a/tests/Bridge/Symfony/Messenger/DataPersisterTest.php +++ b/tests/Bridge/Symfony/Messenger/DataPersisterTest.php @@ -80,7 +80,7 @@ public function testHandle() $dummy = new Dummy(); $messageBus = $this->prophesize(MessageBusInterface::class); - $messageBus->dispatch($dummy)->willReturn(new Envelope($dummy, new HandledStamp($dummy, 'DummyHandler::__invoke')))->shouldBeCalled(); + $messageBus->dispatch($dummy)->willReturn((new Envelope($dummy))->with(new HandledStamp($dummy, 'DummyHandler::__invoke')))->shouldBeCalled(); $dataPersister = new DataPersister($this->prophesize(ResourceMetadataFactoryInterface::class)->reveal(), $messageBus->reveal()); $this->assertSame($dummy, $dataPersister->persist($dummy)); diff --git a/tests/Fixtures/app/AppKernel.php b/tests/Fixtures/app/AppKernel.php index 87a7fd3f4ef..feb981f694c 100644 --- a/tests/Fixtures/app/AppKernel.php +++ b/tests/Fixtures/app/AppKernel.php @@ -130,7 +130,6 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load 'provider' => 'chain_provider', 'http_basic' => null, 'anonymous' => null, - 'logout_on_user_change' => true, ], ], 'access_control' => [ diff --git a/tests/Fixtures/app/config/config_common.yml b/tests/Fixtures/app/config/config_common.yml index c6d853d9632..bbae36ad1b1 100644 --- a/tests/Fixtures/app/config/config_common.yml +++ b/tests/Fixtures/app/config/config_common.yml @@ -8,8 +8,6 @@ framework: session: storage_id: 'session.storage.mock_file' form: ~ # For FOSUser - templating: - engines: ['twig'] # For Swagger UI profiler: enabled: true collect: false