rector/vendor/rector/rector-doctrine/docs/rector_rules_overview.md
Tomas Votruba 11b9220a05 Updated Rector to commit b4eb883e9110f50607ce2eed629c237b5e7e7356
b4eb883e91 [DeadCode] Skip isset() from property fetch from docblock on RemoveAlwaysTrueIfConditionRector (#5754)
2024-03-22 00:10:36 +00:00

12 KiB

19 Rules Overview

ChangeCompositeExpressionAddMultipleWithWithRector

Change CompositeExpression ->addMultiple($parts) to ->with(...$parts)

 use Doctrine\ORM\EntityRepository;
 use Doctrine\DBAL\Query\Expression\CompositeExpression;

 class SomeRepository extends EntityRepository
 {
     public function getSomething($parts)
     {
         $compositeExpression = CompositeExpression::and('', ...$parts);
-        $compositeExpression->addMultiple($parts);
+        $compositeExpression->with(...$parts);
     }
 }

CorrectDefaultTypesOnEntityPropertyRector

Change default value types to match Doctrine annotation type

 use Doctrine\ORM\Mapping as ORM;

 /**
  * @ORM\Entity()
  */
 class User
 {
     /**
      * @ORM\Column(name="is_old", type="boolean")
      */
-    private $isOld = '0';
+    private $isOld = false;
 }

EventSubscriberInterfaceToAttributeRector

Replace EventSubscriberInterface with AsDoctrineListener attribute(s)

+use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
 use Doctrine\ORM\Event\PrePersistEventArgs;
 use Doctrine\ORM\Event\PostUpdateEventArgs;
-use Doctrine\Common\EventSubscriber;
 use Doctrine\ORM\Events;

-class MyEventSubscriber implements EventSubscriber
+#[AsDoctrineListener(event: Events::postUpdate)]
+#[AsDoctrineListener(event: Events::prePersist)]
+class MyEventSubscriber
 {
-    public function getSubscribedEvents()
-    {
-        return array(
-            Events::postUpdate,
-            Events::prePersist,
-        );
-    }
-
     public function postUpdate(PostUpdateEventArgs $args)
     {
         // ...
     }

     public function prePersist(PrePersistEventArgs $args)
     {
         // ...
     }
 }

ExplicitRelationCollectionRector

Use explicit collection in one-to-many relations of Doctrine entity

+use Doctrine\ORM\Mapping\Entity;
 use Doctrine\ORM\Mapping\OneToMany;
-use Doctrine\ORM\Mapping\Entity;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;

 #[Entity]
 class SomeClass
 {
     #[OneToMany(targetEntity: 'SomeClass')]
-    private $items = [];
+    private Collection $items;
+
+    public function __construct()
+    {
+        $this->items = new ArrayCollection();
+    }
 }

ExtractArrayArgOnQueryBuilderSelectRector

Extract array arg on QueryBuilder select, addSelect, groupBy, addGroupBy

 function query(\Doctrine\DBAL\Query\QueryBuilder $queryBuilder)
 {
-    $query = $queryBuilder->select(['u.id', 'p.id']);
+    $query = $queryBuilder->select('u.id', 'p.id');
 }

ImproveDoctrineCollectionDocTypeInEntityRector

Improve @var, @param and @return types for Doctrine collections to make them useful both for PHPStan and PHPStorm

 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;

 /**
  * @ORM\Entity
  */
 class SomeClass
 {
     /**
      * @ORM\OneToMany(targetEntity=Trainer::class, mappedBy="trainer")
-     * @var Collection|Trainer[]
+     * @var Collection<int, Trainer>
      */
     private $trainings = [];
 }

InitializeDefaultEntityCollectionRector

Initialize collection property in Entity constructor

 use Doctrine\ORM\Mapping as ORM;

 /**
  * @ORM\Entity
  */
 class SomeClass
 {
     /**
      * @ORM\OneToMany(targetEntity="MarketingEvent")
      */
     private $marketingEvents = [];
+
+    public function __construct()
+    {
+        $this->marketingEvents = new ArrayCollection();
+    }
 }

IterateToToIterableRector

Change iterate() => toIterable()

 use Doctrine\ORM\EntityRepository;
 use Doctrine\ORM\Internal\Hydration\IterableResult;

 class SomeRepository extends EntityRepository
 {
-    public function run(): IterateResult
+    public function run(): iterable
     {
         /** @var \Doctrine\ORM\AbstractQuery $query */
         $query = $this->getEntityManager()->select('e')->from('entity')->getQuery();

-        return $query->iterate();
+        return $query->toIterable();
     }
 }

MakeEntityDateTimePropertyDateTimeInterfaceRector

Make maker bundle generate DateTime property accept DateTimeInterface too

 use Doctrine\ORM\Mapping as ORM;

 /**
  * @ORM\Entity()
  */
 class User
 {
     /**
-     * @var DateTime|null
+     * @var DateTimeInterface|null
      */
     private $bornAt;

     public function setBornAt(DateTimeInterface $bornAt)
     {
         $this->bornAt = $bornAt;
     }
 }

MoveCurrentDateTimeDefaultInEntityToConstructorRector

Move default value for entity property to constructor, the safest place

 use Doctrine\ORM\Mapping as ORM;

 /**
  * @ORM\Entity()
  */
 class User
 {
     /**
      * @var DateTimeInterface
      *
-     * @ORM\Column(type="datetime", nullable=false, options={"default"="now()"})
+     * @ORM\Column(type="datetime", nullable=false)
      */
-    private $when = 'now()';
+    private $when;
+
+    public function __construct()
+    {
+        $this->when = new \DateTime();
+    }
 }

OrderByKeyToClassConstRector

Replace OrderBy Attribute ASC/DESC with class constant from Criteria

 use Doctrine\ORM\Mapping as ORM;

 class ReplaceOrderByAscWithClassConstant
 {
-    #[ORM\OrderBy(['createdAt' => 'ASC'])]
+    #[ORM\OrderBy(['createdAt' => \Doctrine\Common\Collections\Criteria::ASC])]
     protected \DateTimeInterface $messages;
 }
 ?>

RemoveEmptyTableAttributeRector

Remove empty Table attribute on entities because it's useless

 <?php

 use Doctrine\ORM\Mapping as ORM;

-#[ORM\Table]
 #[ORM\Entity]
 class Product
 {
 }

ReplaceFetchAllMethodCallRector

Change Doctrine\DBAL\Connection and Doctrine\DBAL\Driver\ResultStatement ->fetchAll() to ->fetchAllAssociative() and other replacements

 use Doctrine\DBAL\Connection;

 class SomeClass
 {
     public function run(Connection $connection)
     {
-        return $connection->fetchAll();
+        return $connection->fetchAllAssociative();
     }
 }

ReplaceLifecycleEventArgsByDedicatedEventArgsRector

Replace Doctrine\ORM\Event\LifecycleEventArgs with specific event classes based on the function call

-use Doctrine\ORM\Event\LifecycleEventArgs;
+use Doctrine\ORM\Event\PrePersistEventArgs;

 class PrePersistExample
 {
-    public function prePersist(LifecycleEventArgs $args)
+    public function prePersist(PrePersistEventArgs $args)
     {
         // ...
     }
 }

TypedPropertyFromColumnTypeRector

Complete @var annotations or types based on @ORM\Column

 use Doctrine\ORM\Mapping as ORM;

 class SimpleColumn
 {
     /**
      * @ORM\Column(type="string")
      */
-    private $name;
+    private string|null $name = null;
 }

TypedPropertyFromDoctrineCollectionRector

Add typed property based on Doctrine collection

 use Doctrine\ORM\Mapping as ORM;
 use App\Entity\TrainingTerm;

 /**
  * @ORM\Entity
  */
 class DoctrineCollection
 {
     /**
      * @ORM\OneToMany(targetEntity="App\Entity\TrainingTerm", mappedBy="training")
      * @var TrainingTerm[]|Collection
      */
-    private $trainingTerms;
+    private \Doctrine\Common\Collections\Collection $trainingTerms;
 }

TypedPropertyFromToManyRelationTypeRector

Complete @var annotations or types based on @ORM*toMany annotations or attributes

 use Doctrine\ORM\Mapping as ORM;

 class SimpleColumn
 {
     /**
      * @ORM\OneToMany(targetEntity="App\Product")
+     * @var \Doctrine\Common\Collections\Collection<int, \App\Product>
      */
-    private $products;
+    private \Doctrine\Common\Collections\Collection $products;
 }

TypedPropertyFromToOneRelationTypeRector

Complete @var annotations or types based on @ORM*toOne annotations or attributes

 use Doctrine\ORM\Mapping as ORM;

 class SimpleColumn
 {
     /**
      * @ORM\OneToOne(targetEntity="App\Company\Entity\Company")
      */
-    private $company;
+    private ?\App\Company\Entity\Company $company = null;
 }

YamlToAttributeDoctrineMappingRector

Converts YAML Doctrine Entity mapping to particular annotation mapping

🔧 configure it!

+use Doctrine\ORM\Mapping as ORM;
+
+#[ORM\Entity]
 class SomeEntity
 {
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column(type: 'integer')]
     private $id;

+    #[ORM\Column(type: 'string')]
     private $name;
 }