diff --git a/README.md b/README.md
index bc6b1db6..7148323e 100644
--- a/README.md
+++ b/README.md
@@ -1065,6 +1065,28 @@ final class SomeClass
+## Doctrine-specific Rules
+
+### NoGetRepositoryOutsideServiceRule
+
+Instead of getting repository from EntityManager, use constructor injection and service pattern to keep code clean
+
+```yaml
+rules:
+ - Symplify\PHPStanRules\Rules\Doctrine\NoGetRepositoryOutsideServiceRule
+```
+
+```php
+class SomeClass
+{
+ public function run(EntityManagerInterface $entityManager)
+ {
+ return $entityManager->getRepository(SomeEntity::class);
+ }
+}
+```
+
+
diff --git a/src/Enum/RuleIdentifier.php b/src/Enum/RuleIdentifier.php
index a79d8874..1b583d09 100644
--- a/src/Enum/RuleIdentifier.php
+++ b/src/Enum/RuleIdentifier.php
@@ -182,4 +182,26 @@ final class RuleIdentifier
public const NO_DYNAMIC_NAME = 'symplify.noDynamicName';
public const NO_REFERENCE = 'symplify.noReference';
+
+ public const PHPUNIT_NO_MOCK_ONLY = 'phpunit.noMockOnly';
+
+ public const SINGLE_ARG_EVENT_DISPATCH = 'symfony.singleArgEventDispatch';
+
+ public const NO_ENTITY_MOCKING = 'doctrine.noEntityMocking';
+
+ public const NO_STRING_IN_GET_SUBSCRIBED_EVENTS = 'symfony.noStringInGetSubscribedEvents';
+
+ public const NO_LISTENER_WITHOUT_CONTRACT = 'symfony.noListenerWithoutContract';
+
+ public const DOCTRINE_NO_PARENT_REPOSITORY = 'doctrine.noParentRepository';
+
+ public const DOCTRINE_NO_GET_REPOSITORY_OUTSIDE_SERVICE = 'doctrine.noGetRepositoryOutsideService';
+
+ public const SYMFONY_NO_REQUIRED_OUTSIDE_CLASS = 'symfony.noRequiredOutsideClass';
+
+ public const NO_CONSTRUCTOR_OVERRIDE = 'symplify.noConstructorOverride';
+
+ public const SYMFONY_NO_ABSTRACT_CONTROLLER_CONSTRUCTOR = 'symfony.noAbstractControllerConstructor';
+
+ public const PHPUNIT_PUBLIC_STATIC_DATA_PROVIDER = 'phpunit.publicStaticDataProvider';
}
diff --git a/src/PHPStan/Rules/Doctrine/NoGetRepositoryOutsideServiceRule.php b/src/PHPStan/Rules/Doctrine/NoGetRepositoryOutsideServiceRule.php
index 4b5e9e3d..7a2ea3cd 100644
--- a/src/PHPStan/Rules/Doctrine/NoGetRepositoryOutsideServiceRule.php
+++ b/src/PHPStan/Rules/Doctrine/NoGetRepositoryOutsideServiceRule.php
@@ -9,14 +9,11 @@
use PhpParser\Node\Identifier;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
- * Check if abstract controller has constructor, as it should use
- * #[Require] instead to avoid parent constructor override
- *
- * @see \Symplify\PHPStanRules\Tests\PHPStan\Rule\NoGetRepositoryOutsideServiceRule\NoGetRepositoryOutsideServiceRuleTest
+ * @see \Symplify\PHPStanRules\Tests\Rules\Doctrine\NoGetRepositoryOutsideServiceRule\NoGetRepositoryOutsideServiceRuleTest
*
* @implements Rule
*/
@@ -34,7 +31,6 @@ public function getNodeType(): string
/**
* @param MethodCall $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -47,7 +43,10 @@ public function processNode(Node $node, Scope $scope): array
}
if (! $scope->isInClass()) {
- $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)->build();
+ $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::DOCTRINE_NO_GET_REPOSITORY_OUTSIDE_SERVICE)
+ ->build();
+
return [$ruleError];
}
@@ -57,7 +56,10 @@ public function processNode(Node $node, Scope $scope): array
return [];
}
- $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)->build();
+ $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::DOCTRINE_NO_GET_REPOSITORY_OUTSIDE_SERVICE)
+ ->build();
+
return [$ruleError];
}
}
diff --git a/src/PHPStan/Rules/Doctrine/NoParentRepositoryRule.php b/src/PHPStan/Rules/Doctrine/NoParentRepositoryRule.php
index a672c7a8..bdddc053 100644
--- a/src/PHPStan/Rules/Doctrine/NoParentRepositoryRule.php
+++ b/src/PHPStan/Rules/Doctrine/NoParentRepositoryRule.php
@@ -9,8 +9,8 @@
use PhpParser\Node\Stmt\Class_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
* Check if class extends repository class,
@@ -39,7 +39,6 @@ public function getNodeType(): string
/**
* @param Class_ $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -53,6 +52,7 @@ public function processNode(Node $node, Scope $scope): array
}
$ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::DOCTRINE_NO_PARENT_REPOSITORY)
->build();
return [$ruleError];
diff --git a/src/Testing/DataProviderMethodResolver.php b/src/PHPUnit/DataProviderMethodResolver.php
similarity index 94%
rename from src/Testing/DataProviderMethodResolver.php
rename to src/PHPUnit/DataProviderMethodResolver.php
index 86b568e4..409fa996 100644
--- a/src/Testing/DataProviderMethodResolver.php
+++ b/src/PHPUnit/DataProviderMethodResolver.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Symplify\PHPStanRules\PHPStan;
+namespace Symplify\PHPStanRules\PHPUnit;
use PhpParser\Comment\Doc;
use PhpParser\Node\Stmt\ClassMethod;
diff --git a/src/Rules/Complexity/NoConstructorOverrideRule.php b/src/Rules/Complexity/NoConstructorOverrideRule.php
index a5f29e91..acb22bff 100644
--- a/src/Rules/Complexity/NoConstructorOverrideRule.php
+++ b/src/Rules/Complexity/NoConstructorOverrideRule.php
@@ -10,8 +10,8 @@
use PhpParser\NodeFinder;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
* @implements Rule
@@ -35,7 +35,6 @@ public function getNodeType(): string
/**
* @param ClassMethod $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -69,7 +68,10 @@ public function processNode(Node $node, Scope $scope): array
return [];
}
- $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)->build();
+ $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::NO_CONSTRUCTOR_OVERRIDE)
+ ->build();
+
return [$ruleError];
}
}
diff --git a/src/Rules/Doctrine/NoEntityMockingRule.php b/src/Rules/Doctrine/NoEntityMockingRule.php
index 18be7a58..2e834c7e 100644
--- a/src/Rules/Doctrine/NoEntityMockingRule.php
+++ b/src/Rules/Doctrine/NoEntityMockingRule.php
@@ -10,8 +10,8 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
use Symplify\PHPStanRules\PHPStan\DoctrineEntityDocumentAnalyser;
/**
@@ -40,7 +40,6 @@ public function getNodeType(): string
/**
* @param MethodCall $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -62,6 +61,7 @@ public function processNode(Node $node, Scope $scope): array
}
$ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::NO_ENTITY_MOCKING)
->build();
return [$ruleError];
diff --git a/src/Rules/PHPUnit/NoMockOnlyTestRule.php b/src/Rules/PHPUnit/NoMockOnlyTestRule.php
index 4b6a2142..6ebcd060 100644
--- a/src/Rules/PHPUnit/NoMockOnlyTestRule.php
+++ b/src/Rules/PHPUnit/NoMockOnlyTestRule.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Symplify\PHPStanRules\PHPStan\Rule;
+namespace Symplify\PHPStanRules\Rules\PHPUnit;
use PhpParser\Node;
use PhpParser\Node\Name;
@@ -10,12 +10,11 @@
use PHPStan\Analyser\Scope;
use PHPStan\Node\InClassNode;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
-use Symplify\PHPStanRules\PHPStan\PHPUnitTestAnalyser;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
- * @see \Symplify\PHPStanRules\Tests\PHPStan\Rule\NoMockOnlyTestRule\NoMockOnlyTestRuleTest
+ * @see \Symplify\PHPStanRules\Tests\Rules\PHPUnit\NoMockOnlyTestRule\NoMockOnlyTestRuleTest
*
* @implements Rule
*/
@@ -38,11 +37,10 @@ public function getNodeType(): string
/**
* @param InClassNode $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
- if (! PHPUnitTestAnalyser::isTestClass($scope)) {
+ if (! \Symplify\PHPStanRules\Testing\PHPUnitTestAnalyser::isTestClass($scope)) {
return [];
}
@@ -74,7 +72,9 @@ public function processNode(Node $node, Scope $scope): array
}
$ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::PHPUNIT_NO_MOCK_ONLY)
->build();
+
return [$ruleError];
}
}
diff --git a/src/Rules/PHPUnit/PublicStaticDataProviderRule.php b/src/Rules/PHPUnit/PublicStaticDataProviderRule.php
index 3629ff47..96cb75f8 100644
--- a/src/Rules/PHPUnit/PublicStaticDataProviderRule.php
+++ b/src/Rules/PHPUnit/PublicStaticDataProviderRule.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Symplify\PHPStanRules\PHPStan\Rule;
+namespace Symplify\PHPStanRules\Rules\PHPUnit;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
@@ -10,8 +10,8 @@
use PHPStan\Node\InClassNode;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
-use Symplify\PHPStanRules\PHPStan\DataProviderMethodResolver;
-use Symplify\PHPStanRules\PHPStan\PHPUnitTestAnalyser;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
+use Symplify\PHPStanRules\PHPUnit\DataProviderMethodResolver;
/**
* PHPUnit data provider have to be public and static
@@ -42,7 +42,7 @@ public function getNodeType(): string
*/
public function processNode(Node $node, Scope $scope): array
{
- if (! PHPUnitTestAnalyser::isTestClass($scope)) {
+ if (! \Symplify\PHPStanRules\Testing\PHPUnitTestAnalyser::isTestClass($scope)) {
return [];
}
@@ -50,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array
$classLike = $node->getOriginalNode();
foreach ($classLike->getMethods() as $classMethod) {
- if (! PHPUnitTestAnalyser::isTestClassMethod($classMethod)) {
+ if (! \Symplify\PHPStanRules\Testing\PHPUnitTestAnalyser::class::isTestClassMethod($classMethod)) {
continue;
}
@@ -75,7 +75,7 @@ public function processNode(Node $node, Scope $scope): array
if (! $dataProviderClassMethod->isStatic()) {
$errorMessage = sprintf(self::PUBLIC_ERROR_MESSAGE, $dataProviderMethodName);
$ruleErrors[] = RuleErrorBuilder::message($errorMessage)
- ->identifier('phpunit.publicDataProvider')
+ ->identifier(RuleIdentifier::PHPUNIT_PUBLIC_STATIC_DATA_PROVIDER)
->line($dataProviderClassMethod->getLine())
->build();
}
diff --git a/src/Rules/Symfony/NoAbstractControllerConstructorRule.php b/src/Rules/Symfony/NoAbstractControllerConstructorRule.php
index 8fd51ddf..8e6cc4de 100644
--- a/src/Rules/Symfony/NoAbstractControllerConstructorRule.php
+++ b/src/Rules/Symfony/NoAbstractControllerConstructorRule.php
@@ -9,8 +9,8 @@
use PhpParser\Node\Stmt\Class_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
* Check if abstract controller has constructor, as it should use
@@ -34,7 +34,6 @@ public function getNodeType(): string
/**
* @param Class_ $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -55,7 +54,10 @@ public function processNode(Node $node, Scope $scope): array
return [];
}
- $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)->build();
+ $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::SYMFONY_NO_ABSTRACT_CONTROLLER_CONSTRUCTOR)
+ ->build();
+
return [$ruleError];
}
}
diff --git a/src/Rules/Symfony/NoListenerWithoutContractRule.php b/src/Rules/Symfony/NoListenerWithoutContractRule.php
index 3b157b3e..41326ab7 100644
--- a/src/Rules/Symfony/NoListenerWithoutContractRule.php
+++ b/src/Rules/Symfony/NoListenerWithoutContractRule.php
@@ -9,8 +9,8 @@
use PHPStan\Analyser\Scope;
use PHPStan\Node\InClassNode;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
* Based on https://tomasvotruba.com/blog/2019/07/22/how-to-convert-listeners-to-subscribers-and-reduce-your-configs
@@ -23,7 +23,7 @@ final class NoListenerWithoutContractRule implements Rule
/**
* @var string
*/
- public const ERROR_MESSAGE = 'There should be no listeners defined in yaml config, use contract + PHP instead';
+ public const ERROR_MESSAGE = 'There should be no listeners modified in config. Use EventSubscriberInterface contract and PHP instead';
public function getNodeType(): string
{
@@ -32,7 +32,6 @@ public function getNodeType(): string
/**
* @param InClassNode $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -54,7 +53,9 @@ public function processNode(Node $node, Scope $scope): array
return [];
}
- $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)->build();
+ $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::NO_LISTENER_WITHOUT_CONTRACT)
+ ->build();
return [$ruleError];
}
diff --git a/src/Rules/Symfony/NoRequiredOutsideClassRule.php b/src/Rules/Symfony/NoRequiredOutsideClassRule.php
index 93bf69d3..22aa07ec 100644
--- a/src/Rules/Symfony/NoRequiredOutsideClassRule.php
+++ b/src/Rules/Symfony/NoRequiredOutsideClassRule.php
@@ -10,8 +10,8 @@
use PhpParser\Node\Stmt\Trait_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
* @see \Symplify\PHPStanRules\Tests\PHPStan\Rule\NoRequiredOutsideClassRule\NoRequiredOutsideClassRuleTest
@@ -37,7 +37,6 @@ public function getNodeType(): string
/**
* @param Trait_ $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -47,6 +46,7 @@ public function processNode(Node $node, Scope $scope): array
if ($this->isAutowiredClassMethod($classMethod)) {
$ruleErrors[] = RuleErrorBuilder::message(self::ERROR_MESSAGE)
->file($scope->getFile())
+ ->identifier(RuleIdentifier::SYMFONY_NO_REQUIRED_OUTSIDE_CLASS)
->line($classMethod->getLine())
->build();
}
diff --git a/src/Rules/Symfony/NoStringInGetSubscribedEventsRule.php b/src/Rules/Symfony/NoStringInGetSubscribedEventsRule.php
index c6640577..c74e1f88 100644
--- a/src/Rules/Symfony/NoStringInGetSubscribedEventsRule.php
+++ b/src/Rules/Symfony/NoStringInGetSubscribedEventsRule.php
@@ -13,9 +13,9 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
use Symplify\PHPStanRules\Enum\ClassName;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
* @implements Rule
@@ -39,7 +39,6 @@ public function getNodeType(): string
/**
* @param ClassMethod $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -95,7 +94,10 @@ public function processNode(Node $node, Scope $scope): array
continue;
}
- $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)->build();
+ $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::NO_STRING_IN_GET_SUBSCRIBED_EVENTS)
+ ->build();
+
return [$ruleError];
}
diff --git a/src/Rules/Symfony/SingleArgEventDispatchRule.php b/src/Rules/Symfony/SingleArgEventDispatchRule.php
index 6bc7f787..134ec1da 100644
--- a/src/Rules/Symfony/SingleArgEventDispatchRule.php
+++ b/src/Rules/Symfony/SingleArgEventDispatchRule.php
@@ -9,10 +9,10 @@
use PhpParser\Node\Identifier;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
-use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\ObjectType;
use Symplify\PHPStanRules\Enum\ClassName;
+use Symplify\PHPStanRules\Enum\RuleIdentifier;
/**
* @implements Rule
@@ -31,7 +31,6 @@ public function getNodeType(): string
/**
* @param MethodCall $node
- * @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
@@ -57,7 +56,10 @@ public function processNode(Node $node, Scope $scope): array
return [];
}
- $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)->build();
+ $ruleError = RuleErrorBuilder::message(self::ERROR_MESSAGE)
+ ->identifier(RuleIdentifier::SINGLE_ARG_EVENT_DISPATCH)
+ ->build();
+
return [$ruleError];
}
}
diff --git a/src/Testing/PHPUnitTestAnalyser.php b/src/Testing/PHPUnitTestAnalyser.php
index 6a7b5947..bf951a4b 100644
--- a/src/Testing/PHPUnitTestAnalyser.php
+++ b/src/Testing/PHPUnitTestAnalyser.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Symplify\PHPStanRules\PHPStan;
+namespace Symplify\PHPStanRules\Testing;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Analyser\Scope;
diff --git a/tests/Rules/PHPUnit/NoMockOnlyTestRule/NoMockOnlyTestRuleTest.php b/tests/Rules/PHPUnit/NoMockOnlyTestRule/NoMockOnlyTestRuleTest.php
index 0b540bcc..1f7e7f85 100644
--- a/tests/Rules/PHPUnit/NoMockOnlyTestRule/NoMockOnlyTestRuleTest.php
+++ b/tests/Rules/PHPUnit/NoMockOnlyTestRule/NoMockOnlyTestRuleTest.php
@@ -8,7 +8,7 @@
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use PHPUnit\Framework\Attributes\DataProvider;
-use Symplify\PHPStanRules\PHPStan\Rule\NoMockOnlyTestRule;
+use Symplify\PHPStanRules\Rules\PHPUnit\NoMockOnlyTestRule;
final class NoMockOnlyTestRuleTest extends RuleTestCase
{
diff --git a/tests/Rules/PHPUnit/PublicStaticDataProviderRule/PublicStaticDataProviderRuleTest.php b/tests/Rules/PHPUnit/PublicStaticDataProviderRule/PublicStaticDataProviderRuleTest.php
index 2a729e2f..4f42c146 100644
--- a/tests/Rules/PHPUnit/PublicStaticDataProviderRule/PublicStaticDataProviderRuleTest.php
+++ b/tests/Rules/PHPUnit/PublicStaticDataProviderRule/PublicStaticDataProviderRuleTest.php
@@ -6,7 +6,7 @@
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use PHPUnit\Framework\Attributes\DataProvider;
-use Symplify\PHPStanRules\PHPStan\Rule\PublicStaticDataProviderRule;
+use Symplify\PHPStanRules\Rules\PHPUnit\PublicStaticDataProviderRule;
final class PublicStaticDataProviderRuleTest extends RuleTestCase
{