Merge pull request #2821 from vladyslavstartsev/setParameters-to-ArrayCollection

rector for doctrine setParameters method
This commit is contained in:
Tomas Votruba 2020-02-12 10:48:37 +01:00 committed by GitHub
commit 6d944620b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 260 additions and 1 deletions

View File

@ -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()
;
}
}
```
<br>
### `InitializeDefaultEntityCollectionRector`
- class: `Rector\DoctrineCodeQuality\Rector\Class_\InitializeDefaultEntityCollectionRector`

View File

@ -0,0 +1,150 @@
<?php
declare(strict_types=1);
namespace Rector\DoctrineCodeQuality\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\String_;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
* @see https://github.com/doctrine/orm/blob/2.7/UPGRADE.md#query-querybuilder-and-nativequery-parameters-bc-break
*
* @see \Rector\DoctrineCodeQuality\Tests\Rector\Class_\ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection\ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionTest
*/
class ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector extends AbstractRector
{
public function getNodeTypes(): array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if ($this->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;
}
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Rector\DoctrineCodeQuality\Tests\Rector\Class_\ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection;
use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\DoctrineCodeQuality\Rector\Class_\ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector;
final class ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $file): void
{
$this->doTestFile($file);
}
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
protected function getRectorClass(): string
{
return ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector::class;
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace Rector\DoctrineCodeQuality\Tests\Rector\Class_\ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection\Fixture;
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
namespace Rector\DoctrineCodeQuality\Tests\Rector\Class_\ChangeQuerySetParametersMethodParameterFromArrayToArrayCollection\Fixture;
use Doctrine\ORM\EntityRepository;
class SomeRepository extends EntityRepository
{
public function getSomething()
{
return $this
->createQueryBuilder('sm')
->select('sm')
->where('sm.foo = :bar')
->setParameters(new \Doctrine\Common\Collections\ArrayCollection([new \Doctrine\ORM\Query\Parameter('bar', 'baz')]))
->getQuery()
->getResult()
;
}
}
?>