Skip to content

Commit 1c4d057

Browse files
[Validator] Allow using attributes to declare compile-time constraint metadata
1 parent b3b8971 commit 1c4d057

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

Extension/Validator/Constraints/Form.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111

1212
namespace Symfony\Component\Form\Extension\Validator\Constraints;
1313

14+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
1415
use Symfony\Component\Validator\Constraint;
1516

1617
/**
1718
* @author Bernhard Schussek <[email protected]>
1819
*/
20+
#[\Attribute(\Attribute::TARGET_CLASS)]
1921
class Form extends Constraint
2022
{
2123
public const NOT_SYNCHRONIZED_ERROR = '1dafa156-89e1-4736-b832-419c2e501fca';
@@ -26,6 +28,12 @@ class Form extends Constraint
2628
self::NO_SUCH_FIELD_ERROR => 'NO_SUCH_FIELD_ERROR',
2729
];
2830

31+
#[HasNamedArguments]
32+
public function __construct(mixed $options = null, ?array $groups = null, mixed $payload = null)
33+
{
34+
parent::__construct($options, $groups, $payload);
35+
}
36+
2937
public function getTargets(): string|array
3038
{
3139
return self::CLASS_CONSTRAINT;

Form.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222
use Symfony\Component\Form\Exception\RuntimeException;
2323
use Symfony\Component\Form\Exception\TransformationFailedException;
2424
use Symfony\Component\Form\Extension\Core\Type\TextType;
25+
use Symfony\Component\Form\Extension\Validator\Constraints\Form as AssertForm;
2526
use Symfony\Component\Form\Util\FormUtil;
2627
use Symfony\Component\Form\Util\InheritDataAwareIterator;
2728
use Symfony\Component\Form\Util\OrderedHashMap;
2829
use Symfony\Component\PropertyAccess\PropertyPath;
2930
use Symfony\Component\PropertyAccess\PropertyPathInterface;
31+
use Symfony\Component\Validator\Constraints\Traverse;
3032

3133
/**
3234
* Form represents a form.
@@ -68,6 +70,8 @@
6870
*
6971
* @implements \IteratorAggregate<string, FormInterface>
7072
*/
73+
#[AssertForm]
74+
#[Traverse(false)]
7175
class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterface
7276
{
7377
private ?FormInterface $parent = null;
@@ -301,7 +305,7 @@ public function setData(mixed $modelData): static
301305
if (null !== $dataClass && !$viewData instanceof $dataClass) {
302306
$actualType = get_debug_type($viewData);
303307

304-
throw new LogicException('The form\'s view data is expected to be a "'.$dataClass.'", but it is a "'.$actualType.'". You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms "'.$actualType.'" to an instance of "'.$dataClass.'".');
308+
throw new LogicException(\sprintf('The form\'s view data is expected to be a "%s", but it is a "%s". You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms "%2$s" to an instance of "%1$s".', $dataClass, $actualType));
305309
}
306310
}
307311

0 commit comments

Comments
 (0)