From 98491a55363a93e3fa8ad0b4f4990da7c4fd02ba Mon Sep 17 00:00:00 2001 From: dev-craftec <89782875+dev-craftec@users.noreply.github.com> Date: Fri, 23 May 2025 10:50:56 +0200 Subject: [PATCH 01/15] Update AbstractScalarParam.php Fixes "Passing an array of options to configure the \"FOS\\RestBundle\\Validator\\Constraints\\Regex\" constraint is deprecated, use named arguments instead." --- Controller/Annotations/AbstractScalarParam.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Controller/Annotations/AbstractScalarParam.php b/Controller/Annotations/AbstractScalarParam.php index 5243f48c1..cf8968724 100644 --- a/Controller/Annotations/AbstractScalarParam.php +++ b/Controller/Annotations/AbstractScalarParam.php @@ -41,19 +41,19 @@ public function getConstraints() if ($this->requirements instanceof Constraint) { $constraints[] = $this->requirements; } elseif (is_scalar($this->requirements)) { - $constraints[] = new Regex([ - 'pattern' => '#^(?:'.$this->requirements.')$#xsu', - 'message' => sprintf( + $constraints[] = new Regex( + pattern: '#^(?:'.$this->requirements.')$#xsu', + message: sprintf( 'Parameter \'%s\' value, does not match requirements \'%s\'', $this->getName(), $this->requirements ), - ]); + ); } elseif (is_array($this->requirements) && isset($this->requirements['rule']) && $this->requirements['error_message']) { - $constraints[] = new Regex([ - 'pattern' => '#^(?:'.$this->requirements['rule'].')$#xsu', - 'message' => $this->requirements['error_message'], - ]); + $constraints[] = new Regex( + pattern: '#^(?:'.$this->requirements['rule'].')$#xsu', + message: $this->requirements['error_message'], + ); } elseif (is_array($this->requirements)) { foreach ($this->requirements as $index => $requirement) { if ($requirement instanceof Constraint) { From aa585772413218154084b9cb4a8e36c02f29201c Mon Sep 17 00:00:00 2001 From: dev-craftec <89782875+dev-craftec@users.noreply.github.com> Date: Fri, 23 May 2025 10:57:00 +0200 Subject: [PATCH 02/15] Update AbstractScalarParam.php Support php <8.0 --- Controller/Annotations/AbstractScalarParam.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Controller/Annotations/AbstractScalarParam.php b/Controller/Annotations/AbstractScalarParam.php index cf8968724..92b512ff1 100644 --- a/Controller/Annotations/AbstractScalarParam.php +++ b/Controller/Annotations/AbstractScalarParam.php @@ -42,8 +42,8 @@ public function getConstraints() $constraints[] = $this->requirements; } elseif (is_scalar($this->requirements)) { $constraints[] = new Regex( - pattern: '#^(?:'.$this->requirements.')$#xsu', - message: sprintf( + '#^(?:'.$this->requirements.')$#xsu', + sprintf( 'Parameter \'%s\' value, does not match requirements \'%s\'', $this->getName(), $this->requirements @@ -51,8 +51,8 @@ public function getConstraints() ); } elseif (is_array($this->requirements) && isset($this->requirements['rule']) && $this->requirements['error_message']) { $constraints[] = new Regex( - pattern: '#^(?:'.$this->requirements['rule'].')$#xsu', - message: $this->requirements['error_message'], + '#^(?:'.$this->requirements['rule'].')$#xsu', + $this->requirements['error_message'], ); } elseif (is_array($this->requirements)) { foreach ($this->requirements as $index => $requirement) { From a0b160a7fb041ce036cefa69fb0d559194e3a5ee Mon Sep 17 00:00:00 2001 From: Thijs-jan Veldhuizen Date: Wed, 23 Jul 2025 10:18:51 +0200 Subject: [PATCH 03/15] Fix deprecations in symfony/validator, including the fix in #2417 Fixes #2416 --- .../Annotations/AbstractScalarParam.php | 25 +++++++++++-------- Controller/Annotations/FileParam.php | 10 +++++--- .../Annotations/AbstractScalarParamTest.php | 4 +-- .../Controller/Annotations/FileParamTest.php | 16 ++++++------ 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Controller/Annotations/AbstractScalarParam.php b/Controller/Annotations/AbstractScalarParam.php index 5243f48c1..646f32388 100644 --- a/Controller/Annotations/AbstractScalarParam.php +++ b/Controller/Annotations/AbstractScalarParam.php @@ -41,19 +41,19 @@ public function getConstraints() if ($this->requirements instanceof Constraint) { $constraints[] = $this->requirements; } elseif (is_scalar($this->requirements)) { - $constraints[] = new Regex([ - 'pattern' => '#^(?:'.$this->requirements.')$#xsu', - 'message' => sprintf( + $constraints[] = new Regex( + '#^(?:'.$this->requirements.')$#xsu', + sprintf( 'Parameter \'%s\' value, does not match requirements \'%s\'', $this->getName(), $this->requirements ), - ]); + ); } elseif (is_array($this->requirements) && isset($this->requirements['rule']) && $this->requirements['error_message']) { - $constraints[] = new Regex([ - 'pattern' => '#^(?:'.$this->requirements['rule'].')$#xsu', - 'message' => $this->requirements['error_message'], - ]); + $constraints[] = new Regex( + '#^(?:'.$this->requirements['rule'].')$#xsu', + $this->requirements['error_message'], + ); } elseif (is_array($this->requirements)) { foreach ($this->requirements as $index => $requirement) { if ($requirement instanceof Constraint) { @@ -75,9 +75,12 @@ public function getConstraints() // If the user wants to map the value, apply all constraints to every // value of the map if ($this->map) { - $constraints = [ - new All(['constraints' => $constraints]), - ]; + if ([] !== $constraints) { + $constraints = [ + new All($constraints), + ]; + } + if (false === $this->nullable) { $constraints[] = new NotNull(); } diff --git a/Controller/Annotations/FileParam.php b/Controller/Annotations/FileParam.php index 55e624db3..8b157475f 100644 --- a/Controller/Annotations/FileParam.php +++ b/Controller/Annotations/FileParam.php @@ -79,15 +79,19 @@ public function getConstraints() $options = is_array($this->requirements) ? $this->requirements : []; if ($this->image) { - $constraints[] = new Image($options); + $constraint = new Image(); } else { - $constraints[] = new File($options); + $constraint = new File(); } + foreach ($options as $name => $value) { + $constraint->$name = $value; + } + $constraints[] = $constraint; // If the user wants to map the value if ($this->map) { $constraints = [ - new All(['constraints' => $constraints]), + new All($constraints), ]; } diff --git a/Tests/Controller/Annotations/AbstractScalarParamTest.php b/Tests/Controller/Annotations/AbstractScalarParamTest.php index b5d35894f..03e7391f6 100644 --- a/Tests/Controller/Annotations/AbstractScalarParamTest.php +++ b/Tests/Controller/Annotations/AbstractScalarParamTest.php @@ -133,8 +133,6 @@ public function testArrayWithNoConstraintsDoesNotCreateInvalidConstraint() { $this->param->nullable = true; $this->param->map = true; - $this->assertEquals([new All([ - 'constraints' => [], - ])], $this->param->getConstraints()); + $this->assertEquals([], $this->param->getConstraints()); } } diff --git a/Tests/Controller/Annotations/FileParamTest.php b/Tests/Controller/Annotations/FileParamTest.php index 81f8bdd77..fe7773a71 100644 --- a/Tests/Controller/Annotations/FileParamTest.php +++ b/Tests/Controller/Annotations/FileParamTest.php @@ -75,19 +75,19 @@ public function testComplexRequirements() public function testFileRequirements() { $this->param->nullable = true; - $this->param->requirements = $requirements = ['mimeTypes' => 'application/json']; + $this->param->requirements = ['mimeTypes' => 'application/json']; $this->assertEquals([ - new File($requirements), + new File(null, null, null, 'application/json'), ], $this->param->getConstraints()); } public function testImageRequirements() { $this->param->image = true; - $this->param->requirements = $requirements = ['mimeTypes' => 'image/gif']; + $this->param->requirements = ['mimeTypes' => ['image/*']]; $this->assertEquals([ new NotNull(), - new Image($requirements), + new Image(null, null, null, ['image/*']), ], $this->param->getConstraints()); } @@ -95,20 +95,20 @@ public function testImageConstraintsTransformWhenParamIsAnArray() { $this->param->image = true; $this->param->map = true; - $this->param->requirements = $requirements = ['mimeTypes' => 'image/gif']; + $this->param->requirements = ['mimeTypes' => ['image/*']]; $this->assertEquals([new All([ new NotNull(), - new Image($requirements), + new Image(null, null, null, ['image/*']), ])], $this->param->getConstraints()); } public function testFileConstraintsWhenParamIsAnArray() { $this->param->map = true; - $this->param->requirements = $requirements = ['mimeTypes' => 'application/pdf']; + $this->param->requirements = ['mimeTypes' => 'application/pdf']; $this->assertEquals([new All([ new NotNull(), - new File($requirements), + new File(null, null, null, 'application/pdf'), ])], $this->param->getConstraints()); } } From f3e60581d75c00357abe77d2fb5553ad6ed7483c Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Thu, 20 Nov 2025 20:38:13 +0100 Subject: [PATCH 04/15] Fix MimeTypeTest for Symfony 7.4 --- Tests/EventListener/MimeTypeListenerTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Tests/EventListener/MimeTypeListenerTest.php b/Tests/EventListener/MimeTypeListenerTest.php index ba2e7097f..b70ac4658 100644 --- a/Tests/EventListener/MimeTypeListenerTest.php +++ b/Tests/EventListener/MimeTypeListenerTest.php @@ -26,7 +26,7 @@ class MimeTypeListenerTest extends TestCase { public function testOnKernelRequest() { - $listener = new MimeTypeListener(['jsonp' => ['application/javascript+jsonp']]); + $listener = new MimeTypeListener(['jsonp_1' => ['application/javascript+jsonp']]); $request = new Request(); $event = $this->getMockBuilder(RequestEvent::class) @@ -35,11 +35,11 @@ public function testOnKernelRequest() ->method('getRequest') ->will($this->returnValue($request)); - $this->assertNull($request->getMimeType('jsonp')); + $this->assertNull($request->getMimeType('jsonp_1')); $listener->onKernelRequest($event); - $this->assertNull($request->getMimeType('jsonp')); + $this->assertNull($request->getMimeType('jsonp_1')); $event->expects($this->once()) ->method('isMainRequest') @@ -47,12 +47,12 @@ public function testOnKernelRequest() $listener->onKernelRequest($event); - $this->assertEquals('application/javascript+jsonp', $request->getMimeType('jsonp')); + $this->assertEquals('application/javascript+jsonp', $request->getMimeType('jsonp_1')); } public function testOnKernelRequestNoZone() { - $listener = new MimeTypeListener(['soap' => ['application/soap+xml']]); + $listener = new MimeTypeListener(['jsonp_2' => ['application/javascript+jsonp']]); $request = new Request(); $request->attributes->set(FOSRestBundle::ZONE_ATTRIBUTE, false); @@ -68,12 +68,12 @@ public function testOnKernelRequestNoZone() $listener->onKernelRequest($event); - $this->assertNull($request->getMimeType('soap')); + $this->assertNull($request->getMimeType('jsonp_2')); } public function testOnKernelRequestWithZone() { - $listener = new MimeTypeListener(['soap' => ['application/soap+xml']]); + $listener = new MimeTypeListener(['jsonp_3' => ['application/javascript+jsonp']]); $request = new Request(); $request->attributes->set(FOSRestBundle::ZONE_ATTRIBUTE, true); @@ -89,6 +89,6 @@ public function testOnKernelRequestWithZone() $listener->onKernelRequest($event); - $this->assertEquals('application/soap+xml', $request->getMimeType('soap')); + $this->assertEquals('application/javascript+jsonp', $request->getMimeType('jsonp_3')); } } From 115b81801062c10a7fcb16c1299560fda965dea0 Mon Sep 17 00:00:00 2001 From: HypeMC Date: Tue, 18 Nov 2025 19:34:30 +0100 Subject: [PATCH 05/15] Don't use deprecated `#[Route]` methods --- Controller/Annotations/Route.php | 6 +++++- Tests/Controller/Annotations/RouteTest.php | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Controller/Annotations/Route.php b/Controller/Annotations/Route.php index b3682e875..caac132a5 100644 --- a/Controller/Annotations/Route.php +++ b/Controller/Annotations/Route.php @@ -123,7 +123,11 @@ public function __construct( ); } - if (!$this->getMethods()) { + if (isset($this->methods)) { + if (!$this->methods) { + $this->methods = (array) $this->getMethod(); + } + } elseif (!$this->getMethods()) { $this->setMethods((array) $this->getMethod()); } } diff --git a/Tests/Controller/Annotations/RouteTest.php b/Tests/Controller/Annotations/RouteTest.php index 394e72c1e..7ee9f6c57 100644 --- a/Tests/Controller/Annotations/RouteTest.php +++ b/Tests/Controller/Annotations/RouteTest.php @@ -41,14 +41,16 @@ public function testCanInstantiate() $condition ); - $this->assertEquals($path, $route->getPath()); - $this->assertEquals($name, $route->getName()); - $this->assertEquals($requirements, $route->getRequirements()); - $this->assertEquals($options, $route->getOptions()); - $this->assertEquals($defaults, $route->getDefaults()); - $this->assertEquals($host, $route->getHost()); - $this->assertEquals($methods, $route->getMethods()); - $this->assertEquals($schemes, $route->getSchemes()); - $this->assertEquals($condition, $route->getCondition()); + $isPublic = isset($route->methods); + + $this->assertEquals($path, $isPublic ? $route->path : $route->getPath()); + $this->assertEquals($name, $isPublic ? $route->name : $route->getName()); + $this->assertEquals($requirements, $isPublic ? $route->requirements : $route->getRequirements()); + $this->assertEquals($options, $isPublic ? $route->options : $route->getOptions()); + $this->assertEquals($defaults, $isPublic ? $route->defaults : $route->getDefaults()); + $this->assertEquals($host, $isPublic ? $route->host : $route->getHost()); + $this->assertEquals($methods, $isPublic ? $route->methods : $route->getMethods()); + $this->assertEquals($schemes, $isPublic ? $route->schemes : $route->getSchemes()); + $this->assertEquals($condition, $isPublic ? $route->condition : $route->getCondition()); } } From a78c1270546a500910bd733b467d2d1ed2376f8e Mon Sep 17 00:00:00 2001 From: W0rma Date: Wed, 29 Oct 2025 08:50:21 +0100 Subject: [PATCH 06/15] Switch to php for service configurations Using xml is deprecated in symfony 7.4 --- DependencyInjection/FOSRestExtension.php | 52 +++++++++---------- Resources/config/allowed_methods_listener.php | 21 ++++++++ Resources/config/allowed_methods_listener.xml | 22 -------- Resources/config/body_listener.php | 31 +++++++++++ Resources/config/body_listener.xml | 31 ----------- Resources/config/exception.php | 40 ++++++++++++++ Resources/config/exception.xml | 32 ------------ Resources/config/format_listener.php | 15 ++++++ Resources/config/format_listener.xml | 17 ------ Resources/config/forms.php | 15 ++++++ Resources/config/forms.xml | 14 ----- Resources/config/mime_type_listener.php | 12 +++++ Resources/config/mime_type_listener.xml | 15 ------ Resources/config/param_fetcher_listener.php | 15 ++++++ Resources/config/param_fetcher_listener.xml | 16 ------ Resources/config/request.php | 22 ++++++++ Resources/config/request.xml | 24 --------- .../config/request_body_param_converter.php | 18 +++++++ .../config/request_body_param_converter.xml | 19 ------- Resources/config/serializer.php | 25 +++++++++ Resources/config/serializer.xml | 22 -------- Resources/config/versioning.php | 43 +++++++++++++++ Resources/config/versioning.xml | 35 ------------- Resources/config/view.php | 20 +++++++ Resources/config/view.xml | 20 ------- Resources/config/view_response_listener.php | 16 ++++++ Resources/config/view_response_listener.xml | 17 ------ Resources/config/zone_matcher_listener.php | 11 ++++ Resources/config/zone_matcher_listener.xml | 15 ------ .../Functional/app/Configuration/routing.yml | 4 +- 30 files changed, 332 insertions(+), 327 deletions(-) create mode 100644 Resources/config/allowed_methods_listener.php delete mode 100644 Resources/config/allowed_methods_listener.xml create mode 100644 Resources/config/body_listener.php delete mode 100644 Resources/config/body_listener.xml create mode 100644 Resources/config/exception.php delete mode 100644 Resources/config/exception.xml create mode 100644 Resources/config/format_listener.php delete mode 100644 Resources/config/format_listener.xml create mode 100644 Resources/config/forms.php delete mode 100644 Resources/config/forms.xml create mode 100644 Resources/config/mime_type_listener.php delete mode 100644 Resources/config/mime_type_listener.xml create mode 100644 Resources/config/param_fetcher_listener.php delete mode 100644 Resources/config/param_fetcher_listener.xml create mode 100644 Resources/config/request.php delete mode 100644 Resources/config/request.xml create mode 100644 Resources/config/request_body_param_converter.php delete mode 100644 Resources/config/request_body_param_converter.xml create mode 100644 Resources/config/serializer.php delete mode 100644 Resources/config/serializer.xml create mode 100644 Resources/config/versioning.php delete mode 100644 Resources/config/versioning.xml create mode 100644 Resources/config/view.php delete mode 100644 Resources/config/view.xml create mode 100644 Resources/config/view_response_listener.php delete mode 100644 Resources/config/view_response_listener.xml create mode 100644 Resources/config/zone_matcher_listener.php delete mode 100644 Resources/config/zone_matcher_listener.xml diff --git a/DependencyInjection/FOSRestExtension.php b/DependencyInjection/FOSRestExtension.php index 3f87d7b04..965bd3110 100644 --- a/DependencyInjection/FOSRestExtension.php +++ b/DependencyInjection/FOSRestExtension.php @@ -23,7 +23,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\LogicException; -use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\HttpFoundation\ChainRequestMatcher; @@ -51,10 +51,10 @@ public function getConfiguration(array $config, ContainerBuilder $container): Co protected function loadInternal(array $mergedConfig, ContainerBuilder $container): void { - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('view.xml'); - $loader->load('request.xml'); - $loader->load('serializer.xml'); + $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('view.php'); + $loader->load('request.php'); + $loader->load('serializer.php'); foreach ($mergedConfig['service'] as $key => $service) { if ('validator' === $service && empty($mergedConfig['body_converter']['validate'])) { @@ -86,10 +86,10 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container $this->loadSerializer($mergedConfig, $container); } - private function loadForm(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadForm(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if (!empty($config['disable_csrf_role'])) { - $loader->load('forms.xml'); + $loader->load('forms.php'); $definition = $container->getDefinition('fos_rest.form.extension.csrf_disable'); $definition->replaceArgument(1, $config['disable_csrf_role']); @@ -97,7 +97,7 @@ private function loadForm(array $config, XmlFileLoader $loader, ContainerBuilder } } - private function loadAllowedMethodsListener(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadAllowedMethodsListener(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if ($this->isConfigEnabled($container, $config['allowed_methods_listener'])) { if (!empty($config['allowed_methods_listener']['service'])) { @@ -105,16 +105,16 @@ private function loadAllowedMethodsListener(array $config, XmlFileLoader $loader $service->clearTag('kernel.event_listener'); } - $loader->load('allowed_methods_listener.xml'); + $loader->load('allowed_methods_listener.php'); $container->getDefinition('fos_rest.allowed_methods_loader')->replaceArgument(1, $config['cache_dir']); } } - private function loadBodyListener(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadBodyListener(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if ($this->isConfigEnabled($container, $config['body_listener'])) { - $loader->load('body_listener.xml'); + $loader->load('body_listener.php'); $service = $container->getDefinition('fos_rest.body_listener'); @@ -146,10 +146,10 @@ private function loadBodyListener(array $config, XmlFileLoader $loader, Containe } } - private function loadFormatListener(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadFormatListener(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if ($this->isConfigEnabled($container, $config['format_listener']) && !empty($config['format_listener']['rules'])) { - $loader->load('format_listener.xml'); + $loader->load('format_listener.php'); if (!empty($config['format_listener']['service'])) { $service = $container->getDefinition('fos_rest.format_listener'); @@ -163,10 +163,10 @@ private function loadFormatListener(array $config, XmlFileLoader $loader, Contai } } - private function loadVersioning(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadVersioning(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if ($this->isConfigEnabled($container, $config['versioning'])) { - $loader->load('versioning.xml'); + $loader->load('versioning.php'); $versionListener = $container->getDefinition('fos_rest.versioning.listener'); $versionListener->replaceArgument(1, $config['versioning']['default_version']); @@ -194,14 +194,14 @@ private function loadVersioning(array $config, XmlFileLoader $loader, ContainerB } } - private function loadParamFetcherListener(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadParamFetcherListener(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if ($this->isConfigEnabled($container, $config['param_fetcher_listener'])) { if (!class_exists(Constraint::class)) { throw new \LogicException('Enabling the fos_rest.param_fetcher_listener option when the Symfony Validator component is not installed is not supported. Try installing the symfony/validator package.'); } - $loader->load('param_fetcher_listener.xml'); + $loader->load('param_fetcher_listener.php'); if (!empty($config['param_fetcher_listener']['service'])) { $service = $container->getDefinition('fos_rest.param_fetcher_listener'); @@ -214,7 +214,7 @@ private function loadParamFetcherListener(array $config, XmlFileLoader $loader, } } - private function loadBodyConverter(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadBodyConverter(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if (!$this->isConfigEnabled($container, $config['body_converter'])) { return; @@ -224,14 +224,14 @@ private function loadBodyConverter(array $config, XmlFileLoader $loader, Contain throw new LogicException('To use the request body param converter, the "sensio/framework-extra-bundle" package is required.'); } - $loader->load('request_body_param_converter.xml'); + $loader->load('request_body_param_converter.php'); if (!empty($config['body_converter']['validation_errors_argument'])) { $container->getDefinition('fos_rest.converter.request_body')->replaceArgument(4, $config['body_converter']['validation_errors_argument']); } } - private function loadView(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadView(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if (!empty($config['view']['jsonp_handler'])) { $handler = new ChildDefinition($config['service']['view_handler']); @@ -249,7 +249,7 @@ private function loadView(array $config, XmlFileLoader $loader, ContainerBuilder } if ($this->isConfigEnabled($container, $config['view']['mime_types'])) { - $loader->load('mime_type_listener.xml'); + $loader->load('mime_type_listener.php'); if (!empty($config['mime_type_listener']['service'])) { $service = $container->getDefinition('fos_rest.mime_type_listener'); @@ -260,7 +260,7 @@ private function loadView(array $config, XmlFileLoader $loader, ContainerBuilder } if ($this->isConfigEnabled($container, $config['view']['view_response_listener'])) { - $loader->load('view_response_listener.xml'); + $loader->load('view_response_listener.php'); $service = $container->getDefinition('fos_rest.view_response_listener'); if (!empty($config['view_response_listener']['service'])) { @@ -298,10 +298,10 @@ private function loadView(array $config, XmlFileLoader $loader, ContainerBuilder ]); } - private function loadException(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadException(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if ($this->isConfigEnabled($container, $config['exception'])) { - $loader->load('exception.xml'); + $loader->load('exception.php'); if ($config['exception']['map_exception_codes']) { $container->register('fos_rest.exception.response_status_code_listener', ResponseStatusCodeListener::class) @@ -373,10 +373,10 @@ private function loadSerializer(array $config, ContainerBuilder $container): voi $viewHandler->addArgument($options); } - private function loadZoneMatcherListener(array $config, XmlFileLoader $loader, ContainerBuilder $container): void + private function loadZoneMatcherListener(array $config, PhpFileLoader $loader, ContainerBuilder $container): void { if (!empty($config['zone'])) { - $loader->load('zone_matcher_listener.xml'); + $loader->load('zone_matcher_listener.php'); $zoneMatcherListener = $container->getDefinition('fos_rest.zone_matcher_listener'); foreach ($config['zone'] as $zone) { diff --git a/Resources/config/allowed_methods_listener.php b/Resources/config/allowed_methods_listener.php new file mode 100644 index 000000000..f5209a2fd --- /dev/null +++ b/Resources/config/allowed_methods_listener.php @@ -0,0 +1,21 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.allowed_methods_listener', \FOS\RestBundle\EventListener\AllowedMethodsListener::class) + ->args([service('fos_rest.allowed_methods_loader')]) + ->tag('kernel.event_listener', ['event' => 'kernel.response', 'method' => 'onKernelResponse']); + + $services->set('fos_rest.allowed_methods_loader', \FOS\RestBundle\Response\AllowedMethodsLoader\AllowedMethodsRouterLoader::class) + ->private() + ->args([ + service('router'), + '', + '%kernel.debug%', + ]) + ->tag('kernel.cache_warmer'); +}; diff --git a/Resources/config/allowed_methods_listener.xml b/Resources/config/allowed_methods_listener.xml deleted file mode 100644 index 13524faf7..000000000 --- a/Resources/config/allowed_methods_listener.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - %kernel.debug% - - - - diff --git a/Resources/config/body_listener.php b/Resources/config/body_listener.php new file mode 100644 index 000000000..52ed2a9cd --- /dev/null +++ b/Resources/config/body_listener.php @@ -0,0 +1,31 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.normalizer.camel_keys', \FOS\RestBundle\Normalizer\CamelKeysNormalizer::class); + + $services->set('fos_rest.normalizer.camel_keys_with_leading_underscore', \FOS\RestBundle\Normalizer\CamelKeysNormalizerWithLeadingUnderscore::class); + + $services->set('fos_rest.decoder.json', \FOS\RestBundle\Decoder\JsonDecoder::class); + + $services->set('fos_rest.decoder.jsontoform', \FOS\RestBundle\Decoder\JsonToFormDecoder::class); + + $services->set('fos_rest.decoder.xml', \FOS\RestBundle\Decoder\XmlDecoder::class); + + $services->set('fos_rest.decoder_provider', \FOS\RestBundle\Decoder\ContainerDecoderProvider::class) + ->args([ + service('service_container'), + [], + ]); + + $services->set('fos_rest.body_listener', \FOS\RestBundle\EventListener\BodyListener::class) + ->args([ + service('fos_rest.decoder_provider'), + '', // exception on unsupported content type + ]) + ->tag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'onKernelRequest', 'priority' => 10]); +}; diff --git a/Resources/config/body_listener.xml b/Resources/config/body_listener.xml deleted file mode 100644 index 1ee5facb7..000000000 --- a/Resources/config/body_listener.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Resources/config/exception.php b/Resources/config/exception.php new file mode 100644 index 000000000..8ffd09fa3 --- /dev/null +++ b/Resources/config/exception.php @@ -0,0 +1,40 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.exception.codes_map', \FOS\RestBundle\Util\ExceptionValueMap::class) + ->private() + ->args([ + [], // exception codes + ]); + + $services->set('fos_rest.exception.messages_map', \FOS\RestBundle\Util\ExceptionValueMap::class) + ->private() + ->args([ + [], // exception messages + ]); + + $services->set('fos_rest.serializer.flatten_exception_handler', \FOS\RestBundle\Serializer\Normalizer\FlattenExceptionHandler::class) + ->private() + ->args([ + service('fos_rest.exception.codes_map'), + service('fos_rest.exception.messages_map'), + '', // show exception message + '', // render according to RFC 7807 + ]) + ->tag('jms_serializer.subscribing_handler'); + + $services->set('fos_rest.serializer.flatten_exception_normalizer', \FOS\RestBundle\Serializer\Normalizer\FlattenExceptionNormalizer::class) + ->private() + ->args([ + service('fos_rest.exception.codes_map'), // exception messages + service('fos_rest.exception.messages_map'), // exception messages + '', // show exception message + '', // render according to RFC 7807 + ]) + ->tag('serializer.normalizer', ['priority' => -10]); +}; diff --git a/Resources/config/exception.xml b/Resources/config/exception.xml deleted file mode 100644 index d33d22d73..000000000 --- a/Resources/config/exception.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Resources/config/format_listener.php b/Resources/config/format_listener.php new file mode 100644 index 000000000..894b9ebe5 --- /dev/null +++ b/Resources/config/format_listener.php @@ -0,0 +1,15 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.format_listener', \FOS\RestBundle\EventListener\FormatListener::class) + ->args([service('fos_rest.format_negotiator')]) + ->tag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'onKernelRequest', 'priority' => 34]); + + $services->set('fos_rest.format_negotiator', \FOS\RestBundle\Negotiation\FormatNegotiator::class) + ->args([service('request_stack')]); +}; diff --git a/Resources/config/format_listener.xml b/Resources/config/format_listener.xml deleted file mode 100644 index d4ea1a965..000000000 --- a/Resources/config/format_listener.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/Resources/config/forms.php b/Resources/config/forms.php new file mode 100644 index 000000000..18b448d3c --- /dev/null +++ b/Resources/config/forms.php @@ -0,0 +1,15 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.form.extension.csrf_disable', \FOS\RestBundle\Form\Extension\DisableCSRFExtension::class) + ->args([ + service('security.token_storage'), + '', // disable CSRF role + service('security.authorization_checker'), + ]); +}; diff --git a/Resources/config/forms.xml b/Resources/config/forms.xml deleted file mode 100644 index aede2bf94..000000000 --- a/Resources/config/forms.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/Resources/config/mime_type_listener.php b/Resources/config/mime_type_listener.php new file mode 100644 index 000000000..22e351a6c --- /dev/null +++ b/Resources/config/mime_type_listener.php @@ -0,0 +1,12 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.mime_type_listener', \FOS\RestBundle\EventListener\MimeTypeListener::class) + ->args([[]]) + ->tag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'onKernelRequest', 'priority' => 200]); +}; diff --git a/Resources/config/mime_type_listener.xml b/Resources/config/mime_type_listener.xml deleted file mode 100644 index 4de4df290..000000000 --- a/Resources/config/mime_type_listener.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - diff --git a/Resources/config/param_fetcher_listener.php b/Resources/config/param_fetcher_listener.php new file mode 100644 index 000000000..0665a9aa5 --- /dev/null +++ b/Resources/config/param_fetcher_listener.php @@ -0,0 +1,15 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.param_fetcher_listener', \FOS\RestBundle\EventListener\ParamFetcherListener::class) + ->args([ + service('fos_rest.request.param_fetcher'), + false, + ]) + ->tag('kernel.event_listener', ['event' => 'kernel.controller', 'method' => 'onKernelController', 'priority' => 5]); +}; diff --git a/Resources/config/param_fetcher_listener.xml b/Resources/config/param_fetcher_listener.xml deleted file mode 100644 index 042757196..000000000 --- a/Resources/config/param_fetcher_listener.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - false - - - - diff --git a/Resources/config/request.php b/Resources/config/request.php new file mode 100644 index 000000000..0005eb380 --- /dev/null +++ b/Resources/config/request.php @@ -0,0 +1,22 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.request.param_fetcher', \FOS\RestBundle\Request\ParamFetcher::class) + ->args([ + service('service_container'), + service('fos_rest.request.param_fetcher.reader'), + service('request_stack'), + service('validator')->nullOnInvalid(), + ]); + + $services->alias(\FOS\RestBundle\Request\ParamFetcherInterface::class, 'fos_rest.request.param_fetcher'); + + $services->set('fos_rest.request.param_fetcher.reader', \FOS\RestBundle\Request\ParamReader::class) + ->private() + ->args([service('annotation_reader')->nullOnInvalid()]); +}; diff --git a/Resources/config/request.xml b/Resources/config/request.xml deleted file mode 100644 index d55542764..000000000 --- a/Resources/config/request.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/Resources/config/request_body_param_converter.php b/Resources/config/request_body_param_converter.php new file mode 100644 index 000000000..7457acf0c --- /dev/null +++ b/Resources/config/request_body_param_converter.php @@ -0,0 +1,18 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.converter.request_body', \FOS\RestBundle\Request\RequestBodyParamConverter::class) + ->args([ + service('fos_rest.serializer'), + [], // serializer exclusion strategy groups + '', // serializer exclusion strategy version + service('fos_rest.validator')->ignoreOnInvalid(), + null, // request body validation errors argument + ]) + ->tag('request.param_converter', ['converter' => 'fos_rest.request_body', 'priority' => -50]); +}; diff --git a/Resources/config/request_body_param_converter.xml b/Resources/config/request_body_param_converter.xml deleted file mode 100644 index 5710bbc1f..000000000 --- a/Resources/config/request_body_param_converter.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - null - - - - - diff --git a/Resources/config/serializer.php b/Resources/config/serializer.php new file mode 100644 index 000000000..1e6203176 --- /dev/null +++ b/Resources/config/serializer.php @@ -0,0 +1,25 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.serializer.jms', \FOS\RestBundle\Serializer\JMSSerializerAdapter::class) + ->private() + ->args([ + service('jms_serializer.serializer'), + service('jms_serializer.serialization_context_factory'), + service('jms_serializer.deserialization_context_factory'), + ]); + + $services->set('fos_rest.serializer.symfony', \FOS\RestBundle\Serializer\SymfonySerializerAdapter::class) + ->private() + ->args([service('serializer')]); + + // Normalizes FormInterface when using the symfony serializer + $services->set('fos_rest.serializer.form_error_normalizer', \FOS\RestBundle\Serializer\Normalizer\FormErrorNormalizer::class) + ->private() + ->tag('serializer.normalizer', ['priority' => -10]); +}; diff --git a/Resources/config/serializer.xml b/Resources/config/serializer.xml deleted file mode 100644 index bf4fdb161..000000000 --- a/Resources/config/serializer.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/Resources/config/versioning.php b/Resources/config/versioning.php new file mode 100644 index 000000000..23d3e65fb --- /dev/null +++ b/Resources/config/versioning.php @@ -0,0 +1,43 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.versioning.listener', \FOS\RestBundle\EventListener\VersionListener::class) + ->args([ + service('fos_rest.versioning.chain_resolver'), + '', // default media type version + ]) + ->tag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'onKernelRequest', 'priority' => 33]); + + $services->set('fos_rest.versioning.exclusion_listener', \FOS\RestBundle\EventListener\VersionExclusionListener::class) + ->args([service('fos_rest.view_handler')]) + ->tag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'onKernelRequest', 'priority' => 31]); + + $services->set('fos_rest.versioning.chain_resolver', \FOS\RestBundle\Version\ChainVersionResolver::class) + ->private() + ->args([ + [], // resolvers + ]); + + $services->set('fos_rest.versioning.header_resolver', \FOS\RestBundle\Version\Resolver\HeaderVersionResolver::class) + ->private() + ->args([ + '', // request header name + ]); + + $services->set('fos_rest.versioning.media_type_resolver', \FOS\RestBundle\Version\Resolver\MediaTypeVersionResolver::class) + ->private() + ->args([ + '', // regex + ]); + + $services->set('fos_rest.versioning.query_parameter_resolver', \FOS\RestBundle\Version\Resolver\QueryParameterVersionResolver::class) + ->private() + ->args([ + '', // request parameter name + ]); +}; diff --git a/Resources/config/versioning.xml b/Resources/config/versioning.xml deleted file mode 100644 index 5071220eb..000000000 --- a/Resources/config/versioning.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Resources/config/view.php b/Resources/config/view.php new file mode 100644 index 000000000..9f4fed397 --- /dev/null +++ b/Resources/config/view.php @@ -0,0 +1,20 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.view_handler.default', \FOS\RestBundle\View\ViewHandler::class) + ->private() + ->tag('kernel.reset', ['method' => 'reset']); + + $services->alias(\FOS\RestBundle\View\ViewHandlerInterface::class, 'fos_rest.view_handler'); + + $services->set('fos_rest.view_handler.jsonp', \FOS\RestBundle\View\JsonpHandler::class) + ->private() + ->args([ + '', // JSONP callback parameter + ]); +}; diff --git a/Resources/config/view.xml b/Resources/config/view.xml deleted file mode 100644 index 996327ff1..000000000 --- a/Resources/config/view.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/Resources/config/view_response_listener.php b/Resources/config/view_response_listener.php new file mode 100644 index 000000000..42e421229 --- /dev/null +++ b/Resources/config/view_response_listener.php @@ -0,0 +1,16 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.view_response_listener', \FOS\RestBundle\EventListener\ViewResponseListener::class) + ->args([ + service('fos_rest.view_handler'), + '', // force view + service('annotation_reader')->nullOnInvalid(), + ]) + ->tag('kernel.event_subscriber'); +}; diff --git a/Resources/config/view_response_listener.xml b/Resources/config/view_response_listener.xml deleted file mode 100644 index 5ea9b7484..000000000 --- a/Resources/config/view_response_listener.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/Resources/config/zone_matcher_listener.php b/Resources/config/zone_matcher_listener.php new file mode 100644 index 000000000..6d1bf7587 --- /dev/null +++ b/Resources/config/zone_matcher_listener.php @@ -0,0 +1,11 @@ +services(); + $parameters = $container->parameters(); + + $services->set('fos_rest.zone_matcher_listener', \FOS\RestBundle\EventListener\ZoneMatcherListener::class) + ->tag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'onKernelRequest', 'priority' => 248]); +}; diff --git a/Resources/config/zone_matcher_listener.xml b/Resources/config/zone_matcher_listener.xml deleted file mode 100644 index 6a18566e1..000000000 --- a/Resources/config/zone_matcher_listener.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - diff --git a/Tests/Functional/app/Configuration/routing.yml b/Tests/Functional/app/Configuration/routing.yml index 3e79dc212..aa539064b 100644 --- a/Tests/Functional/app/Configuration/routing.yml +++ b/Tests/Functional/app/Configuration/routing.yml @@ -1,7 +1,7 @@ _wdt: - resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" + resource: "@WebProfilerBundle/Resources/config/routing/wdt.php" prefix: /_wdt _profiler: - resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" + resource: "@WebProfilerBundle/Resources/config/routing/profiler.php" prefix: /_profiler From 02d0e33d1b0380ac5749ff4d933250ec0fbbdb3a Mon Sep 17 00:00:00 2001 From: W0rma Date: Sun, 21 Dec 2025 09:09:27 +0100 Subject: [PATCH 07/15] Fix usage of deprecated method Request::get() --- EventListener/AllowedMethodsListener.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EventListener/AllowedMethodsListener.php b/EventListener/AllowedMethodsListener.php index fa88c8a78..ca10b141e 100644 --- a/EventListener/AllowedMethodsListener.php +++ b/EventListener/AllowedMethodsListener.php @@ -41,10 +41,10 @@ public function onKernelResponse(ResponseEvent $event): void $allowedMethods = $this->loader->getAllowedMethods(); - if (isset($allowedMethods[$event->getRequest()->get('_route')])) { + if (isset($allowedMethods[$event->getRequest()->attributes->get('_route')])) { $event->getResponse() ->headers - ->set('Allow', implode(', ', $allowedMethods[$event->getRequest()->get('_route')])); + ->set('Allow', implode(', ', $allowedMethods[$event->getRequest()->attributes->get('_route')])); } } } From 13213ab7be5cd7e003731f9eb384d5564fe6bc47 Mon Sep 17 00:00:00 2001 From: W0rma Date: Sun, 21 Dec 2025 09:10:20 +0100 Subject: [PATCH 08/15] Fix deprecated usages of symfony/validator --- .../Annotations/AbstractScalarParamTest.php | 16 ++++++++-------- .../Annotations/IdenticalToRequestParam.php | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Tests/Controller/Annotations/AbstractScalarParamTest.php b/Tests/Controller/Annotations/AbstractScalarParamTest.php index 03e7391f6..1db1e7e4a 100644 --- a/Tests/Controller/Annotations/AbstractScalarParamTest.php +++ b/Tests/Controller/Annotations/AbstractScalarParamTest.php @@ -80,10 +80,10 @@ public function testScalarRequirements() $this->param->requirements = 'foo %bar% %%'; $this->assertEquals([ new NotNull(), - new Regex([ - 'pattern' => '#^(?:foo %bar% %%)$#xsu', - 'message' => "Parameter 'bar' value, does not match requirements 'foo %bar% %%'", - ]), + new Regex( + '#^(?:foo %bar% %%)$#xsu', + "Parameter 'bar' value, does not match requirements 'foo %bar% %%'", + ), ], $this->param->getConstraints()); } @@ -95,10 +95,10 @@ public function testArrayRequirements() ]; $this->assertEquals([ new NotNull(), - new Regex([ - 'pattern' => '#^(?:foo)$#xsu', - 'message' => 'bar', - ]), + new Regex( + '#^(?:foo)$#xsu', + 'bar', + ), ], $this->param->getConstraints()); } diff --git a/Tests/Fixtures/Annotations/IdenticalToRequestParam.php b/Tests/Fixtures/Annotations/IdenticalToRequestParam.php index 45b1f97e9..0935c605f 100644 --- a/Tests/Fixtures/Annotations/IdenticalToRequestParam.php +++ b/Tests/Fixtures/Annotations/IdenticalToRequestParam.php @@ -11,6 +11,7 @@ namespace FOS\RestBundle\Tests\Fixtures\Annotations; +use Composer\InstalledVersions; use FOS\RestBundle\Controller\Annotations\RequestParam; use Symfony\Component\Validator\Constraints\IdenticalTo; @@ -41,6 +42,21 @@ public function __construct( bool $nullable = false, bool $allowBlank = true ) { - parent::__construct($name, $key, null !== $identicalTo ? new IdenticalTo($identicalTo) : null, $default, $description, $incompatibles, $strict, $map, $nullable, $allowBlank); + $validatorSupportsArrayConfig = true; + if (class_exists(InstalledVersions::class)) { + $validatorVersion = InstalledVersions::getVersion('symfony/validator'); + + $validatorSupportsArrayConfig = version_compare($validatorVersion, '8.0', '<'); + } + + if (null === $identicalTo) { + $options = null; + } elseif ($validatorSupportsArrayConfig) { + $options = $identicalTo; + } else { + $options = $identicalTo['value']; + } + + parent::__construct($name, $key, null !== $options ? new IdenticalTo($options) : null, $default, $description, $incompatibles, $strict, $map, $nullable, $allowBlank); } } From ce7380cdbbe32c0b5925f22657c54df1d9f91294 Mon Sep 17 00:00:00 2001 From: W0rma Date: Sun, 21 Dec 2025 09:11:56 +0100 Subject: [PATCH 09/15] Add support for symfony 8 --- .github/workflows/continuous-integration.yml | 20 ++++++++++ composer.json | 40 ++++++++++---------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 0a4dd2efe..0958ff52b 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -68,6 +68,26 @@ jobs: can-fail: false symfony-require: "7.0.*" remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later + - php-version: "8.3" + composer-flags: "" + can-fail: false + symfony-require: "7.0.*" + remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later + - php-version: "8.4" + composer-flags: "" + can-fail: false + symfony-require: "7.0.*" + remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later + - php-version: "8.4" + composer-flags: "" + can-fail: false + symfony-require: "7.4.*" + remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later + - php-version: "8.4" + composer-flags: "" + can-fail: false + symfony-require: "8.0.*" + remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later - php-version: "8.3" composer-flags: "" can-fail: true # we don't want to fail the build if we are incompatible with the next (unstable) Symfony version diff --git a/composer.json b/composer.json index 9738ffaca..f60a63f2f 100644 --- a/composer.json +++ b/composer.json @@ -31,14 +31,14 @@ "require": { "php": "^7.4|^8.0", "symfony/config": "^5.4|^6.4|^7.0", - "symfony/dependency-injection": "^5.4|^6.4|^7.0", + "symfony/dependency-injection": "^5.4|^6.4|^7.0|^8.0", "symfony/deprecation-contracts": "^2.1|^3.0", - "symfony/event-dispatcher": "^5.4|^6.4|^7.0", - "symfony/framework-bundle": "^5.4|^6.4|^7.0", - "symfony/http-foundation": "^5.4|^6.4|^7.0", - "symfony/http-kernel": "^5.4|^6.4|^7.0", - "symfony/routing": "^5.4|^6.4|^7.0", - "symfony/security-core": "^5.4|^6.4|^7.0", + "symfony/event-dispatcher": "^5.4|^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^5.4|^6.4|^7.0|^8.0", + "symfony/http-foundation": "^5.4|^6.4|^7.0|^8.0", + "symfony/http-kernel": "^5.4|^6.4|^7.0|^8.0", + "symfony/routing": "^5.4|^6.4|^7.0|^8.0", + "symfony/security-core": "^5.4|^6.4|^7.0|^8.0", "willdurand/jsonp-callback-validator": "^1.0|^2.0", "willdurand/negotiation": "^2.0|^3.0" }, @@ -50,19 +50,19 @@ "psr/http-message": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "sensio/framework-extra-bundle": "^6.1", - "symfony/asset": "^5.4|^6.4|^7.0", - "symfony/browser-kit": "^5.4|^6.4|^7.0", - "symfony/css-selector": "^5.4|^6.4|^7.0", - "symfony/expression-language": "^5.4|^6.4|^7.0", - "symfony/form": "^5.4|^6.4|^7.0", - "symfony/mime": "^5.4|^6.4|^7.0", - "symfony/phpunit-bridge": "^7.0.1", - "symfony/security-bundle": "^5.4|^6.4|^7.0", - "symfony/serializer": "^5.4|^6.4|^7.0", - "symfony/twig-bundle": "^5.4|^6.4|^7.0", - "symfony/validator": "^5.4|^6.4|^7.0", - "symfony/web-profiler-bundle": "^5.4|^6.4|^7.0", - "symfony/yaml": "^5.4|^6.4|^7.0" + "symfony/asset": "^5.4|^6.4|^7.0|^8.0", + "symfony/browser-kit": "^5.4|^6.4|^7.0|^8.0", + "symfony/css-selector": "^5.4|^6.4|^7.0|^8.0", + "symfony/expression-language": "^5.4|^6.4|^7.0|^8.0", + "symfony/form": "^5.4|^6.4|^7.0|^8.0", + "symfony/mime": "^5.4|^6.4|^7.0|^8.0", + "symfony/phpunit-bridge": "^7.0.1|^8.0", + "symfony/security-bundle": "^5.4|^6.4|^7.0|^8.0", + "symfony/serializer": "^5.4|^6.4|^7.0|^8.0", + "symfony/twig-bundle": "^5.4|^6.4|^7.0|^8.0", + "symfony/validator": "^5.4|^6.4|^7.0|^8.0", + "symfony/web-profiler-bundle": "^5.4|^6.4|^7.0|^8.0", + "symfony/yaml": "^5.4|^6.4|^7.0|^8.0" }, "suggest": { "jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended", From d71a83c3ecb45db60fd10e5136db6f21095b91f4 Mon Sep 17 00:00:00 2001 From: W0rma Date: Sat, 20 Dec 2025 21:38:09 +0100 Subject: [PATCH 10/15] Test against PHP 8.5 --- .github/workflows/continuous-integration.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 0958ff52b..e333810fc 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -53,6 +53,10 @@ jobs: composer-flags: "" can-fail: false symfony-require: "6.4.*" + - php-version: "8.5" + composer-flags: "" + can-fail: false + symfony-require: "6.4.*" - php-version: "8.3" composer-flags: "" can-fail: false @@ -83,11 +87,21 @@ jobs: can-fail: false symfony-require: "7.4.*" remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later + - php-version: "8.5" + composer-flags: "" + can-fail: false + symfony-require: "7.4.*" + remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later - php-version: "8.4" composer-flags: "" can-fail: false symfony-require: "8.0.*" remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later + - php-version: "8.5" + composer-flags: "" + can-fail: false + symfony-require: "8.0.*" + remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later - php-version: "8.3" composer-flags: "" can-fail: true # we don't want to fail the build if we are incompatible with the next (unstable) Symfony version @@ -96,6 +110,10 @@ jobs: composer-flags: "" can-fail: true # we don't want to fail the build if we are incompatible with the next (unstable) Symfony version remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later + - php-version: "8.5" + composer-flags: "" + can-fail: true # we don't want to fail the build if we are incompatible with the next (unstable) Symfony version + remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later env: COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} From c7a461514e10b46bb1977f8c549cf25534a5492c Mon Sep 17 00:00:00 2001 From: W0rma Date: Sun, 21 Dec 2025 08:59:39 +0100 Subject: [PATCH 11/15] Fix noop call of deprecated setAccessible() in PHP > 8.0 --- Tests/Negotiation/FormatNegotiatorTest.php | 8 ++++++-- Tests/Request/RequestBodyParamConverterTest.php | 8 ++++++-- Tests/View/ViewHandlerTest.php | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Tests/Negotiation/FormatNegotiatorTest.php b/Tests/Negotiation/FormatNegotiatorTest.php index 0a92a2014..6b89c6d9a 100644 --- a/Tests/Negotiation/FormatNegotiatorTest.php +++ b/Tests/Negotiation/FormatNegotiatorTest.php @@ -112,7 +112,9 @@ public function testGetBestWithPreferExtension() $reflectionClass = new \ReflectionClass(get_class($this->request)); $reflectionProperty = $reflectionClass->getProperty('pathInfo'); - $reflectionProperty->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $reflectionProperty->setAccessible(true); + } $reflectionProperty->setValue($this->request, '/file.json'); // Without extension mime-type in Accept header @@ -135,7 +137,9 @@ public function testGetBestWithPreferExtensionAndUnknownExtension() $reflectionClass = new \ReflectionClass(get_class($this->request)); $reflectionProperty = $reflectionClass->getProperty('pathInfo'); - $reflectionProperty->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $reflectionProperty->setAccessible(true); + } $reflectionProperty->setValue($this->request, '/file.123456789'); $this->request->headers->set('Accept', 'text/html, application/json'); diff --git a/Tests/Request/RequestBodyParamConverterTest.php b/Tests/Request/RequestBodyParamConverterTest.php index b0094c65b..05bf67a03 100644 --- a/Tests/Request/RequestBodyParamConverterTest.php +++ b/Tests/Request/RequestBodyParamConverterTest.php @@ -194,7 +194,9 @@ public function testContextConfiguration() ]; $contextConfigurationMethod = new \ReflectionMethod($converter, 'configureContext'); - $contextConfigurationMethod->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $contextConfigurationMethod->setAccessible(true); + } $contextConfigurationMethod->invoke($converter, $context = new Context(), $options); $expectedContext = new Context(); @@ -225,7 +227,9 @@ public function testValidatorOptionsGetter() ]; $validatorMethod = new \ReflectionMethod($converter, 'getValidatorOptions'); - $validatorMethod->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $validatorMethod->setAccessible(true); + } $this->assertEquals(['groups' => ['foo'], 'traverse' => true, 'deep' => false], $validatorMethod->invoke($converter, $options1)); $this->assertEquals(['groups' => false, 'traverse' => false, 'deep' => true], $validatorMethod->invoke($converter, $options2)); } diff --git a/Tests/View/ViewHandlerTest.php b/Tests/View/ViewHandlerTest.php index 26ece5058..f5f340cae 100644 --- a/Tests/View/ViewHandlerTest.php +++ b/Tests/View/ViewHandlerTest.php @@ -308,7 +308,9 @@ public function testSerializeNullDataValues($expected, $serializeNull) $viewHandler->setSerializeNullStrategy($serializeNull); $contextMethod = new \ReflectionMethod($viewHandler, 'getSerializationContext'); - $contextMethod->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $contextMethod->setAccessible(true); + } $view = new View(); $context = $contextMethod->invoke($viewHandler, $view); @@ -384,7 +386,9 @@ public function testConfigurableViewHandlerInterface() $viewHandler->setSerializeNullStrategy(true); $contextMethod = new \ReflectionMethod($viewHandler, 'getSerializationContext'); - $contextMethod->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $contextMethod->setAccessible(true); + } $view = new View(); $context = $contextMethod->invoke($viewHandler, $view); From 5dce8602dc5b518951a2969ca6906aec27eca6f7 Mon Sep 17 00:00:00 2001 From: W0rma Date: Mon, 22 Dec 2025 08:14:39 +0100 Subject: [PATCH 12/15] Fix build status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 966629721..5e373bf8b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ applications with Symfony. Features include: compatible with RFC 7807 using the Symfony Serializer component or the JMS Serializer -[![Build Status](https://img.shields.io/github/workflow/status/FriendsOfSymfony/FOSRestBundle/CI?style=flat-square)](https://github.com/FriendsOfSymfony/FOSRestBundle/actions?query=workflow:CI) +[![Build Status](https://github.com/FriendsOfSymfony/FOSRestBundle/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/FriendsOfSymfony/FOSRestBundle/actions/workflows/continuous-integration.yml) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/?branch=master) [![Code Coverage](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/?branch=master) [![Total Downloads](https://poser.pugx.org/FriendsOfSymfony/rest-bundle/downloads.svg)](https://packagist.org/packages/FriendsOfSymfony/rest-bundle) From 438a54df31c8a1a4a7a27e960927d3dcd75b33d3 Mon Sep 17 00:00:00 2001 From: W0rma Date: Mon, 22 Dec 2025 08:15:44 +0100 Subject: [PATCH 13/15] Remove broken SensioLabsInsight badge --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 5e373bf8b..28e3fda4f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ applications with Symfony. Features include: [![Code Coverage](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/?branch=master) [![Total Downloads](https://poser.pugx.org/FriendsOfSymfony/rest-bundle/downloads.svg)](https://packagist.org/packages/FriendsOfSymfony/rest-bundle) [![Latest Stable Version](https://poser.pugx.org/FriendsOfSymfony/rest-bundle/v/stable.svg)](https://packagist.org/packages/FriendsOfSymfony/rest-bundle) -[![SensioLabsInsight](https://insight.sensiolabs.com/projects/0be23389-2e85-49cf-b333-caaa36d11c62/mini.png)](https://insight.sensiolabs.com/projects/0be23389-2e85-49cf-b333-caaa36d11c62) Documentation ------------- From c93f1e706d1be2a05907ad0b45d832ed8df7adeb Mon Sep 17 00:00:00 2001 From: W0rma Date: Mon, 22 Dec 2025 08:22:09 +0100 Subject: [PATCH 14/15] Remove outdated scrutinizer badges --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 28e3fda4f..12e05d554 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,6 @@ applications with Symfony. Features include: JMS Serializer [![Build Status](https://github.com/FriendsOfSymfony/FOSRestBundle/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/FriendsOfSymfony/FOSRestBundle/actions/workflows/continuous-integration.yml) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/?branch=master) -[![Code Coverage](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSRestBundle/?branch=master) [![Total Downloads](https://poser.pugx.org/FriendsOfSymfony/rest-bundle/downloads.svg)](https://packagist.org/packages/FriendsOfSymfony/rest-bundle) [![Latest Stable Version](https://poser.pugx.org/FriendsOfSymfony/rest-bundle/v/stable.svg)](https://packagist.org/packages/FriendsOfSymfony/rest-bundle) From 0cb1733b927b41b8ad4cbae80fdd12781c9f1f3e Mon Sep 17 00:00:00 2001 From: W0rma Date: Mon, 22 Dec 2025 14:52:00 +0100 Subject: [PATCH 15/15] Allow usage with symfony/config v8 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f60a63f2f..1d0aa6c18 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ }, "require": { "php": "^7.4|^8.0", - "symfony/config": "^5.4|^6.4|^7.0", + "symfony/config": "^5.4|^6.4|^7.0|^8.0", "symfony/dependency-injection": "^5.4|^6.4|^7.0|^8.0", "symfony/deprecation-contracts": "^2.1|^3.0", "symfony/event-dispatcher": "^5.4|^6.4|^7.0|^8.0",