diff --git a/composer.json b/composer.json
index 8145bde2889e..0266ad85f967 100644
--- a/composer.json
+++ b/composer.json
@@ -267,7 +267,7 @@
"bin/rector dump-rectors > docs/AllRectorsOverview.md",
"bin/rector dump-nodes > docs/NodesOverview.md"
],
- "rector-ci": "bin/rector process --config rector-ci.yaml --debug --dry-run",
+ "rector-ci": "bin/rector process --config rector-ci.yaml --dry-run",
"rector": "bin/rector process --config rector-ci.yaml --ansi"
},
"config": {
diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md
index 5372c597c076..7f75848f27c6 100644
--- a/docs/AllRectorsOverview.md
+++ b/docs/AllRectorsOverview.md
@@ -1,4 +1,4 @@
-# All 498 Rectors Overview
+# All 499 Rectors Overview
- [Projects](#projects)
- [General](#general)
@@ -8880,6 +8880,27 @@ Convert missing class reference to string
+### `RemoveFinalFromEntityRector`
+
+- class: [`Rector\Restoration\Rector\Class_\RemoveFinalFromEntityRector`](/../master/rules/restoration/src/Rector/Class_/RemoveFinalFromEntityRector.php)
+- [test fixtures](/../master/rules/restoration/tests/Rector/Class_/RemoveFinalFromEntityRector/Fixture)
+
+Remove final from Doctrine entities
+
+```diff
+ use Doctrine\ORM\Mapping as ORM;
+
+ /**
+ * @ORM\Entity
+ */
+-final class SomeClass
++class SomeClass
+ {
+ }
+```
+
+
+
## SOLID
### `ChangeIfElseValueAssignToEarlyReturnRector`
diff --git a/rules/restoration/src/Rector/Class_/RemoveFinalFromEntityRector.php b/rules/restoration/src/Rector/Class_/RemoveFinalFromEntityRector.php
new file mode 100644
index 000000000000..0e0b1e09f150
--- /dev/null
+++ b/rules/restoration/src/Rector/Class_/RemoveFinalFromEntityRector.php
@@ -0,0 +1,73 @@
+isDoctrineEntityClass($node)) {
+ return null;
+ }
+
+ if (! $node->isFinal()) {
+ return null;
+ }
+
+ $this->removeFinal($node);
+
+ return $node;
+ }
+}
diff --git a/rules/restoration/tests/Rector/Class_/RemoveFinalFromEntityRector/Fixture/fixture.php.inc b/rules/restoration/tests/Rector/Class_/RemoveFinalFromEntityRector/Fixture/fixture.php.inc
new file mode 100644
index 000000000000..47bd269382e6
--- /dev/null
+++ b/rules/restoration/tests/Rector/Class_/RemoveFinalFromEntityRector/Fixture/fixture.php.inc
@@ -0,0 +1,29 @@
+
+-----
+
diff --git a/rules/restoration/tests/Rector/Class_/RemoveFinalFromEntityRector/RemoveFinalFromEntityRectorTest.php b/rules/restoration/tests/Rector/Class_/RemoveFinalFromEntityRector/RemoveFinalFromEntityRectorTest.php
new file mode 100644
index 000000000000..dced6dc23dd5
--- /dev/null
+++ b/rules/restoration/tests/Rector/Class_/RemoveFinalFromEntityRector/RemoveFinalFromEntityRectorTest.php
@@ -0,0 +1,30 @@
+doTestFile($file);
+ }
+
+ public function provideData(): Iterator
+ {
+ return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
+ }
+
+ protected function getRectorClass(): string
+ {
+ return RemoveFinalFromEntityRector::class;
+ }
+}
diff --git a/src/Rector/AbstractRector/AbstractRectorTrait.php b/src/Rector/AbstractRector/AbstractRectorTrait.php
index af4732aeeed7..36cc18c3f827 100644
--- a/src/Rector/AbstractRector/AbstractRectorTrait.php
+++ b/src/Rector/AbstractRector/AbstractRectorTrait.php
@@ -44,4 +44,9 @@ protected function isNonAnonymousClass(?Node $node): bool
return ! Strings::contains($name, 'AnonymousClass');
}
+
+ protected function removeFinal(Class_ $node): void
+ {
+ $node->flags -= Class_::MODIFIER_FINAL;
+ }
}