From 74cb0399b9419729cad1f825c74f88e2296bc1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Fri, 19 Dec 2025 10:33:14 +0100 Subject: [PATCH 01/31] Do not support EOL versions of PHP and Symfony anymore --- .github/workflows/tests.yml | 16 ++-------------- composer.json | 36 ++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 72a54d84..fcaca1cd 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,36 +24,24 @@ jobs: fail-fast: false matrix: include: - - - php: '7.3' - dependencies: lowest - symfony-deprecations: max[indirect]=5 - php: '8.4' dependencies: highest - php: '7.4' - symfony: '5.4.*' - - - php: '8.0' - symfony: '5.4.*' + symfony: '6.4.*' - php: '8.1' - symfony: '5.4.*' + symfony: '6.4.*' - php: '8.2' symfony: '6.4.*' - php: '8.3' symfony: '6.4.*' - - - php: '8.2' - symfony: '7.2.*' - php: '8.4' symfony: '7.4.*' - stability: dev - allow-failure: true - php: '8.4' symfony: '8.0.*' diff --git a/composer.json b/composer.json index 35503b23..cc195fdc 100644 --- a/composer.json +++ b/composer.json @@ -21,18 +21,18 @@ ], "homepage": "https://github.com/craue/CraueFormFlowBundle", "require": { - "php": "^7.3 || ^8", - "symfony/config": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/form": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/http-foundation": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/http-kernel": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/options-resolver": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/security-core": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/translation": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/validator": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/yaml": "^5.4 || ^6.4 || ^7.2 || ^8.0" + "php": "^8.1", + "symfony/config": "^6.4 || ^7.2 || ^8.0", + "symfony/dependency-injection": "^6.4 || ^7.2 || ^8.0", + "symfony/event-dispatcher": "^6.4 || ^7.2 || ^8.0", + "symfony/form": "^6.4 || ^7.2 || ^8.0", + "symfony/http-foundation": "^6.4 || ^7.2 || ^8.0", + "symfony/http-kernel": "^6.4 || ^7.2 || ^8.0", + "symfony/options-resolver": "^6.4 || ^7.2 || ^8.0", + "symfony/security-core": "^6.4 || ^7.2 || ^8.0", + "symfony/translation": "^6.4 || ^7.2 || ^8.0", + "symfony/validator": "^6.4 || ^7.2 || ^8.0", + "symfony/yaml": "^6.4 || ^7.2 || ^8.0" }, "require-dev": { "craue/translations-tests": "^1.1", @@ -46,13 +46,13 @@ "phpstan/phpstan-strict-rules": "^1.1", "phpstan/phpstan-symfony": "^1.1", "phpunit/phpunit": "^9.5", - "symfony/browser-kit": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/css-selector": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/framework-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/mime": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/browser-kit": "^6.4 || ^7.2 || ^8.0", + "symfony/css-selector": "^6.4 || ^7.2 || ^8.0", + "symfony/framework-bundle": "^6.4 || ^7.2 || ^8.0", + "symfony/mime": "^6.4 || ^7.2 || ^8.0", "symfony/phpunit-bridge": "^7.3", - "symfony/security-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0" + "symfony/security-bundle": "^6.4 || ^7.2 || ^8.0", + "symfony/twig-bundle": "^6.4 || ^7.2 || ^8.0" }, "conflict": { "doctrine/dbal": "<2.10" From 7f9a77cfe72d1f1753c500866ad15f7357124464 Mon Sep 17 00:00:00 2001 From: knallcharge <1715912+knallcharge@users.noreply.github.com> Date: Tue, 6 Jan 2026 09:14:58 +0100 Subject: [PATCH 02/31] allow Symfony 8 --- composer.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index 68e8b170..32b179c3 100644 --- a/composer.json +++ b/composer.json @@ -22,17 +22,17 @@ "homepage": "https://github.com/craue/CraueFormFlowBundle", "require": { "php": "^7.3 || ^8", - "symfony/config": "^5.4 || ^6.4 || ^7.2", - "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.2", - "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.2", - "symfony/form": "^5.4 || ^6.4 || ^7.2", - "symfony/http-foundation": "^5.4 || ^6.4 || ^7.2", - "symfony/http-kernel": "^5.4 || ^6.4 || ^7.2", - "symfony/options-resolver": "^5.4 || ^6.4 || ^7.2", - "symfony/security-core": "^5.4 || ^6.4 || ^7.2", - "symfony/translation": "^5.4 || ^6.4 || ^7.2", - "symfony/validator": "^5.4 || ^6.4 || ^7.2", - "symfony/yaml": "^5.4 || ^6.4 || ^7.2" + "symfony/config": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/form": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/http-foundation": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/http-kernel": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/security-core": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/translation": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/validator": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/yaml": "^5.4 || ^6.4 || ^7.2 || ^8.0" }, "require-dev": { "craue/translations-tests": "^1.1", @@ -46,13 +46,13 @@ "phpstan/phpstan-strict-rules": "^1.1", "phpstan/phpstan-symfony": "^1.1", "phpunit/phpunit": "^9.5", - "symfony/browser-kit": "^5.4 || ^6.4 || ^7.2", - "symfony/css-selector": "^5.4 || ^6.4 || ^7.2", - "symfony/framework-bundle": "^5.4 || ^6.4 || ^7.2", - "symfony/mime": "^5.4 || ^6.4 || ^7.2", - "symfony/phpunit-bridge": "^7.3", - "symfony/security-bundle": "^5.4 || ^6.4 || ^7.2", - "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.2" + "symfony/browser-kit": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/css-selector": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/framework-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/mime": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/phpunit-bridge": "^7.3 || ^8.0", + "symfony/security-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0", + "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0" }, "conflict": { "doctrine/dbal": "<2.10" From 40402df8c240e565d93a8bdac6bc65ff3c4fe069 Mon Sep 17 00:00:00 2001 From: knallcharge <1715912+knallcharge@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:15:49 +0100 Subject: [PATCH 03/31] Change boot method signature to return void --- CraueFormFlowBundle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CraueFormFlowBundle.php b/CraueFormFlowBundle.php index 1047f6f8..7ed260d0 100644 --- a/CraueFormFlowBundle.php +++ b/CraueFormFlowBundle.php @@ -15,7 +15,7 @@ class CraueFormFlowBundle extends Bundle { /** * @return void */ - public function boot() { + public function boot(): void { /* * Removes all temporary files created while handling file uploads. * Use a shutdown function to clean up even in case of a fatal error. From 16992a73589ef220a0cd700b4c20bac8e62f291b Mon Sep 17 00:00:00 2001 From: borisf Date: Fri, 9 Jan 2026 09:34:46 +0100 Subject: [PATCH 04/31] converted configs to PHP --- .../CraueFormFlowExtension.php | 10 +-- Resources/config/form_flow.php | 47 ++++++++++++ Resources/config/form_flow.xml | 71 ------------------- Resources/config/twig.php | 13 ++++ Resources/config/twig.xml | 23 ------ Resources/config/util.php | 15 ++++ Resources/config/util.xml | 21 ------ 7 files changed, 80 insertions(+), 120 deletions(-) create mode 100644 Resources/config/form_flow.php delete mode 100644 Resources/config/form_flow.xml create mode 100644 Resources/config/twig.php delete mode 100644 Resources/config/twig.xml create mode 100644 Resources/config/util.php delete mode 100644 Resources/config/util.xml diff --git a/DependencyInjection/CraueFormFlowExtension.php b/DependencyInjection/CraueFormFlowExtension.php index cfce10dc..0aef094f 100644 --- a/DependencyInjection/CraueFormFlowExtension.php +++ b/DependencyInjection/CraueFormFlowExtension.php @@ -7,7 +7,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; -use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; /** * Registration of the extension via DI. @@ -24,10 +24,10 @@ class CraueFormFlowExtension extends Extension implements CompilerPassInterface * @return void */ public function load(array $config, ContainerBuilder $container) { - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('form_flow.xml'); - $loader->load('twig.xml'); - $loader->load('util.xml'); + $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('form_flow.php'); + $loader->load('twig.php'); + $loader->load('util.php'); $container->registerForAutoconfiguration(FormFlowInterface::class)->addTag(self::FORM_FLOW_TAG); } diff --git a/Resources/config/form_flow.php b/Resources/config/form_flow.php new file mode 100644 index 00000000..f45a9543 --- /dev/null +++ b/Resources/config/form_flow.php @@ -0,0 +1,47 @@ +services(); + $parameters = $container->parameters(); + $parameters->set('craue.form.flow.class', \Craue\FormFlowBundle\Form\FormFlow::class); + $parameters->set('craue.form.flow.storage.class', \Craue\FormFlowBundle\Storage\SessionStorage::class); + $parameters->set('craue.form.flow.event_listener.previous_step_invalid.class', \Craue\FormFlowBundle\EventListener\PreviousStepInvalidEventListener::class); + $parameters->set('craue.form.flow.event_listener.previous_step_invalid.event', \Craue\FormFlowBundle\Form\FormFlowEvents::PREVIOUS_STEP_INVALID); + $parameters->set('craue.form.flow.event_listener.flow_expired.class', \Craue\FormFlowBundle\EventListener\FlowExpiredEventListener::class); + $parameters->set('craue.form.flow.event_listener.flow_expired.event', \Craue\FormFlowBundle\Form\FormFlowEvents::FLOW_EXPIRED); + + $services->set('craue.form.flow.storage_default', '%craue.form.flow.storage.class%') + ->private() + ->args([service('request_stack')]); + + $services->alias('craue.form.flow.storage', 'craue.form.flow.storage_default') + ->public(); + + $services->set('craue.form.flow.data_manager_default', \Craue\FormFlowBundle\Storage\DataManager::class) + ->private() + ->args([service('craue.form.flow.storage')]); + + $services->alias('craue.form.flow.data_manager', 'craue.form.flow.data_manager_default'); + + $services->set('craue.form.flow', '%craue.form.flow.class%') + ->call('setDataManager', [service('craue.form.flow.data_manager')]) + ->call('setFormFactory', [service('form.factory')]) + ->call('setRequestStack', [service('request_stack')]) + ->call('setEventDispatcher', [service('event_dispatcher')->ignoreOnInvalid()]); + + $services->set('craue.form.flow.form_extension', \Craue\FormFlowBundle\Form\Extension\FormFlowFormExtension::class) + ->tag('form.type_extension', ['extended_type' => \Symfony\Component\Form\Extension\Core\Type\FormType::class]); + + $services->set('craue.form.flow.hidden_field_extension', \Craue\FormFlowBundle\Form\Extension\FormFlowHiddenFieldExtension::class) + ->tag('form.type_extension', ['extended_type' => \Symfony\Component\Form\Extension\Core\Type\HiddenType::class]); + + $services->set('craue.form.flow.event_listener.previous_step_invalid', '%craue.form.flow.event_listener.previous_step_invalid.class%') + ->tag('kernel.event_listener', ['event' => '%craue.form.flow.event_listener.previous_step_invalid.event%', 'method' => 'onPreviousStepInvalid']) + ->call('setTranslator', [service('translator')]); + + $services->set('craue.form.flow.event_listener.flow_expired', '%craue.form.flow.event_listener.flow_expired.class%') + ->tag('kernel.event_listener', ['event' => '%craue.form.flow.event_listener.flow_expired.event%', 'method' => 'onFlowExpired']) + ->call('setTranslator', [service('translator')]); +}; diff --git a/Resources/config/form_flow.xml b/Resources/config/form_flow.xml deleted file mode 100644 index dd9075ff..00000000 --- a/Resources/config/form_flow.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Craue\FormFlowBundle\Form\FormFlow - Craue\FormFlowBundle\Storage\SessionStorage - Craue\FormFlowBundle\EventListener\PreviousStepInvalidEventListener - Craue\FormFlowBundle\Form\FormFlowEvents::PREVIOUS_STEP_INVALID - Craue\FormFlowBundle\EventListener\FlowExpiredEventListener - Craue\FormFlowBundle\Form\FormFlowEvents::FLOW_EXPIRED - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Resources/config/twig.php b/Resources/config/twig.php new file mode 100644 index 00000000..fe8c30c9 --- /dev/null +++ b/Resources/config/twig.php @@ -0,0 +1,13 @@ +services(); + $parameters = $container->parameters(); + $parameters->set('craue_twig_extensions.formflow.class', \Craue\FormFlowBundle\Twig\Extension\FormFlowExtension::class); + + $services->set('twig.extension.craue_formflow', '%craue_twig_extensions.formflow.class%') + ->tag('twig.extension') + ->call('setFormFlowUtil', [service('craue_formflow_util')]); +}; diff --git a/Resources/config/twig.xml b/Resources/config/twig.xml deleted file mode 100644 index 5b99d019..00000000 --- a/Resources/config/twig.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Craue\FormFlowBundle\Twig\Extension\FormFlowExtension - - - - - - - - - - - diff --git a/Resources/config/util.php b/Resources/config/util.php new file mode 100644 index 00000000..1297e7a1 --- /dev/null +++ b/Resources/config/util.php @@ -0,0 +1,15 @@ +services(); + $parameters = $container->parameters(); + $parameters->set('craue_formflow.util.class', \Craue\FormFlowBundle\Util\FormFlowUtil::class); + + $services->set('craue_formflow_util', '%craue_formflow.util.class%') + ->public(); + + $services->alias(\Craue\FormFlowBundle\Util\FormFlowUtil::class, 'craue_formflow_util') + ->private(); +}; diff --git a/Resources/config/util.xml b/Resources/config/util.xml deleted file mode 100644 index c3c9442f..00000000 --- a/Resources/config/util.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Craue\FormFlowBundle\Util\FormFlowUtil - - - - - - - - - From ad2828df834d7e35c6aa46057ba9e969e8955528 Mon Sep 17 00:00:00 2001 From: knallcharge <1715912+knallcharge@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:36:30 +0100 Subject: [PATCH 05/31] Add return type declaration to load method --- DependencyInjection/CraueFormFlowExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DependencyInjection/CraueFormFlowExtension.php b/DependencyInjection/CraueFormFlowExtension.php index 0aef094f..8fa36bc8 100644 --- a/DependencyInjection/CraueFormFlowExtension.php +++ b/DependencyInjection/CraueFormFlowExtension.php @@ -23,7 +23,7 @@ class CraueFormFlowExtension extends Extension implements CompilerPassInterface /** * @return void */ - public function load(array $config, ContainerBuilder $container) { + public function load(array $config, ContainerBuilder $container): void { $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('form_flow.php'); $loader->load('twig.php'); From 2ece05a92f56c8010d04e778226a6079fc02ec69 Mon Sep 17 00:00:00 2001 From: knallcharge <1715912+knallcharge@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:37:39 +0100 Subject: [PATCH 06/31] Add return type declaration to process method --- DependencyInjection/CraueFormFlowExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DependencyInjection/CraueFormFlowExtension.php b/DependencyInjection/CraueFormFlowExtension.php index 8fa36bc8..da98bb30 100644 --- a/DependencyInjection/CraueFormFlowExtension.php +++ b/DependencyInjection/CraueFormFlowExtension.php @@ -35,7 +35,7 @@ public function load(array $config, ContainerBuilder $container): void { /** * @return void */ - public function process(ContainerBuilder $container) { + public function process(ContainerBuilder $container): void { $baseFlowDefinitionMethodCalls = $container->getDefinition('craue.form.flow')->getMethodCalls(); foreach (array_keys($container->findTaggedServiceIds(self::FORM_FLOW_TAG)) as $id) { From 01fac9c97bf22cfbbe4f9a19cca522ef6802be15 Mon Sep 17 00:00:00 2001 From: knallcharge <1715912+knallcharge@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:45:36 +0100 Subject: [PATCH 07/31] Fix request method check to use request data --- Form/FormFlow.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Form/FormFlow.php b/Form/FormFlow.php index db8adcac..198cc1f2 100644 --- a/Form/FormFlow.php +++ b/Form/FormFlow.php @@ -652,7 +652,7 @@ protected function bindFlow() { $reset = true; } - if (in_array($request->getMethod(), ['POST', 'PUT'], true) && $request->get($this->getFormStepKey()) !== null && !$this->dataManager->exists($this)) { + if (in_array($request->getMethod(), ['POST', 'PUT'], true) && $request->request->get($this->getFormStepKey()) !== null && !$this->dataManager->exists($this)) { // flow is expired, drop posted data and reset $request->request->replace(); $reset = true; From f3dce90050f615853371cb6dab636749b880a2c5 Mon Sep 17 00:00:00 2001 From: knallcharge <1715912+knallcharge@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:47:27 +0100 Subject: [PATCH 08/31] Fix GET request handling for dynamic step navigation --- Form/FormFlow.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Form/FormFlow.php b/Form/FormFlow.php index 198cc1f2..23f34e29 100644 --- a/Form/FormFlow.php +++ b/Form/FormFlow.php @@ -539,7 +539,7 @@ protected function getRequestedStepNumber() { return intval($request->request->get($this->getFormStepKey(), $defaultStepNumber)); case 'GET': return $this->allowDynamicStepNavigation || $this->allowRedirectAfterSubmit ? - intval($request->get($this->dynamicStepNavigationStepParameter, $defaultStepNumber)) : + intval($request->query->get($this->dynamicStepNavigationStepParameter, $defaultStepNumber)) : $defaultStepNumber; } From c6f947002a942401f4d1a075686c3e323db5ef44 Mon Sep 17 00:00:00 2001 From: knallcharge <1715912+knallcharge@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:51:25 +0100 Subject: [PATCH 09/31] Refactor instanceId retrieval for dynamic navigation --- Form/FormFlow.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Form/FormFlow.php b/Form/FormFlow.php index 23f34e29..4d771593 100644 --- a/Form/FormFlow.php +++ b/Form/FormFlow.php @@ -625,7 +625,8 @@ protected function determineInstanceId() { $instanceId = null; if ($this->allowDynamicStepNavigation || $this->allowRedirectAfterSubmit) { - $instanceId = $request->get($this->getDynamicStepNavigationInstanceParameter()); + $requestData = in_array($request->getMethod(), ['POST', 'PUT'], true) ? $request->request : $request->query; + $instanceId = $requestData->get($this->getDynamicStepNavigationInstanceParameter()); } if ($instanceId === null) { From d223560c9bf4d93c6e03db00817596fe0ee5fcf2 Mon Sep 17 00:00:00 2001 From: borisf Date: Fri, 9 Jan 2026 10:11:34 +0100 Subject: [PATCH 10/31] merged changes from relthyg --- .github/workflows/tests.yml | 19 +++++-------------- composer.json | 38 ++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8259e8b0..fcaca1cd 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,36 +24,27 @@ jobs: fail-fast: false matrix: include: - - - php: '7.3' - dependencies: lowest - symfony-deprecations: max[indirect]=5 - php: '8.4' dependencies: highest - php: '7.4' - symfony: '5.4.*' - - - php: '8.0' - symfony: '5.4.*' + symfony: '6.4.*' - php: '8.1' - symfony: '5.4.*' + symfony: '6.4.*' - php: '8.2' symfony: '6.4.*' - php: '8.3' symfony: '6.4.*' - - - php: '8.2' - symfony: '7.2.*' - php: '8.4' symfony: '7.4.*' - stability: dev - allow-failure: true + - + php: '8.4' + symfony: '8.0.*' services: mysql: diff --git a/composer.json b/composer.json index 32b179c3..cc195fdc 100644 --- a/composer.json +++ b/composer.json @@ -21,18 +21,18 @@ ], "homepage": "https://github.com/craue/CraueFormFlowBundle", "require": { - "php": "^7.3 || ^8", - "symfony/config": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/form": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/http-foundation": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/http-kernel": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/options-resolver": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/security-core": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/translation": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/validator": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/yaml": "^5.4 || ^6.4 || ^7.2 || ^8.0" + "php": "^8.1", + "symfony/config": "^6.4 || ^7.2 || ^8.0", + "symfony/dependency-injection": "^6.4 || ^7.2 || ^8.0", + "symfony/event-dispatcher": "^6.4 || ^7.2 || ^8.0", + "symfony/form": "^6.4 || ^7.2 || ^8.0", + "symfony/http-foundation": "^6.4 || ^7.2 || ^8.0", + "symfony/http-kernel": "^6.4 || ^7.2 || ^8.0", + "symfony/options-resolver": "^6.4 || ^7.2 || ^8.0", + "symfony/security-core": "^6.4 || ^7.2 || ^8.0", + "symfony/translation": "^6.4 || ^7.2 || ^8.0", + "symfony/validator": "^6.4 || ^7.2 || ^8.0", + "symfony/yaml": "^6.4 || ^7.2 || ^8.0" }, "require-dev": { "craue/translations-tests": "^1.1", @@ -46,13 +46,13 @@ "phpstan/phpstan-strict-rules": "^1.1", "phpstan/phpstan-symfony": "^1.1", "phpunit/phpunit": "^9.5", - "symfony/browser-kit": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/css-selector": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/framework-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/mime": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/phpunit-bridge": "^7.3 || ^8.0", - "symfony/security-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0", - "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.2 || ^8.0" + "symfony/browser-kit": "^6.4 || ^7.2 || ^8.0", + "symfony/css-selector": "^6.4 || ^7.2 || ^8.0", + "symfony/framework-bundle": "^6.4 || ^7.2 || ^8.0", + "symfony/mime": "^6.4 || ^7.2 || ^8.0", + "symfony/phpunit-bridge": "^7.3", + "symfony/security-bundle": "^6.4 || ^7.2 || ^8.0", + "symfony/twig-bundle": "^6.4 || ^7.2 || ^8.0" }, "conflict": { "doctrine/dbal": "<2.10" From c07fc712e14a5f83413c09dae461088e71a76edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Fri, 16 Jan 2026 14:02:00 +0000 Subject: [PATCH 11/31] Allow PHP 7.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cc195fdc..53325a78 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ ], "homepage": "https://github.com/craue/CraueFormFlowBundle", "require": { - "php": "^8.1", + "php": "^7.4 || ^8.1", "symfony/config": "^6.4 || ^7.2 || ^8.0", "symfony/dependency-injection": "^6.4 || ^7.2 || ^8.0", "symfony/event-dispatcher": "^6.4 || ^7.2 || ^8.0", From 4c6e3022a209056cf3f65097b5a89b1fd9d2c55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Fri, 16 Jan 2026 15:06:07 +0100 Subject: [PATCH 12/31] Do not test for Symfony 6.4 with PHP 7.4 as Symfony 6.4 needs PHP 8.1 or greater. --- .github/workflows/tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fcaca1cd..a46c532b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -27,9 +27,6 @@ jobs: - php: '8.4' dependencies: highest - - - php: '7.4' - symfony: '6.4.*' - php: '8.1' symfony: '6.4.*' From c3e38e2ab136ad27c4d582d0d272dc1c4adb5880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Fri, 16 Jan 2026 16:04:44 +0100 Subject: [PATCH 13/31] Convert `IntegrationTestBundle` config to PHP --- .../Compiler/DoctrineStorageCompilerPass.php | 5 ++-- .../Resources/config/controller.php | 12 ++++++++++ .../Resources/config/controller.xml | 14 ----------- .../Resources/config/doctrine_storage.php | 24 +++++++++++++++++++ .../Resources/config/doctrine_storage.xml | 24 ------------------- .../form_flow_with_autoconfiguration.php | 12 ++++++++++ .../form_flow_with_autoconfiguration.xml | 14 ----------- .../config/form_flow_with_parent_service.php | 12 ++++++++++ .../config/form_flow_with_parent_service.xml | 14 ----------- Tests/config/config.yml | 4 ++-- .../config_flows_with_autoconfiguration.yml | 2 +- .../config_flows_with_parent_service.yml | 2 +- 12 files changed, 67 insertions(+), 72 deletions(-) create mode 100644 Tests/IntegrationTestBundle/Resources/config/controller.php delete mode 100644 Tests/IntegrationTestBundle/Resources/config/controller.xml create mode 100644 Tests/IntegrationTestBundle/Resources/config/doctrine_storage.php delete mode 100644 Tests/IntegrationTestBundle/Resources/config/doctrine_storage.xml create mode 100644 Tests/IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.php delete mode 100644 Tests/IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.xml create mode 100644 Tests/IntegrationTestBundle/Resources/config/form_flow_with_parent_service.php delete mode 100644 Tests/IntegrationTestBundle/Resources/config/form_flow_with_parent_service.xml diff --git a/Tests/IntegrationTestBundle/DependencyInjection/Compiler/DoctrineStorageCompilerPass.php b/Tests/IntegrationTestBundle/DependencyInjection/Compiler/DoctrineStorageCompilerPass.php index 4e22ff38..d8471874 100644 --- a/Tests/IntegrationTestBundle/DependencyInjection/Compiler/DoctrineStorageCompilerPass.php +++ b/Tests/IntegrationTestBundle/DependencyInjection/Compiler/DoctrineStorageCompilerPass.php @@ -5,6 +5,7 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; /** @@ -18,8 +19,8 @@ class DoctrineStorageCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) : void { if ($container->has('doctrine.dbal.default_connection')) { - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../Resources/config')); - $loader->load('doctrine_storage.xml'); + $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../../Resources/config')); + $loader->load('doctrine_storage.php'); } } diff --git a/Tests/IntegrationTestBundle/Resources/config/controller.php b/Tests/IntegrationTestBundle/Resources/config/controller.php new file mode 100644 index 00000000..d2f766db --- /dev/null +++ b/Tests/IntegrationTestBundle/Resources/config/controller.php @@ -0,0 +1,12 @@ +services(); + $parameters = $container->parameters(); + + $services->load('Craue\\FormFlowBundle\\Tests\\IntegrationTestBundle\\Controller\\', '../../Controller/*') + ->autowire() + ->autoconfigure(); +}; diff --git a/Tests/IntegrationTestBundle/Resources/config/controller.xml b/Tests/IntegrationTestBundle/Resources/config/controller.xml deleted file mode 100644 index b4fc4542..00000000 --- a/Tests/IntegrationTestBundle/Resources/config/controller.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/Tests/IntegrationTestBundle/Resources/config/doctrine_storage.php b/Tests/IntegrationTestBundle/Resources/config/doctrine_storage.php new file mode 100644 index 00000000..ce7d45d3 --- /dev/null +++ b/Tests/IntegrationTestBundle/Resources/config/doctrine_storage.php @@ -0,0 +1,24 @@ +services(); + $parameters = $container->parameters(); + + $services->set('craue.form.flow.storageKeyGenerator', \Craue\FormFlowBundle\Storage\UserSessionStorageKeyGenerator::class) + ->args([ + service('security.token_storage'), + service('request_stack'), + ]); + + $services->set('craue.form.flow.storage.doctrine', \Craue\FormFlowBundle\Storage\DoctrineStorage::class) + ->private() + ->args([ + service('doctrine.dbal.default_connection'), + service('craue.form.flow.storageKeyGenerator'), + ]); + + $services->alias('craue.form.flow.storage', 'craue.form.flow.storage.doctrine') + ->public(); +}; diff --git a/Tests/IntegrationTestBundle/Resources/config/doctrine_storage.xml b/Tests/IntegrationTestBundle/Resources/config/doctrine_storage.xml deleted file mode 100644 index 0e50f4c0..00000000 --- a/Tests/IntegrationTestBundle/Resources/config/doctrine_storage.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/Tests/IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.php b/Tests/IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.php new file mode 100644 index 00000000..890baefb --- /dev/null +++ b/Tests/IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.php @@ -0,0 +1,12 @@ +services(); + $parameters = $container->parameters(); + + $services->load('Craue\\FormFlowBundle\\Tests\\IntegrationTestBundle\\Form\\', '../../Form/*') + ->public() + ->autoconfigure(); +}; diff --git a/Tests/IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.xml b/Tests/IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.xml deleted file mode 100644 index 07615d04..00000000 --- a/Tests/IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/Tests/IntegrationTestBundle/Resources/config/form_flow_with_parent_service.php b/Tests/IntegrationTestBundle/Resources/config/form_flow_with_parent_service.php new file mode 100644 index 00000000..b3e443d9 --- /dev/null +++ b/Tests/IntegrationTestBundle/Resources/config/form_flow_with_parent_service.php @@ -0,0 +1,12 @@ +services(); + $parameters = $container->parameters(); + + $services->load('Craue\\FormFlowBundle\\Tests\\IntegrationTestBundle\\Form\\', '../../Form/*') + ->parent('craue.form.flow') + ->public(); +}; diff --git a/Tests/IntegrationTestBundle/Resources/config/form_flow_with_parent_service.xml b/Tests/IntegrationTestBundle/Resources/config/form_flow_with_parent_service.xml deleted file mode 100644 index 870dab5f..00000000 --- a/Tests/IntegrationTestBundle/Resources/config/form_flow_with_parent_service.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/Tests/config/config.yml b/Tests/config/config.yml index f8b78166..fac68d73 100644 --- a/Tests/config/config.yml +++ b/Tests/config/config.yml @@ -1,6 +1,6 @@ imports: - - { resource: '@CraueFormFlowBundle/Resources/config/form_flow.xml' } - - { resource: '@IntegrationTestBundle/Resources/config/controller.xml' } + - { resource: '@CraueFormFlowBundle/Resources/config/form_flow.php' } + - { resource: '@IntegrationTestBundle/Resources/config/controller.php' } - { resource: config_hacks.php } framework: diff --git a/Tests/config/config_flows_with_autoconfiguration.yml b/Tests/config/config_flows_with_autoconfiguration.yml index c4614521..d9058ba2 100644 --- a/Tests/config/config_flows_with_autoconfiguration.yml +++ b/Tests/config/config_flows_with_autoconfiguration.yml @@ -1,3 +1,3 @@ imports: - { resource: config.yml } - - { resource: '@IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.xml' } + - { resource: '@IntegrationTestBundle/Resources/config/form_flow_with_autoconfiguration.php' } diff --git a/Tests/config/config_flows_with_parent_service.yml b/Tests/config/config_flows_with_parent_service.yml index 27defdfc..3c53a1d8 100644 --- a/Tests/config/config_flows_with_parent_service.yml +++ b/Tests/config/config_flows_with_parent_service.yml @@ -1,3 +1,3 @@ imports: - { resource: config.yml } - - { resource: '@IntegrationTestBundle/Resources/config/form_flow_with_parent_service.xml' } + - { resource: '@IntegrationTestBundle/Resources/config/form_flow_with_parent_service.php' } From 0a27a4bf5b6f84d2bcdcdb477ae7a2e447f7c4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Fri, 16 Jan 2026 16:35:32 +0000 Subject: [PATCH 14/31] Use dev-Version of `craue/translation-tests` for symfony 8 compatibility --- composer.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 53325a78..ce363846 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,12 @@ } ], "homepage": "https://github.com/craue/CraueFormFlowBundle", + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/relthyg/CraueTranslationsTests" + } + ], "require": { "php": "^7.4 || ^8.1", "symfony/config": "^6.4 || ^7.2 || ^8.0", @@ -35,7 +41,7 @@ "symfony/yaml": "^6.4 || ^7.2 || ^8.0" }, "require-dev": { - "craue/translations-tests": "^1.1", + "craue/translations-tests": "dev-symfony8 as 1.2", "doctrine/collections": "^1.8 || ^2.1", "doctrine/common": "^2.9 || ^3.0", "doctrine/dbal": "^2.10 || ^3.0", From 642be39b592640b0a173ea971143c85f4078f1f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Mon, 19 Jan 2026 13:21:56 +0000 Subject: [PATCH 15/31] Ignore `var/` --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8751a3b9..ad227c47 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /phpstan.neon /phpunit.xml /vendor +/var From 488491cc1c685356c316c83e6e4affc1e31a9d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Mon, 19 Jan 2026 15:44:03 +0100 Subject: [PATCH 16/31] Fix parameter retrieval from `Request` --- Form/FormFlow.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Form/FormFlow.php b/Form/FormFlow.php index 4d771593..43325ffa 100644 --- a/Form/FormFlow.php +++ b/Form/FormFlow.php @@ -538,9 +538,10 @@ protected function getRequestedStepNumber() { case 'POST': return intval($request->request->get($this->getFormStepKey(), $defaultStepNumber)); case 'GET': - return $this->allowDynamicStepNavigation || $this->allowRedirectAfterSubmit ? - intval($request->query->get($this->dynamicStepNavigationStepParameter, $defaultStepNumber)) : - $defaultStepNumber; + $result = $request->attributes->get($this->dynamicStepNavigationStepParameter, $request); + $var = ($request !== $result) ? $result : $request->query->get($this->dynamicStepNavigationStepParameter, $defaultStepNumber); + + return ($this->allowDynamicStepNavigation || $this->allowRedirectAfterSubmit) ? (int)$var : $defaultStepNumber; } return $defaultStepNumber; From 9f5097a389704af28d0960f57e7bb4e313a7f4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 13:51:17 +0100 Subject: [PATCH 17/31] Remove config parameter `twig.exception_controller` ... as setting it to `null` ist deprecated as of symfony/twig-bundle 7.4 --- Tests/config/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/config/config.yml b/Tests/config/config.yml index fac68d73..ad99013f 100644 --- a/Tests/config/config.yml +++ b/Tests/config/config.yml @@ -27,4 +27,3 @@ security: twig: debug: '%kernel.debug%' strict_variables: '%kernel.debug%' - exception_controller: ~ From 9a6d77806fd83f017387d70cf1050ae56db6da8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 14:06:45 +0100 Subject: [PATCH 18/31] Allow `doctrine/dbal:^4.4`, `doctrine/doctrine-bundle:^3.2`, `symfony/phpunit-bridge:^8.0` --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index ce363846..b319426d 100644 --- a/composer.json +++ b/composer.json @@ -44,8 +44,8 @@ "craue/translations-tests": "dev-symfony8 as 1.2", "doctrine/collections": "^1.8 || ^2.1", "doctrine/common": "^2.9 || ^3.0", - "doctrine/dbal": "^2.10 || ^3.0", - "doctrine/doctrine-bundle": "^1.10 || ^2.0", + "doctrine/dbal": "^2.10 || ^3.0 || ^4.4", + "doctrine/doctrine-bundle": "^1.10 || ^2.0 || ^3.2", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.10", "phpstan/phpstan-deprecation-rules": "^1.0", @@ -56,7 +56,7 @@ "symfony/css-selector": "^6.4 || ^7.2 || ^8.0", "symfony/framework-bundle": "^6.4 || ^7.2 || ^8.0", "symfony/mime": "^6.4 || ^7.2 || ^8.0", - "symfony/phpunit-bridge": "^7.3", + "symfony/phpunit-bridge": "^7.3 || ^8.0", "symfony/security-bundle": "^6.4 || ^7.2 || ^8.0", "symfony/twig-bundle": "^6.4 || ^7.2 || ^8.0" }, From 5be312d53d435951ae0b046fcbba92ca09facb9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 14:19:31 +0100 Subject: [PATCH 19/31] Use method `Connection::quoteSingleIdentifier` instead of `quoteIdentifier` as the latter is deprecated --- Storage/DoctrineStorage.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Storage/DoctrineStorage.php b/Storage/DoctrineStorage.php index 39f942f8..64bedb56 100644 --- a/Storage/DoctrineStorage.php +++ b/Storage/DoctrineStorage.php @@ -52,8 +52,8 @@ public function __construct(Connection $conn, StorageKeyGeneratorInterface $stor $this->storageKeyGenerator = $storageKeyGenerator; // TODO just call `createSchemaManager()` as soon as DBAL >= 3.1 is required $this->schemaManager = \method_exists($this->conn, 'createSchemaManager') ? $this->conn->createSchemaManager() : $this->conn->getSchemaManager(); - $this->keyColumn = $this->conn->quoteIdentifier(self::KEY_COLUMN); - $this->valueColumn = $this->conn->quoteIdentifier(self::VALUE_COLUMN); + $this->keyColumn = $this->conn->quoteSingleIdentifier(self::KEY_COLUMN); + $this->valueColumn = $this->conn->quoteSingleIdentifier(self::VALUE_COLUMN); } /** From 20c72b7ac270c664cfb93fb68283123c01d77158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 14:34:03 +0100 Subject: [PATCH 20/31] Do not use method `Table::setPrimaryKey()` as this is deprecated --- Storage/DoctrineStorage.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Storage/DoctrineStorage.php b/Storage/DoctrineStorage.php index 64bedb56..9270e9b4 100644 --- a/Storage/DoctrineStorage.php +++ b/Storage/DoctrineStorage.php @@ -5,6 +5,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\PrimaryKeyConstraint; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Types; @@ -155,7 +156,12 @@ private function createTable() { new Column($this->valueColumn, Type::getType(Types::TEXT)), ]); - $table->setPrimaryKey([$this->keyColumn]); + $table->addPrimaryKeyConstraint( + PrimaryKeyConstraint::editor() + ->setUnquotedColumnNames($this->keyColumn) + ->create() + ); + $this->schemaManager->createTable($table); } From 6e0733f8649eec78d23602f67fe56f870d287998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 13:39:30 +0000 Subject: [PATCH 21/31] Normalize `composer.json` --- composer.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index b319426d..0a24390e 100644 --- a/composer.json +++ b/composer.json @@ -20,12 +20,6 @@ } ], "homepage": "https://github.com/craue/CraueFormFlowBundle", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/relthyg/CraueTranslationsTests" - } - ], "require": { "php": "^7.4 || ^8.1", "symfony/config": "^6.4 || ^7.2 || ^8.0", @@ -63,6 +57,12 @@ "conflict": { "doctrine/dbal": "<2.10" }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/relthyg/CraueTranslationsTests" + } + ], "minimum-stability": "stable", "autoload": { "psr-4": { From 1b069a11b169f5986cc7ea4e0d0e0ccfb85576b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 14:55:51 +0100 Subject: [PATCH 22/31] Use docker image `mysql:8.0` for all tests ... as the use of MySQL < 8 is deprecated in DBAL 4 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a46c532b..8581f4f5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -45,7 +45,7 @@ jobs: services: mysql: - image: mysql:${{ (matrix.php == '7.3' && '5.7') || '8.0' }} + image: mysql:8.0 env: MYSQL_USER: test MYSQL_PASSWORD: test From 4809797bd5a0a6a4d389e694ad2de75a2646c8f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 15:13:15 +0100 Subject: [PATCH 23/31] Add server version to MySQL DSN --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8581f4f5..f02911db 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ jobs: env: SYMFONY_REQUIRE: ${{ matrix.symfony }} SYMFONY_DEPRECATIONS_HELPER: ${{ matrix.symfony-deprecations }} - DB_DSN_MYSQL: mysql://test:test@127.0.0.1/craue_form_flow_tests + DB_DSN_MYSQL: mysql://test:test@127.0.0.1/craue_form_flow_tests?serverVersion=8.0 DB_DSN_POSTGRESQL: pgsql://test:test@127.0.0.1/craue_form_flow_tests DB_DSN_SQLITE: sqlite:///sqlite.db From b5001276a30387f28673be794a3059c6615361e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 15:16:48 +0100 Subject: [PATCH 24/31] Use MySQL 8.0.44 explicitly --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f02911db..aa8b86e8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ jobs: env: SYMFONY_REQUIRE: ${{ matrix.symfony }} SYMFONY_DEPRECATIONS_HELPER: ${{ matrix.symfony-deprecations }} - DB_DSN_MYSQL: mysql://test:test@127.0.0.1/craue_form_flow_tests?serverVersion=8.0 + DB_DSN_MYSQL: mysql://test:test@127.0.0.1/craue_form_flow_tests?serverVersion=8.0.44 DB_DSN_POSTGRESQL: pgsql://test:test@127.0.0.1/craue_form_flow_tests DB_DSN_SQLITE: sqlite:///sqlite.db @@ -45,7 +45,7 @@ jobs: services: mysql: - image: mysql:8.0 + image: mysql:8.0.44 env: MYSQL_USER: test MYSQL_PASSWORD: test From 1eac04dc03ed33f6026c213ff9b1ce4fa7c606dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 15:33:03 +0100 Subject: [PATCH 25/31] Use PostgreSQL 18.1 explicitly --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index aa8b86e8..47c6867e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,7 +17,7 @@ jobs: SYMFONY_REQUIRE: ${{ matrix.symfony }} SYMFONY_DEPRECATIONS_HELPER: ${{ matrix.symfony-deprecations }} DB_DSN_MYSQL: mysql://test:test@127.0.0.1/craue_form_flow_tests?serverVersion=8.0.44 - DB_DSN_POSTGRESQL: pgsql://test:test@127.0.0.1/craue_form_flow_tests + DB_DSN_POSTGRESQL: pgsql://test:test@127.0.0.1/craue_form_flow_tests?serverVersion=18.1 DB_DSN_SQLITE: sqlite:///sqlite.db strategy: @@ -60,7 +60,7 @@ jobs: - 3306:3306 postgres: - image: postgres + image: postgres:18.1 env: POSTGRES_USER: test POSTGRES_PASSWORD: test From 755c0a62da1357e189023f43cc924325cb1cbd33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 16:16:08 +0100 Subject: [PATCH 26/31] Use method `Connection::quoteSingleIdentifier()` only if it exists --- Storage/DoctrineStorage.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Storage/DoctrineStorage.php b/Storage/DoctrineStorage.php index 9270e9b4..60ec4665 100644 --- a/Storage/DoctrineStorage.php +++ b/Storage/DoctrineStorage.php @@ -53,8 +53,15 @@ public function __construct(Connection $conn, StorageKeyGeneratorInterface $stor $this->storageKeyGenerator = $storageKeyGenerator; // TODO just call `createSchemaManager()` as soon as DBAL >= 3.1 is required $this->schemaManager = \method_exists($this->conn, 'createSchemaManager') ? $this->conn->createSchemaManager() : $this->conn->getSchemaManager(); - $this->keyColumn = $this->conn->quoteSingleIdentifier(self::KEY_COLUMN); - $this->valueColumn = $this->conn->quoteSingleIdentifier(self::VALUE_COLUMN); + + // BC for doctrine/dbal < 4 + if(method_exists($this->conn, 'quoteSingleIdentifier')) { + $this->keyColumn = $this->conn->quoteSingleIdentifier(self::KEY_COLUMN); + $this->valueColumn = $this->conn->quoteSingleIdentifier(self::VALUE_COLUMN); + } else { + $this->keyColumn = $this->conn->quoteIdentifier(self::KEY_COLUMN); + $this->valueColumn = $this->conn->quoteIdentifier(self::VALUE_COLUMN); + } } /** From 91ad766da1ca90194d42b0aac376e6d89d9aab88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 16:34:01 +0100 Subject: [PATCH 27/31] Use method `Table::addPrimaryKeyConstraint()` only if it exists --- Storage/DoctrineStorage.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Storage/DoctrineStorage.php b/Storage/DoctrineStorage.php index 60ec4665..a1776d4e 100644 --- a/Storage/DoctrineStorage.php +++ b/Storage/DoctrineStorage.php @@ -163,11 +163,16 @@ private function createTable() { new Column($this->valueColumn, Type::getType(Types::TEXT)), ]); - $table->addPrimaryKeyConstraint( - PrimaryKeyConstraint::editor() - ->setUnquotedColumnNames($this->keyColumn) - ->create() - ); + // BC for doctrine/dbal < 4 + if (method_exists($table, 'addPrimaryKeyConstraint')) { + $table->addPrimaryKeyConstraint( + PrimaryKeyConstraint::editor() + ->setUnquotedColumnNames($this->keyColumn) + ->create() + ); + } else { + $table->setPrimaryKey([$this->keyColumn]); + } $this->schemaManager->createTable($table); } From 4b53dc3b643db05a21e90d02f637418ba14aa36a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Tue, 20 Jan 2026 17:02:50 +0100 Subject: [PATCH 28/31] Cast value to string to satisfy PHPStan --- Form/FormFlow.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Form/FormFlow.php b/Form/FormFlow.php index 43325ffa..67e53c86 100644 --- a/Form/FormFlow.php +++ b/Form/FormFlow.php @@ -539,7 +539,7 @@ protected function getRequestedStepNumber() { return intval($request->request->get($this->getFormStepKey(), $defaultStepNumber)); case 'GET': $result = $request->attributes->get($this->dynamicStepNavigationStepParameter, $request); - $var = ($request !== $result) ? $result : $request->query->get($this->dynamicStepNavigationStepParameter, $defaultStepNumber); + $var = ($request !== $result) ? $result : $request->query->get($this->dynamicStepNavigationStepParameter, (string)$defaultStepNumber); return ($this->allowDynamicStepNavigation || $this->allowRedirectAfterSubmit) ? (int)$var : $defaultStepNumber; } From ab2f2a13844e88dfb88da05b3f5ba5c5f98bc678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Wed, 21 Jan 2026 15:38:02 +0100 Subject: [PATCH 29/31] Require DBAL 3.1 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0a24390e..fa429cf7 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "craue/translations-tests": "dev-symfony8 as 1.2", "doctrine/collections": "^1.8 || ^2.1", "doctrine/common": "^2.9 || ^3.0", - "doctrine/dbal": "^2.10 || ^3.0 || ^4.4", + "doctrine/dbal": "^3.1 || ^4.4", "doctrine/doctrine-bundle": "^1.10 || ^2.0 || ^3.2", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.10", From d35bc1453506b42d0cbe65ca1b9559c67891c8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Wed, 21 Jan 2026 15:57:49 +0100 Subject: [PATCH 30/31] Remove usage of methods from DBAL < 3.1 --- Storage/DoctrineStorage.php | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/Storage/DoctrineStorage.php b/Storage/DoctrineStorage.php index a1776d4e..98252da5 100644 --- a/Storage/DoctrineStorage.php +++ b/Storage/DoctrineStorage.php @@ -51,15 +51,17 @@ class DoctrineStorage implements StorageInterface { public function __construct(Connection $conn, StorageKeyGeneratorInterface $storageKeyGenerator) { $this->conn = $conn; $this->storageKeyGenerator = $storageKeyGenerator; - // TODO just call `createSchemaManager()` as soon as DBAL >= 3.1 is required - $this->schemaManager = \method_exists($this->conn, 'createSchemaManager') ? $this->conn->createSchemaManager() : $this->conn->getSchemaManager(); + $this->schemaManager = $this->conn->createSchemaManager(); // BC for doctrine/dbal < 4 + /* @phpstan-ignore function.alreadyNarrowedType */ if(method_exists($this->conn, 'quoteSingleIdentifier')) { $this->keyColumn = $this->conn->quoteSingleIdentifier(self::KEY_COLUMN); $this->valueColumn = $this->conn->quoteSingleIdentifier(self::VALUE_COLUMN); } else { + /* @phpstan-ignore method.deprecated */ $this->keyColumn = $this->conn->quoteIdentifier(self::KEY_COLUMN); + /* @phpstan-ignore method.deprecated */ $this->valueColumn = $this->conn->quoteIdentifier(self::VALUE_COLUMN); } } @@ -142,15 +144,7 @@ private function getRawValueForKey($key) { ->setParameter('key', $this->generateKey($key)) ; - // TODO just call `executeQuery()` as soon as DBAL >= 2.13.1 is required - $result = \method_exists($qb, 'executeQuery') ? $qb->executeQuery() : $qb->execute(); - - // TODO remove as soon as Doctrine DBAL >= 3.0 is required - if (!\method_exists($result, 'fetchOne')) { - return $result->fetchColumn(); - } - - return $result->fetchOne(); + return $qb->executeQuery()->fetchOne(); } private function tableExists() { @@ -164,6 +158,7 @@ private function createTable() { ]); // BC for doctrine/dbal < 4 + /* @phpstan-ignore function.alreadyNarrowedType */ if (method_exists($table, 'addPrimaryKeyConstraint')) { $table->addPrimaryKeyConstraint( PrimaryKeyConstraint::editor() @@ -171,6 +166,7 @@ private function createTable() { ->create() ); } else { + /* @phpstan-ignore method.deprecated */ $table->setPrimaryKey([$this->keyColumn]); } @@ -180,5 +176,4 @@ private function createTable() { private function generateKey($key) { return $this->storageKeyGenerator->generate($key); } - } From 9a1532866002741ee3e8ab4c934e0b86a384028a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20G=C3=BCthler?= Date: Wed, 21 Jan 2026 15:58:36 +0100 Subject: [PATCH 31/31] Remove unnecessary PHPStan error handlings --- phpstan-config.neon | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/phpstan-config.neon b/phpstan-config.neon index 18ff4872..e2ae63d0 100644 --- a/phpstan-config.neon +++ b/phpstan-config.neon @@ -10,25 +10,3 @@ parameters: - message: '#^Unsafe usage of new static\(\)\.$#' path: Form/Step.php - # TODO remove as soon as Doctrine DBAL >= 2.13.1 is required - - - message: """ - #^Call to deprecated method execute\\(\\) of class Doctrine\\\\DBAL\\\\Query\\\\QueryBuilder\\: - Use \\{@see executeQuery\\(\\)\\} or \\{@see executeStatement\\(\\)\\} instead\\.$# - """ - path: Storage/DoctrineStorage.php - # TODO remove as soon as Doctrine DBAL >= 3.0 is required - - - message: '#^Cannot call method fetchColumn\(\) on Doctrine\\DBAL\\Result\|int\|string\.$#' - path: Storage/DoctrineStorage.php - # TODO remove as soon as Doctrine DBAL >= 3.1 is required - - - message: "#^Call to function method_exists\\(\\) with Doctrine\\\\DBAL\\\\Connection and 'createSchemaManager' will always evaluate to true\\.$#" - path: Storage/DoctrineStorage.php - # TODO remove as soon as Doctrine DBAL >= 3.1 is required - - - message: """ - #^Call to deprecated method getSchemaManager\\(\\) of class Doctrine\\\\DBAL\\\\Connection\\: - Use \\{@see createSchemaManager\\(\\)\\} instead\\.$# - """ - path: Storage/DoctrineStorage.php