Skip to content

Commit aaabd63

Browse files
[Symfony73] Handle nested array on ConstraintOptionsToNamedArgumentsRector (#815)
* Add fixtures for issue #9258 * FIx * clean up --------- Co-authored-by: Guillaume Erpeldinger <[email protected]>
1 parent 0b3b4fd commit aaabd63

File tree

2 files changed

+129
-3
lines changed

2 files changed

+129
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
namespace Rector\Symfony\Tests\Symfony73\Rector\Class_\ConstraintOptionsToNamedArgumentsRector\Fixture;
4+
5+
use Symfony\Component\Form\AbstractType;
6+
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
7+
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
8+
use Symfony\Component\Form\Extension\Core\Type\TextType;
9+
use Symfony\Component\Form\FormBuilderInterface;
10+
use Symfony\Component\Validator\Constraints\All;
11+
use Symfony\Component\Validator\Constraints\AtLeastOneOf;
12+
use Symfony\Component\Validator\Constraints\Count;
13+
use Symfony\Component\Validator\Constraints\DivisibleBy;
14+
use Symfony\Component\Validator\Constraints\EqualTo;
15+
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
16+
use Symfony\Component\Validator\Constraints\Length;
17+
use Symfony\Component\Validator\Constraints\LessThanOrEqual;
18+
use Symfony\Component\Validator\Constraints\NotBlank;
19+
use Symfony\Component\Validator\Constraints\Regex;
20+
21+
class NestedConstraintForm extends AbstractType
22+
{
23+
public function buildForm(FormBuilderInterface $builder, array $options): void
24+
{
25+
$builder
26+
->add('foo', CollectionType::class, [
27+
'entry_type' => TextType::class,
28+
'allow_add' => true,
29+
'allow_delete' => true,
30+
'required' => false,
31+
'constraints' => [
32+
new Count(['min' => 3, 'max' => 30]),
33+
new All([
34+
new Length([
35+
'min' => 2,
36+
'max' => 50,
37+
'minMessage' => 'Your foo must be at least {{ limit }} characters long',
38+
'maxMessage' => 'Your foo cannot be longer than {{ limit }} characters',
39+
]),
40+
new NotBlank(['allowNull' => false]),
41+
new Regex([
42+
'pattern' => '/\d/',
43+
'message' => 'Your foo cannot contain a number',
44+
'match' => false,
45+
]),
46+
]),
47+
],
48+
])
49+
->add('bar', CollectionType::class, [
50+
'entry_type' => IntegerType::class,
51+
'allow_add' => true,
52+
'allow_delete' => true,
53+
'required' => false,
54+
'constraints' => new AtLeastOneOf([
55+
new All([new LessThanOrEqual(10), new GreaterThanOrEqual(5)]),
56+
new All(new EqualTo(value: 50)),
57+
new All(new DivisibleBy(0.25)),
58+
]),
59+
]);
60+
}
61+
}
62+
?>
63+
-----
64+
<?php
65+
66+
namespace Rector\Symfony\Tests\Symfony73\Rector\Class_\ConstraintOptionsToNamedArgumentsRector\Fixture;
67+
68+
use Symfony\Component\Form\AbstractType;
69+
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
70+
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
71+
use Symfony\Component\Form\Extension\Core\Type\TextType;
72+
use Symfony\Component\Form\FormBuilderInterface;
73+
use Symfony\Component\Validator\Constraints\All;
74+
use Symfony\Component\Validator\Constraints\AtLeastOneOf;
75+
use Symfony\Component\Validator\Constraints\Count;
76+
use Symfony\Component\Validator\Constraints\DivisibleBy;
77+
use Symfony\Component\Validator\Constraints\EqualTo;
78+
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
79+
use Symfony\Component\Validator\Constraints\Length;
80+
use Symfony\Component\Validator\Constraints\LessThanOrEqual;
81+
use Symfony\Component\Validator\Constraints\NotBlank;
82+
use Symfony\Component\Validator\Constraints\Regex;
83+
84+
class NestedConstraintForm extends AbstractType
85+
{
86+
public function buildForm(FormBuilderInterface $builder, array $options): void
87+
{
88+
$builder
89+
->add('foo', CollectionType::class, [
90+
'entry_type' => TextType::class,
91+
'allow_add' => true,
92+
'allow_delete' => true,
93+
'required' => false,
94+
'constraints' => [
95+
new Count(min: 3, max: 30),
96+
new All([
97+
new Length(min: 2, max: 50, minMessage: 'Your foo must be at least {{ limit }} characters long', maxMessage: 'Your foo cannot be longer than {{ limit }} characters'),
98+
new NotBlank(allowNull: false),
99+
new Regex(pattern: '/\d/', message: 'Your foo cannot contain a number', match: false),
100+
]),
101+
],
102+
])
103+
->add('bar', CollectionType::class, [
104+
'entry_type' => IntegerType::class,
105+
'allow_add' => true,
106+
'allow_delete' => true,
107+
'required' => false,
108+
'constraints' => new AtLeastOneOf([
109+
new All([new LessThanOrEqual(10), new GreaterThanOrEqual(5)]),
110+
new All(new EqualTo(value: 50)),
111+
new All(new DivisibleBy(0.25)),
112+
]),
113+
]);
114+
}
115+
}
116+
?>

rules/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
use PhpParser\Node;
88
use PhpParser\Node\Arg;
99
use PhpParser\Node\Expr\Array_;
10-
use PhpParser\Node\Expr\ArrayItem;
10+
use PhpParser\Node\ArrayItem;
11+
use PhpParser\Node\Expr;
1112
use PhpParser\Node\Expr\New_;
1213
use PhpParser\Node\Name;
1314
use PhpParser\Node\Name\FullyQualified;
@@ -85,8 +86,17 @@ public function refactor(Node $node): ?Node
8586
$array = $node->args[0]->value;
8687
$namedArgs = [];
8788

88-
foreach ($array->items as $item) {
89-
if (! $item instanceof ArrayItem || $item->key === null) {
89+
foreach ($array->items as $key => $item) {
90+
if (! $item instanceof ArrayItem) {
91+
continue;
92+
}
93+
94+
if (! $item->key instanceof Expr) {
95+
// handle nested array
96+
if ($item->value instanceof New_) {
97+
return null;
98+
}
99+
90100
continue;
91101
}
92102

0 commit comments

Comments
 (0)