8000 Merge pull request #3704 from rectorphp/symfony3-entry-type · rectorphp/rector@965cef9 · GitHub
[go: up one dir, main page]

Skip t 8000 o content

Commit 965cef9

Browse files
authored
Merge pull request #3704 from rectorphp/symfony3-entry-type
2 parents 2350472 + 4c88e5d commit 965cef9

File tree

10 files changed

+261
-165
lines changed

10 files changed

+261
-165
lines changed

docs/rector_rules_overview.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10899,11 +10899,8 @@ Changes createForm(new FormType), add(new FormType) to ones with "FormType::clas
1089910899
{
1090010900
public function action()
1090110901
{
10902-
- $form = $this->createForm(new TeamType, $entity, [
10903-
+ $form = $this->createForm(TeamType::class, $entity, [
10904-
'action' => $this->generateUrl('teams_update', ['id' => $entity->getId()]),
10905-
'method' => 'PUT',
10906-
]);
10902+
- $form = $this->createForm(new TeamType, $entity);
10903+
+ $form = $this->createForm(TeamType::class, $entity);
1090710904
}
1090810905
}
1090910906
```
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Symfony\NodeFactory;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\ArrayDimFetch;
9+
use PhpParser\Node\Expr\Assign;
10+
use PhpParser\Node\Expr\Variable;
11+
use PhpParser\Node\Name\FullyQualified;
12+
use PhpParser\Node\Param;
13+
use PhpParser\Node\Scalar\String_;
14+
use PhpParser\Node\Stmt\ClassMethod;
15+
use PhpParser\Node\Stmt\Expression;
16+
use Rector\Core\PhpParser\Builder\MethodBuilder;
17+
use Rector\Core\PhpParser\Builder\ParamBuilder;
18+
use Rector\NodeNameResolver\NodeNameResolver;
19+
20+
final class BuilderFormNodeFactory
21+
{
22+
/**
23+
* @var NodeNameResolver
24+
*/
25+
private $nodeNameResolver;
26+
27+
public function __construct(NodeNameResolver $nodeNameResolver)
28+
{
29+
$this->nodeNameResolver = $nodeNameResolver;
30+
}
31+
32+
public function create(ClassMethod $constructorClassMethod): ClassMethod
33+
{
34+
$formBuilderParam = $this->createBuilderParam();
35+
36+
$optionsParam = $this->createOptionsParam();
37+
38+
$classMethodBuilder = new MethodBuilder('buildForm');
39+
$classMethodBuilder->makePublic();
40+
$classMethodBuilder->addParam($formBuilderParam);
41+
$classMethodBuilder->addParam($optionsParam);
42+
43+
// raw copy stmts from ctor
44+
$options = $this->replaceParameterAssignWithOptionAssign((array) $constructorClassMethod->stmts, $optionsParam);
45+
$classMethodBuilder->addStmts($options);
46+
47+
return $classMethodBuilder->getNode();
48+
}
49+
50+
/**
51+
* @param Node[] $nodes
52+
* @return Node[]
53+
*
54+
* $this->value = $value
55+
* ↓
56+
* $this->value = $options['value']
57+
*/
58+
private function replaceParameterAssignWithOptionAssign(array $nodes, Param $param): array
59+
{
60+
foreach ($nodes as $expression) {
61+
if (! $expression instanceof Expression) {
62+
continue;
63+
}
64+
65+
$node = $expression->expr;
66+
if (! $node instanceof Assign) {
67+
continue;
68+
}
69+
70+
$variableName = $this->nodeNameResolver->getName($node->var);
71+
if ($variableName === null) {
72+
continue;
73+
}
74+
75+
if ($node->expr instanceof Variable) {
76+
$node->expr = new ArrayDimFetch($param->var, new String_($variableName));
77+
}
78+
}
79+
80+
return $nodes;
81+
}
82+
83+
private function createBuilderParam(): Param
84+
{
85+
$builderParamBuilder = new ParamBuilder('builder');
86+
$builderParamBuilder->setType(new FullyQualified('Symfony\Component\Form\FormBuilderInterface'));
87+
88+
return $builderParamBuilder->getNode();
89+
}
90+
91+
private function createOptionsParam(): Param
92+
{
93+
$optionsParamBuilder = new ParamBuilder('options');
94+
$optionsParamBuilder->setType('array');
95+
96+
return $optionsParamBuilder->getNode();
97+
}
98+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Symfony\NodeFactory;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Arg;
9+
use PhpParser\Node\Expr\Array_;
10+
use PhpParser\Node\Expr\ArrayItem;
11+
use PhpParser\Node\Expr\ConstFetch;
12+
use PhpParser\Node\Expr\MethodCall;
13+
use PhpParser\Node\Identifier;
14+
use PhpParser\Node\Name;
15+
use PhpParser\Node\Name\FullyQualified;
16+
use PhpParser\Node\Param;
17+
use PhpParser\Node\Scalar\String_;
18+
use PhpParser\Node\Stmt\ClassMethod;
19+
use Rector\Core\PhpParser\Builder\MethodBuilder;
20+
use Rector\Core\PhpParser\Builder\ParamBuilder;
21+
22+
final class ConfigureOptionsNodeFactory
23+
{
24+
/**
25+
* @param array<string, Node\Arg> $namesToArgs
26+
*/
27+
public function create(array $namesToArgs): ClassMethod
28+
{
29+
$resolverParam = $this->createParam();
30+
$args = $this->createArgs($namesToArgs);
31+
32+
$setDefaultsMethodCall = new MethodCall($resolverParam->var, new Identifier('setDefaults'), $args);
33+
34+
$methodBuilder = new MethodBuilder('configureOptions');
35+
$methodBuilder->makePublic();
36+
$methodBuilder->addParam($resolverParam);
37+
$methodBuilder->addStmt($setDefaultsMethodCall);
38+
39+
return $methodBuilder->getNode();
40+
}
41+
42+
private function createNull(): ConstFetch
43+
{
44+
return new ConstFetch(new Name('null'));
45+
}
46+
47+
private function createParam(): Param
48+
{
49+
$paramBuilder = new ParamBuilder('resolver');
50+
$paramBuilder->setType(new FullyQualified('Symfony\Component\OptionsResolver\OptionsResolver'));
51+
52+
return $paramBuilder->getNode();
53+
}
54+
55+
/**
56+
* @param Arg[] $namesToArgs
57+
* @return Arg[]
58+
*/
59+
private function createArgs(array $namesToArgs): array
60+
{
61+
$array = new Array_();
62+
foreach (array_keys($namesToArgs) as $optionName) {
63+
$array->items[] = new ArrayItem($this->createNull(), new String_($optionName));
64+
}
65+
66+
return [new Arg($array)];
67+
}
68+
}

rules/symfony/src/Rector/MethodCall/AbstractFormAddRector.php

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212

1313
abstract class AbstractFormAddRector extends AbstractRector
1414
{
15+
/**
16+
* @var string[]
17+
*/
18+
private const FORM_TYPES = ['Symfony\Component\Form\FormBuilderInterface', 'Symfony\Component\Form\FormInterface'];
19+
1520
/**
1621
* @var FormTypeStringToTypeProvider
1722
*/
@@ -25,17 +30,9 @@ public function autowireAbstractFormAddRector(FormTypeStringToTypeProvider $form
2530
$this->formTypeStringToTypeProvider = $formTypeStringToTypeProvider;
2631
}
2732

28-
/**
29-
* @return string[]
30-
*/
31-
public function getNodeTypes(): array
32-
{
33-
return [MethodCall::class];
34-
}
35-
3633
protected function isFormAddMethodCall(MethodCall $methodCall): bool
3734
{
38-
if (! $this->isObjectType($methodCall->var, 'Symfony\Component\Form\FormBuilderInterface')) {
35+
if (! $this->isObjectTypes($methodCall->var, self::FORM_TYPES)) {
3936
return false;
4037
}
4138

0 commit comments

Comments
 (0)
0