From 8b99df5c73dd334fcb06b8101650d1bb7e292aa6 Mon Sep 17 00:00:00 2001 From: Dawid Parafinski Date: Wed, 9 Sep 2026 13:35:35 +0200 Subject: [PATCH 1/2] IBX-12046: Removed Symfony 8 deprecated code usage Replaced Request::get() with an explicit attributes bag lookup in UserRegisterController, and aligned the Password, EmailInvitation and UserPassword validator constraints with the Symfony 7.4 constructor contract (#[HasNamedArguments], BC-preserving options array with a deprecation notice for external callers). Updated the two in-repo form types that instantiated Password with a positional options array to use named arguments instead. --- .../Controller/UserRegisterController.php | 2 +- src/lib/Form/Type/UserPasswordChangeType.php | 8 ++--- src/lib/Form/Type/UserPasswordResetType.php | 6 ++-- .../Validator/Constraints/EmailInvitation.php | 30 ++++++++++++++++ src/lib/Validator/Constraints/Password.php | 36 +++++++++++++++++++ .../Validator/Constraints/UserPassword.php | 30 ++++++++++++++++ 6 files changed, 103 insertions(+), 9 deletions(-) diff --git a/src/bundle/Controller/UserRegisterController.php b/src/bundle/Controller/UserRegisterController.php index 5ce6f7b2..af05ba1f 100644 --- a/src/bundle/Controller/UserRegisterController.php +++ b/src/bundle/Controller/UserRegisterController.php @@ -69,7 +69,7 @@ public function registerConfirmAction(): ConfirmView public function registerFromInvitationAction(Request $request): Response|FormView { - $invitation = $this->invitationService->getInvitation($request->get('inviteHash')); + $invitation = $this->invitationService->getInvitation($request->attributes->get('inviteHash')); if (!$this->invitationService->isValid($invitation)) { throw new UnauthorizedHttpException('You are not allowed to register a new account'); diff --git a/src/lib/Form/Type/UserPasswordChangeType.php b/src/lib/Form/Type/UserPasswordChangeType.php index 383b7027..5bfd66f6 100644 --- a/src/lib/Form/Type/UserPasswordChangeType.php +++ b/src/lib/Form/Type/UserPasswordChangeType.php @@ -35,10 +35,10 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'first_options' => ['label' => /** @Desc("New password") */ 'ezplatform.change_user_password.new_password'], 'second_options' => ['label' => /** @Desc("Confirm password") */ 'ezplatform.change_user_password.confirm_new_password'], 'constraints' => [ - new Password([ - 'contentType' => $options['content_type'], - 'user' => $options['user'] ?? null, - ]), + new Password( + contentType: $options['content_type'], + user: $options['user'] ?? null, + ), ], ]) ->add( diff --git a/src/lib/Form/Type/UserPasswordResetType.php b/src/lib/Form/Type/UserPasswordResetType.php index 6b6ad4c6..69e70736 100644 --- a/src/lib/Form/Type/UserPasswordResetType.php +++ b/src/lib/Form/Type/UserPasswordResetType.php @@ -32,10 +32,8 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'second_options' => ['label' => /** @Desc("Confirm password") */ 'ezplatform.reset_user_password.confirm_new_password'], 'constraints' => [ new Password( - [ - 'contentType' => $options['content_type'], - 'user' => $options['user'] ?? null, - ] + contentType: $options['content_type'], + user: $options['user'] ?? null, ), ], ]) diff --git a/src/lib/Validator/Constraints/EmailInvitation.php b/src/lib/Validator/Constraints/EmailInvitation.php index fe6dcbc0..08071b8f 100644 --- a/src/lib/Validator/Constraints/EmailInvitation.php +++ b/src/lib/Validator/Constraints/EmailInvitation.php @@ -10,6 +10,7 @@ use JMS\TranslationBundle\Model\Message; use JMS\TranslationBundle\Translation\TranslationContainerInterface; +use Symfony\Component\Validator\Attribute\HasNamedArguments; use Symfony\Component\Validator\Constraint; /** @@ -19,6 +20,35 @@ class EmailInvitation extends Constraint implements TranslationContainerInterfac { public string $message = 'ibexa.user.invitation.user_with_email_exists'; + /** + * @param array|null $options Deprecated, use named arguments instead + * @param array|null $groups + */ + #[HasNamedArguments] + public function __construct( + ?array $options = null, + ?string $message = null, + ?array $groups = null, + mixed $payload = null, + ) { + if (null !== $options) { + trigger_deprecation( + 'ibexa/user', + '6.0', + 'Passing an options array to "%s" is deprecated, use named arguments instead.', + static::class + ); + + $message ??= $options['message'] ?? null; + $groups ??= $options['groups'] ?? null; + $payload ??= $options['payload'] ?? null; + } + + parent::__construct(null, $groups, $payload); + + $this->message = $message ?? $this->message; + } + public static function getTranslationMessages(): array { return [ diff --git a/src/lib/Validator/Constraints/Password.php b/src/lib/Validator/Constraints/Password.php index c20956f7..2afa939c 100644 --- a/src/lib/Validator/Constraints/Password.php +++ b/src/lib/Validator/Constraints/Password.php @@ -10,6 +10,7 @@ use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType; use Ibexa\Contracts\Core\Repository\Values\User\User; +use Symfony\Component\Validator\Attribute\HasNamedArguments; use Symfony\Component\Validator\Constraint; /** @@ -23,6 +24,41 @@ class Password extends Constraint public ?User $user = null; + /** + * @param array|null $options Deprecated, use named arguments instead + * @param array|null $groups + */ + #[HasNamedArguments] + public function __construct( + ?array $options = null, + ?ContentType $contentType = null, + ?User $user = null, + ?string $message = null, + ?array $groups = null, + mixed $payload = null, + ) { + if (null !== $options) { + trigger_deprecation( + 'ibexa/user', + '6.0', + 'Passing an options array to "%s" is deprecated, use named arguments instead.', + static::class + ); + + $contentType ??= $options['contentType'] ?? null; + $user ??= $options['user'] ?? null; + $message ??= $options['message'] ?? null; + $groups ??= $options['groups'] ?? null; + $payload ??= $options['payload'] ?? null; + } + + parent::__construct(null, $groups, $payload); + + $this->contentType = $contentType; + $this->user = $user; + $this->message = $message ?? $this->message; + } + #[\Override] public function getTargets(): array { diff --git a/src/lib/Validator/Constraints/UserPassword.php b/src/lib/Validator/Constraints/UserPassword.php index f0d78239..253827e3 100644 --- a/src/lib/Validator/Constraints/UserPassword.php +++ b/src/lib/Validator/Constraints/UserPassword.php @@ -10,6 +10,7 @@ use JMS\TranslationBundle\Model\Message; use JMS\TranslationBundle\Translation\TranslationContainerInterface; +use Symfony\Component\Validator\Attribute\HasNamedArguments; use Symfony\Component\Validator\Constraint; /** @@ -19,6 +20,35 @@ class UserPassword extends Constraint implements TranslationContainerInterface { public string $message = 'ezplatform.change_user_password.not_match'; + /** + * @param array|null $options Deprecated, use named arguments instead + * @param array|null $groups + */ + #[HasNamedArguments] + public function __construct( + ?array $options = null, + ?string $message = null, + ?array $groups = null, + mixed $payload = null, + ) { + if (null !== $options) { + trigger_deprecation( + 'ibexa/user', + '6.0', + 'Passing an options array to "%s" is deprecated, use named arguments instead.', + static::class + ); + + $message ??= $options['message'] ?? null; + $groups ??= $options['groups'] ?? null; + $payload ??= $options['payload'] ?? null; + } + + parent::__construct(null, $groups, $payload); + + $this->message = $message ?? $this->message; + } + /** * @return \JMS\TranslationBundle\Model\Message[] */ From e79e764050d999fa5617e5e5f48ba584169e0328 Mon Sep 17 00:00:00 2001 From: Dawid Parafinski Date: Fri, 11 Sep 2026 13:48:50 +0200 Subject: [PATCH 2/2] IBX-12046: Dropped the options-array constructor path from validator constraints 6.0 is a major and Symfony 8 removes options-array support from Constraint itself; the form types already use named arguments and no other package instantiates Password, EmailInvitation or UserPassword. --- .../Validator/Constraints/EmailInvitation.php | 15 --------- src/lib/Validator/Constraints/Password.php | 17 ---------- .../Validator/Constraints/UserPassword.php | 15 --------- .../Constraint/PasswordValidatorTest.php | 32 +++++++++---------- 4 files changed, 16 insertions(+), 63 deletions(-) diff --git a/src/lib/Validator/Constraints/EmailInvitation.php b/src/lib/Validator/Constraints/EmailInvitation.php index 08071b8f..81d6bc7a 100644 --- a/src/lib/Validator/Constraints/EmailInvitation.php +++ b/src/lib/Validator/Constraints/EmailInvitation.php @@ -21,29 +21,14 @@ class EmailInvitation extends Constraint implements TranslationContainerInterfac public string $message = 'ibexa.user.invitation.user_with_email_exists'; /** - * @param array|null $options Deprecated, use named arguments instead * @param array|null $groups */ #[HasNamedArguments] public function __construct( - ?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null, ) { - if (null !== $options) { - trigger_deprecation( - 'ibexa/user', - '6.0', - 'Passing an options array to "%s" is deprecated, use named arguments instead.', - static::class - ); - - $message ??= $options['message'] ?? null; - $groups ??= $options['groups'] ?? null; - $payload ??= $options['payload'] ?? null; - } - parent::__construct(null, $groups, $payload); $this->message = $message ?? $this->message; diff --git a/src/lib/Validator/Constraints/Password.php b/src/lib/Validator/Constraints/Password.php index 2afa939c..0f9a6cd3 100644 --- a/src/lib/Validator/Constraints/Password.php +++ b/src/lib/Validator/Constraints/Password.php @@ -25,33 +25,16 @@ class Password extends Constraint public ?User $user = null; /** - * @param array|null $options Deprecated, use named arguments instead * @param array|null $groups */ #[HasNamedArguments] public function __construct( - ?array $options = null, ?ContentType $contentType = null, ?User $user = null, ?string $message = null, ?array $groups = null, mixed $payload = null, ) { - if (null !== $options) { - trigger_deprecation( - 'ibexa/user', - '6.0', - 'Passing an options array to "%s" is deprecated, use named arguments instead.', - static::class - ); - - $contentType ??= $options['contentType'] ?? null; - $user ??= $options['user'] ?? null; - $message ??= $options['message'] ?? null; - $groups ??= $options['groups'] ?? null; - $payload ??= $options['payload'] ?? null; - } - parent::__construct(null, $groups, $payload); $this->contentType = $contentType; diff --git a/src/lib/Validator/Constraints/UserPassword.php b/src/lib/Validator/Constraints/UserPassword.php index 253827e3..1ba6fdd9 100644 --- a/src/lib/Validator/Constraints/UserPassword.php +++ b/src/lib/Validator/Constraints/UserPassword.php @@ -21,29 +21,14 @@ class UserPassword extends Constraint implements TranslationContainerInterface public string $message = 'ezplatform.change_user_password.not_match'; /** - * @param array|null $options Deprecated, use named arguments instead * @param array|null $groups */ #[HasNamedArguments] public function __construct( - ?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null, ) { - if (null !== $options) { - trigger_deprecation( - 'ibexa/user', - '6.0', - 'Passing an options array to "%s" is deprecated, use named arguments instead.', - static::class - ); - - $message ??= $options['message'] ?? null; - $groups ??= $options['groups'] ?? null; - $payload ??= $options['payload'] ?? null; - } - parent::__construct(null, $groups, $payload); $this->message = $message ?? $this->message; diff --git a/tests/lib/Validator/Constraint/PasswordValidatorTest.php b/tests/lib/Validator/Constraint/PasswordValidatorTest.php index b3f18825..cce89c3f 100644 --- a/tests/lib/Validator/Constraint/PasswordValidatorTest.php +++ b/tests/lib/Validator/Constraint/PasswordValidatorTest.php @@ -85,10 +85,10 @@ static function (string $actualPassword, PasswordValidationContext $actualContex $this->validator->validate( $password, - new Password([ - 'contentType' => $contentType, - 'user' => $user, - ]) + new Password( + contentType: $contentType, + user: $user, + ) ); } @@ -140,9 +140,9 @@ public function testInvalid(): void ->expects(self::once()) ->method('addViolation'); - $this->validator->validate('pass', new Password([ - 'contentType' => $contentType, - ])); + $this->validator->validate('pass', new Password( + contentType: $contentType, + )); } public function testPluralValidationErrorUsesPluralMessageTemplate(): void @@ -174,9 +174,9 @@ public function testPluralValidationErrorUsesPluralMessageTemplate(): void ->with('plural error') ->willReturn($constraintViolationBuilder); - $this->validator->validate('pass', new Password([ - 'contentType' => $contentType, - ])); + $this->validator->validate('pass', new Password( + contentType: $contentType, + )); } /** @@ -212,9 +212,9 @@ public function testKnownValidationErrorsGetRequirementCode( ->with($errorMessage) ->willReturn($constraintViolationBuilder); - $this->validator->validate('pass', new Password([ - 'contentType' => $contentType, - ])); + $this->validator->validate('pass', new Password( + contentType: $contentType, + )); } /** @@ -293,9 +293,9 @@ public function testEveryCoreCharacterRuleErrorProducesRequirementCode(): void ->method('buildViolation') ->willReturn($constraintViolationBuilder); - $this->validator->validate('pass', new Password([ - 'contentType' => $this->createMock(ContentType::class), - ])); + $this->validator->validate('pass', new Password( + contentType: $this->createMock(ContentType::class), + )); } /**