diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md index f8e05a55c75..c9908e47053 100644 --- a/docs/AllRectorsOverview.md +++ b/docs/AllRectorsOverview.md @@ -1,4 +1,4 @@ -# All 447 Rectors Overview +# All 448 Rectors Overview - [Projects](#projects) - [General](#general) @@ -3134,6 +3134,40 @@ Remove temporary *Uuid relation properties ## DoctrineCodeQuality +### `ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector` + +- class: `Rector\DoctrineCodeQuality\Rector\Class_\ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector` + +Change array to ArrayCollection in setParameters method of query builder + +```diff + +-use Doctrine\ORM\EntityRepository; ++use Doctrine\Common\Collections\ArrayCollection;use Doctrine\ORM\EntityRepository;use Doctrine\ORM\Query\Parameter; + + class SomeRepository extends EntityRepository + { + public function getSomething() + { + return $this + ->createQueryBuilder('sm') + ->select('sm') + ->where('sm.foo = :bar') +- ->setParameters([ +- 'bar' => 'baz' +- ]) ++ ->setParameters(new ArrayCollection([ ++ new Parameter('bar', 'baz'), ++ ])) + ->getQuery() + ->getResult() + ; + } + } +``` + +
+ ### `InitializeDefaultEntityCollectionRector` - class: `Rector\DoctrineCodeQuality\Rector\Class_\InitializeDefaultEntityCollectionRector` diff --git a/packages/doctrine-code-quality/src/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector.php b/packages/doctrine-code-quality/src/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector.php new file mode 100644 index 00000000000..5dd529995f4 --- /dev/null +++ b/packages/doctrine-code-quality/src/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector.php @@ -0,0 +1,150 @@ +needToSkip($node)) { + return null; + } + + $methodArguments = $node->args; + if (count($methodArguments) !== 1) { + return null; + } + $firstArgument = $methodArguments[0]; + if (! $this->isArrayType($firstArgument->value)) { + return null; + } + + unset($node->args); + + $arrayCollection = $this->getNewArrayCollectionFromSetParametersArgument($firstArgument); + + $node->args = [new Arg($arrayCollection)]; + return $node; + } + + public function getDefinition(): RectorDefinition + { + return new RectorDefinition('Change array to ArrayCollection in setParameters method of query builder', [ + new CodeSample( + <<<'PHP' + +use Doctrine\ORM\EntityRepository; + +class SomeRepository extends EntityRepository +{ + public function getSomething() + { + return $this + ->createQueryBuilder('sm') + ->select('sm') + ->where('sm.foo = :bar') + ->setParameters([ + 'bar' => 'baz' + ]) + ->getQuery() + ->getResult() + ; + } +} +PHP + , + <<<'PHP' + +use Doctrine\Common\Collections\ArrayCollection;use Doctrine\ORM\EntityRepository;use Doctrine\ORM\Query\Parameter; + +class SomeRepository extends EntityRepository +{ + public function getSomething() + { + return $this + ->createQueryBuilder('sm') + ->select('sm') + ->where('sm.foo = :bar') + ->setParameters(new ArrayCollection([ + new Parameter('bar', 'baz'), + ])) + ->getQuery() + ->getResult() + ; + } +} +PHP + ), + ]); + } + + private function needToSkip(Node $node): bool + { + $classNode = $node->getAttribute(AttributeKey::CLASS_NODE); + if ($classNode === null) { + return true; + } + + //one of the cases when we are in the repo and it's extended from EntityRepository + if (! $this->isObjectType($classNode, 'Doctrine\ORM\EntityRepository')) { + return true; + } + if (! $this->isObjectType($node->var, 'Doctrine\ORM\EntityRepository')) { + return true; + } + + return ! $this->isName($node->name, 'setParameters'); + } + + private function getNewArrayCollectionFromSetParametersArgument(Arg $arg): New_ + { + /** @var Array_ $arrayExpression */ + $arrayExpression = $arg->value; + /** @var ArrayItem[] $firstArgumentArrayItems */ + $firstArgumentArrayItems = $arrayExpression->items; + $arrayCollectionArrayArguments = []; + foreach ($firstArgumentArrayItems as $firstArgumentArrayItem) { + if (! $firstArgumentArrayItem->key instanceof String_ || ! $firstArgumentArrayItem->value instanceof String_) { + throw new ShouldNotHappenException(); + } + $queryParameter = new New_(new FullyQualified('Doctrine\ORM\Query\Parameter')); + $queryParameter->args = [new Arg($firstArgumentArrayItem->key), new Arg($firstArgumentArrayItem->value)]; + $arrayCollectionArrayArguments[] = new ArrayItem($queryParameter); + } + + $arrayCollection = new New_(new FullyQualified('Doctrine\Common\Collections\ArrayCollection')); + + $arrayCollection->args = [new Arg(new Array_($arrayCollectionArrayArguments))]; + + return $arrayCollection; + } +} diff --git a/packages/doctrine-code-quality/tests/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionTest.php b/packages/doctrine-code-quality/tests/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionTest.php new file mode 100644 index 00000000000..8dbda3eac54 --- /dev/null +++ b/packages/doctrine-code-quality/tests/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionTest.php @@ -0,0 +1,30 @@ +doTestFile($file); + } + + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + protected function getRectorClass(): string + { + return ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector::class; + } +} diff --git a/packages/doctrine-code-quality/tests/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection/Fixture/extends_entity_repository.php.inc b/packages/doctrine-code-quality/tests/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection/Fixture/extends_entity_repository.php.inc new file mode 100644 index 00000000000..5efa429e973 --- /dev/null +++ b/packages/doctrine-code-quality/tests/Rector/Class_/ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection/Fixture/extends_entity_repository.php.inc @@ -0,0 +1,45 @@ +createQueryBuilder('sm') + ->select('sm') + ->where('sm.foo = :bar') + ->setParameters([ + 'bar' => 'baz', + ]) + ->getQuery() + ->getResult() + ; + } +} +?> +----- +createQueryBuilder('sm') + ->select('sm') + ->where('sm.foo = :bar') + ->setParameters(new \Doctrine\Common\Collections\ArrayCollection([new \Doctrine\ORM\Query\Parameter('bar', 'baz')])) + ->getQuery() + ->getResult() + ; + } +} +?>