Skip to content

Commit a5ff686

Browse files
authored
tv skip param converter (#876)
* add fixture * skip param converter param types
1 parent a71ee0d commit a5ff686

4 files changed

Lines changed: 81 additions & 2 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\ControllerMethodInjectionToConstructorRector\Fixture;
6+
7+
use Rector\Symfony\Tests\CodeQuality\Rector\Class_\ControllerMethodInjectionToConstructorRector\Source\SomeConvertedEntity;
8+
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
9+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
10+
use Symfony\Component\Routing\Annotation\Route;
11+
12+
final class SkipParamConverter extends AbstractController
13+
{
14+
#[ParamConverter('entity', class: SomeConvertedEntity::class)]
15+
#[Route('/some-action', name: 'some_action')]
16+
public function someAction(SomeConvertedEntity $entity)
17+
{
18+
}
19+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\ControllerMethodInjectionToConstructorRector\Source;
6+
7+
final class SomeConvertedEntity
8+
{
9+
}

rules/CodeQuality/Rector/Class_/ControllerMethodInjectionToConstructorRector.php

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
use PhpParser\Node\Name;
1313
use PhpParser\Node\Stmt\Class_;
1414
use PhpParser\Node\Stmt\ClassMethod;
15+
use Rector\Doctrine\NodeAnalyzer\AttributeFinder;
1516
use Rector\NodeManipulator\ClassDependencyManipulator;
17+
use Rector\PhpParser\Node\Value\ValueResolver;
1618
use Rector\PostRector\ValueObject\PropertyMetadata;
1719
use Rector\Rector\AbstractRector;
1820
use Rector\StaticTypeMapper\StaticTypeMapper;
1921
use Rector\Symfony\Bridge\NodeAnalyzer\ControllerMethodAnalyzer;
22+
use Rector\Symfony\Enum\SensioAttribute;
2023
use Rector\Symfony\Enum\SymfonyClass;
2124
use Rector\Symfony\TypeAnalyzer\ControllerAnalyzer;
2225
use Rector\ValueObject\MethodName;
@@ -33,6 +36,8 @@ public function __construct(
3336
private readonly ControllerMethodAnalyzer $controllerMethodAnalyzer,
3437
private readonly ClassDependencyManipulator $classDependencyManipulator,
3538
private readonly StaticTypeMapper $staticTypeMapper,
39+
private readonly AttributeFinder $attributeFinder,
40+
private readonly ValueResolver $valueResolver,
3641
) {
3742
}
3843

@@ -108,15 +113,23 @@ public function refactor(Node $node): ?Node
108113
continue;
109114
}
110115

116+
$entityClasses = $this->resolveParamConverterEntityClasses($classMethod);
117+
111118
foreach ($classMethod->getParams() as $key => $param) {
112119
// skip scalar and empty values, as not services
113120
if ($param->type === null || $param->type instanceof Identifier) {
114121
continue;
115122
}
116123

117124
// request is allowed
118-
if ($param->type instanceof Name && $this->isName($param->type, SymfonyClass::REQUEST)) {
119-
continue;
125+
if ($param->type instanceof Name) {
126+
if ($this->isName($param->type, SymfonyClass::REQUEST)) {
127+
continue;
128+
}
129+
130+
if ($this->isNames($param->type, $entityClasses)) {
131+
continue;
132+
}
120133
}
121134

122135
// @todo allow parameter converter
@@ -188,4 +201,31 @@ private function shouldSkipClassMethod(ClassMethod $classMethod): bool
188201

189202
return ! $this->controllerMethodAnalyzer->isAction($classMethod);
190203
}
204+
205+
/**
206+
* @return string[]
207+
*/
208+
private function resolveParamConverterEntityClasses(ClassMethod $classMethod): array
209+
{
210+
$entityClasses = [];
211+
212+
$paramConverterAttributes = $this->attributeFinder->findManyByClass(
213+
$classMethod,
214+
SensioAttribute::PARAM_CONVERTER
215+
);
216+
foreach ($paramConverterAttributes as $paramConverterAttribute) {
217+
foreach ($paramConverterAttribute->args as $arg) {
218+
if ($arg->name instanceof Identifier && $this->isName($arg->name, 'class')) {
219+
$entityClass = $this->valueResolver->getValue($arg->value);
220+
if (! is_string($entityClass)) {
221+
continue;
222+
}
223+
224+
$entityClasses[] = $entityClass;
225+
}
226+
}
227+
}
228+
229+
return $entityClasses;
230+
}
191231
}

stubs/Symfony/Bundle/FrameworkExtraBundle/Configuration/ParamConverter.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,15 @@
44

55
class ParamConverter
66
{
7+
/**
8+
* @param array|string $data
9+
*/
10+
public function __construct(
11+
$data = [],
12+
string $class = null,
13+
array $options = [],
14+
bool $isOptional = false,
15+
string $converter = null
16+
) {
17+
}
718
}

0 commit comments

Comments
 (0)