Skip to content

[Validator] remove support for generic constraint option handling #61063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 8.0
Choose a base branch
from

Conversation

xabbuh
Copy link
Member

@xabbuh xabbuh commented Jul 8, 2025

Q A
Branch? 8.0
Bug fix? no
New feature? yes
Deprecations? no
Issues
License MIT

opening the PR already even if some polishing needs to be done (and not all tests pass yet) to avoid someone else wasting their time on this topic

@carsonbot carsonbot added this to the 8.0 milestone Jul 8, 2025
@carsonbot carsonbot changed the title [WIP][Validator] remove support for generic constraint option handling [Validator] [WIP] remove support for generic constraint option handling Jul 8, 2025
@xabbuh xabbuh force-pushed the validator-cleanup branch from 95fd8a0 to d04270c Compare July 8, 2025 06:58
@xabbuh xabbuh requested a review from chalasr as a code owner July 8, 2025 06:58
@xabbuh xabbuh force-pushed the validator-cleanup branch 2 times, most recently from b8ba9e7 to 0c03730 Compare July 8, 2025 09:25
@@ -32,7 +32,7 @@ public function __construct(mixed $options = null, ?array $groups = null, mixed
throw new ConstraintDefinitionException(\sprintf('You can\'t redefine the "%s" option. Use the "%s::getConstraints()" method instead.', $this->getCompositeOption(), __CLASS__));
}

$this->constraints = $this->getConstraints($this->normalizeOptions($options));
$this->constraints = $this->getConstraints($options ?? []);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to deprecate using options in this Compound abstract class first, to be able to remove support properly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, that's not a really useful feature anymore. I'm gonna send a PR for the deprecation targeting the 7.4 branch.

public function getDefaultOption(): ?string
{
return 'constraints';
parent::__construct(null, $groups, $payload);
}

protected function getCompositeOption(): string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method should also be removed, as it does not make sense anymore once the parent does not handle an array of options anymore.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getCompositeOption() is used independently from the $options array in the constructor of the Composite base class:

foreach ((array) $this->getCompositeOption() as $option) {
/** @var Constraint[] $nestedConstraints */
$nestedConstraints = $this->$option;
if (!\is_array($nestedConstraints)) {
$nestedConstraints = [$nestedConstraints];
}
foreach ($nestedConstraints as $constraint) {
if (!$constraint instanceof Constraint) {
if (\is_object($constraint)) {
$constraint = get_debug_type($constraint);
}
throw new ConstraintDefinitionException(\sprintf('The value "%s" is not an instance of Constraint in constraint "%s".', $constraint, get_debug_type($this)));
}
if ($constraint instanceof Valid) {
throw new ConstraintDefinitionException(\sprintf('The constraint Valid cannot be nested inside constraint "%s". You can only declare the Valid constraint directly on a field or method.', get_debug_type($this)));
}
}
if (!isset(((array) $this)['groups'])) {
$mergedGroups = [];
foreach ($nestedConstraints as $constraint) {
foreach ($constraint->groups as $group) {
$mergedGroups[$group] = true;
}
}
// prevent empty composite constraint to have empty groups
$this->groups = array_keys($mergedGroups) ?: [self::DEFAULT_GROUP];
$this->$option = $nestedConstraints;
continue;
}
foreach ($nestedConstraints as $constraint) {
if (isset(((array) $constraint)['groups'])) {
$excessGroups = array_diff($constraint->groups, $this->groups);
if (\count($excessGroups) > 0) {
throw new ConstraintDefinitionException(\sprintf('The group(s) "%s" passed to the constraint "%s" should also be passed to its containing constraint "%s".', implode('", "', $excessGroups), get_debug_type($constraint), get_debug_type($this)));
}
} else {
$constraint->groups = $this->groups;
}
}
$this->$option = $nestedConstraints;
}

The important part when not being able anymore to use the options array is that the property/properties referenced with getCompositeOption() are initialised in child class before the base constructor is called (that's part of the upgrade/changelog files).

@xabbuh xabbuh force-pushed the validator-cleanup branch 2 times, most recently from 5428b30 to e934b07 Compare July 11, 2025 18:34
@alexandre-daubois alexandre-daubois added the BC Layer removal Used to track BC layer removals before a major release label Jul 11, 2025
@xabbuh xabbuh force-pushed the validator-cleanup branch 5 times, most recently from 71a8b66 to 8397d33 Compare July 16, 2025 13:37
@xabbuh xabbuh force-pushed the validator-cleanup branch 5 times, most recently from 17fcad8 to 9df2c71 Compare July 24, 2025 06:03
@xabbuh xabbuh changed the title [Validator] [WIP] remove support for generic constraint option handling [Validator] remove support for generic constraint option handling Jul 24, 2025
@xabbuh
Copy link
Member Author

xabbuh commented Jul 24, 2025

This is ready to be reviewed.

Status: Needs Review

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, such nice diff! Thanks for working on this!

UPGRADE-8.0.md Outdated
public $option2;

#[HasNamedArguments]
public function __construct($option1 = null, $option2 = null, ?array $groups = null, mixed $payload = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we propose CPP here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea, done

UPGRADE-8.0.md Outdated
parent::__construct(null, $groups, $payload);
}
}
```
* Remove `Bic::INVALID_BANK_CODE_ERROR` constant. This error code was not used in the Bic constraint validator anymore.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no trailing dot anywhere ;)

UPGRADE-8.0.md Outdated
public $option1;
public $option2;

#[HasNamedArguments]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed no, fixed

@@ -41,11 +41,7 @@ class Date extends Constraint
#[HasNamedArguments]
public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null)
{
if (\is_array($options)) {
trigger_deprecation('symfony/validator', '7.3', 'Passing an array of options to configure the "%s" constraint is deprecated, use named arguments instead.', static::class);
Copy link
Member

@nicolas-grekas nicolas-grekas Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in cases like this, we still have a legacy $options argument
would it make sense to try to remove it, using some BC layer?
or should we throw to be sure passing anything else than null is forbidden?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot easily detect if options are passed when changing the order of arguments in 7.4 (we can try again in 8.1). But I added checks for $options to be null and throw otherwise.

$this->maxRatio = $maxRatio ?? $this->maxRatio;
$this->minRatio = $minRatio ?? $this->minRatio;
$this->minPixels = $minPixels ?? $this->minPixels;
$this->maxPixels = $maxPixels ?? $this->maxPixels;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't really have a deprecation layer for this change, do we?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do, all these properties could only have been non null before if any of the properties were passed through the $options array.

@@ -26,38 +25,16 @@ class Traverse extends Constraint
public bool $traverse = true;

/**
* @param bool|array<string,mixed>|null $traverse Whether to traverse the given object or not (defaults to true). Pass an associative array to configure the constraint's options (e.g. payload).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be worth doing this on 7.4: docblocks should be only about the non-deprecated API

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see #61240

@xabbuh xabbuh force-pushed the validator-cleanup branch from 9df2c71 to 28644a9 Compare July 25, 2025 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BC Layer removal Used to track BC layer removals before a major release Feature Status: Needs Review Validator
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy