diff --git a/.github/workflows/code_analysis.yaml b/.github/workflows/code_analysis.yaml index b137903f..f949625f 100644 --- a/.github/workflows/code_analysis.yaml +++ b/.github/workflows/code_analysis.yaml @@ -19,9 +19,6 @@ jobs: - name: 'Active Classes' run: vendor/bin/class-leak check config src rules --skip-suffix "Rector" - - - name: "Validate docs" - run: vendor/bin/rule-doc-generator validate src rules name: ${{ matrix.actions.name }} runs-on: ubuntu-latest diff --git a/README.md b/README.md index ba34bf4f..4a98c6bc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rector Rules for Doctrine -See available [Doctrine rules](https://getrector.com/find-rule?query=doctrine+rules) +See available [Doctrine rules](https://getrector.com/find-rule?activeRectorSetGroup=doctrine) ## Install diff --git a/composer.json b/composer.json index 5bd27537..df7ee474 100644 --- a/composer.json +++ b/composer.json @@ -16,14 +16,13 @@ "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^10.5", "rector/rector-src": "dev-main", - "rector/type-perfect": "^0.1.8", + "rector/type-perfect": "^0.2", "symplify/easy-coding-standard": "^12.3", "symplify/phpstan-extensions": "^11.4", "symplify/phpstan-rules": "^13.0", - "symplify/rule-doc-generator": "^12.2.5", "symplify/vendor-patches": "^11.3", "tomasvotruba/class-leak": "^0.2.15", - "tomasvotruba/unused-public": "^0.3", + "tomasvotruba/unused-public": "^0.4", "tracy/tracy": "^2.10" }, "autoload": { diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md index d78e20f7..e7daf1fa 100644 --- a/docs/rector_rules_overview.md +++ b/docs/rector_rules_overview.md @@ -1,475 +1,5 @@ -# 18 Rules Overview +# Rules Overview **This overview is deprecated and replaced by more advanced web search. There you can search and filter by nodes, copy-paste configs for configurable rules and more.** -Use https://getrector.com/find-rule?query=doctrine+rules instead! - ---- - -## AddReturnDocBlockToCollectionPropertyGetterByToManyAnnotationRector - -Adds `@return` PHPDoc type to Collection property getter by *ToMany annotation/attribute - -- class: [`Rector\Doctrine\CodeQuality\Rector\Class_\AddReturnDocBlockToCollectionPropertyGetterByToManyAnnotationRector`](../rules/CodeQuality/Rector/Class_/AddReturnDocBlockToCollectionPropertyGetterByToManyAnnotationRector.php) - -```diff --use App\Entity\Training; -- - /** - * @ORM\Entity - */ - final class Trainer - { - /** - * @ORM\OneToMany(targetEntity=Training::class) - */ - private $trainings; - -+ /** -+ * @return \Doctrine\Common\Collections\Collection -+ */ - public function getTrainings() - { - return $this->trainings; - } - } -``` - -
- -## ChangeCompositeExpressionAddMultipleWithWithRector - -Change CompositeExpression ->addMultiple($parts) to ->with(...$parts) - -- class: [`Rector\Doctrine\Dbal40\Rector\MethodCall\ChangeCompositeExpressionAddMultipleWithWithRector`](../rules/Dbal40/Rector/MethodCall/ChangeCompositeExpressionAddMultipleWithWithRector.php) - -```diff - 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 - -- class: [`Rector\Doctrine\CodeQuality\Rector\Property\CorrectDefaultTypesOnEntityPropertyRector`](../rules/CodeQuality/Rector/Property/CorrectDefaultTypesOnEntityPropertyRector.php) - -```diff - 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) - -- class: [`Rector\Doctrine\Bundle210\Rector\Class_\EventSubscriberInterfaceToAttributeRector`](../rules/Bundle210/Rector/Class_/EventSubscriberInterfaceToAttributeRector.php) - -```diff -+use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; - use Doctrine\ORM\Event\PrePersistEventArgs; - use Doctrine\ORM\Event\PostUpdateEventArgs; --use Doctrine\Common\EventSubscriberInterface; - use Doctrine\ORM\Events; - --class MyEventSubscriber implements EventSubscriberInterface -+#[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 Collection object type for one-to-many relations of Doctrine entity/ODM document - -- class: [`Rector\Doctrine\CodeQuality\Rector\Class_\ExplicitRelationCollectionRector`](../rules/CodeQuality/Rector/Class_/ExplicitRelationCollectionRector.php) - -```diff -+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 - -- class: [`Rector\Doctrine\Dbal211\Rector\MethodCall\ExtractArrayArgOnQueryBuilderSelectRector`](../rules/Dbal211/Rector/MethodCall/ExtractArrayArgOnQueryBuilderSelectRector.php) - -```diff - 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 - -- class: [`Rector\Doctrine\CodeQuality\Rector\Property\ImproveDoctrineCollectionDocTypeInEntityRector`](../rules/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector.php) - -```diff - 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 - */ - private $trainings = []; - } -``` - -
- -## IterateToToIterableRector - -Change `iterate()` => `toIterable()` - -- class: [`Rector\Doctrine\Orm28\Rector\MethodCall\IterateToToIterableRector`](../rules/Orm28/Rector/MethodCall/IterateToToIterableRector.php) - -```diff - 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 - -- class: [`Rector\Doctrine\CodeQuality\Rector\Property\MakeEntityDateTimePropertyDateTimeInterfaceRector`](../rules/CodeQuality/Rector/Property/MakeEntityDateTimePropertyDateTimeInterfaceRector.php) - -```diff - 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 - -- class: [`Rector\Doctrine\CodeQuality\Rector\Class_\MoveCurrentDateTimeDefaultInEntityToConstructorRector`](../rules/CodeQuality/Rector/Class_/MoveCurrentDateTimeDefaultInEntityToConstructorRector.php) - -```diff - 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 - -- class: [`Rector\Doctrine\CodeQuality\Rector\Property\OrderByKeyToClassConstRector`](../rules/CodeQuality/Rector/Property/OrderByKeyToClassConstRector.php) - -```diff - 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 - -- class: [`Rector\Doctrine\CodeQuality\Rector\Class_\RemoveEmptyTableAttributeRector`](../rules/CodeQuality/Rector/Class_/RemoveEmptyTableAttributeRector.php) - -```diff - - -## ReplaceFetchAllMethodCallRector - -Change `Doctrine\DBAL\Connection` and `Doctrine\DBAL\Driver\ResultStatement` `->fetchAll()` to `->fetchAllAssociative()` and other replacements - -- class: [`Rector\Doctrine\Dbal211\Rector\MethodCall\ReplaceFetchAllMethodCallRector`](../rules/Dbal211/Rector/MethodCall/ReplaceFetchAllMethodCallRector.php) - -```diff - 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 - -- class: [`Rector\Doctrine\Orm214\Rector\Param\ReplaceLifecycleEventArgsByDedicatedEventArgsRector`](../rules/Orm214/Rector/Param/ReplaceLifecycleEventArgsByDedicatedEventArgsRector.php) - -```diff --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 - -- class: [`Rector\Doctrine\CodeQuality\Rector\Property\TypedPropertyFromColumnTypeRector`](../rules/CodeQuality/Rector/Property/TypedPropertyFromColumnTypeRector.php) - -```diff - use Doctrine\ORM\Mapping as ORM; - - class SimpleColumn - { - /** - * @ORM\Column(type="string") - */ -- private $name; -+ private string|null $name = null; - } -``` - -
- -## TypedPropertyFromToManyRelationTypeRector - -Complete `@var` annotations or types based on @ORM\*toMany annotations or attributes - -- class: [`Rector\Doctrine\CodeQuality\Rector\Property\TypedPropertyFromToManyRelationTypeRector`](../rules/CodeQuality/Rector/Property/TypedPropertyFromToManyRelationTypeRector.php) - -```diff - use Doctrine\ORM\Mapping as ORM; - - class SimpleColumn - { - /** - * @ORM\OneToMany(targetEntity="App\Product") -+ * @var \Doctrine\Common\Collections\Collection - */ -- private $products; -+ private \Doctrine\Common\Collections\Collection $products; - } -``` - -
- -## TypedPropertyFromToOneRelationTypeRector - -Complete `@var` annotations or types based on @ORM\*toOne annotations or attributes - -:wrench: **configure it!** - -- class: [`Rector\Doctrine\CodeQuality\Rector\Property\TypedPropertyFromToOneRelationTypeRector`](../rules/CodeQuality/Rector/Property/TypedPropertyFromToOneRelationTypeRector.php) - -```diff - use Doctrine\ORM\Mapping as ORM; - - class SimpleColumn - { - /** - * @ORM\OneToOne(targetEntity="App\Company\Entity\Company") - * @ORM\JoinColumn(nullable=false) - */ -- private $company; -+ private ?\App\Company\Entity\Company $company = null; - } -``` - -
- -```diff - use Doctrine\ORM\Mapping as ORM; - - class SimpleColumn - { - /** - * @ORM\OneToOne(targetEntity="App\Company\Entity\Company") - * @ORM\JoinColumn(nullable=false) - */ -- private $company; -+ private \App\Company\Entity\Company $company; - } -``` - -
- -## YamlToAttributeDoctrineMappingRector - -Converts YAML Doctrine Entity mapping to particular annotation mapping - -:wrench: **configure it!** - -- class: [`Rector\Doctrine\CodeQuality\Rector\Class_\YamlToAttributeDoctrineMappingRector`](../rules/CodeQuality/Rector/Class_/YamlToAttributeDoctrineMappingRector.php) - -```diff -+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; - } -``` - -
+Use https://getrector.com/find-rule?activeRectorSetGroup=doctrine instead! diff --git a/phpstan.neon b/phpstan.neon index cf0f5122..e805ece3 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,8 +4,6 @@ includes: parameters: level: 8 - reportUnmatchedIgnoredErrors: false - paths: - config - src