Skip to content

Commit c380871

Browse files
committed
[symfony] Add RequireIsGrantedEnumRule
1 parent 04ef7e0 commit c380871

File tree

11 files changed

+120
-9
lines changed

11 files changed

+120
-9
lines changed

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
<exclude>tests/Rules/ClassNameRespectsParentSuffixRule/Fixture/</exclude>
1313
<exclude>tests/Rules/PHPUnit/PublicStaticDataProviderRule</exclude>
1414
<exclude>tests/Rules/PHPUnit/NoAssertFuncCallInTestsRule/Fixture</exclude>
15+
<exclude>tests/Rules/PHPUnit/NoMockOnlyTestRule/Fixture/SkipConstraintValidatorTest.php</exclude>
1516
</testsuite>
1617
</phpunit>

src/Enum/RuleIdentifier/SymfonyRuleIdentifier.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@ final class SymfonyRuleIdentifier
5353
public const NO_DUPLICATE_ARG_AUTOWIRE_BY_TYPE = 'symfony.noDuplicateArgAutowireByType';
5454

5555
public const NO_SERVICE_SAME_NAME_SET_CLASS = 'symfony.noServiceSameNameSetClass';
56+
57+
public const REQUIRED_IS_GRANTED_ENUM = 'symfony.requiredIsGrantedEnum';
5658
}

src/Enum/SensioClass.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\PHPStanRules\Enum;
6+
7+
final class SensioClass
8+
{
9+
public const IS_GRANTED = 'Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted';
10+
}

src/Enum/SymfonyClass.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,6 @@ final class SymfonyClass
4242
public const VALIDATOR_TEST_CASE = 'Symfony\Component\Validator\Test\ConstraintValidatorTestCase';
4343

4444
public const CONTAINER_CONFIGURATOR = 'Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator';
45+
46+
public const IS_GRANTED = 'Symfony\Component\Security\Http\Attribute\IsGranted';
4547
}

src/Rules/Symfony/RequireIsGrantedEnumRule.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,19 @@
1010
use PHPStan\Analyser\Scope;
1111
use PHPStan\Rules\Rule;
1212
use PHPStan\Rules\RuleErrorBuilder;
13-
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
13+
use Symplify\PHPStanRules\Enum\RuleIdentifier\SymfonyRuleIdentifier;
14+
use Symplify\PHPStanRules\Enum\SensioClass;
15+
use Symplify\PHPStanRules\Enum\SymfonyClass;
1416

17+
/**
18+
* @see \Symplify\PHPStanRules\Tests\Rules\Symfony\RequireIsGrantedEnumRule\RequireIsGrantedEnumRuleTest
19+
*
20+
* @implements Rule<Attribute>
21+
*/
1522
final class RequireIsGrantedEnumRule implements Rule
1623
{
24+
public const ERROR_MESSAGE = 'Instead of "%s" string, use enum constant for #[IsGranted]';
25+
1726
public function getNodeType(): string
1827
{
1928
return Attribute::class;
@@ -24,7 +33,7 @@ public function getNodeType(): string
2433
*/
2534
public function processNode(Node $node, Scope $scope): array
2635
{
27-
if ($node->name->toString() !== IsGranted::class) {
36+
if (! in_array($node->name->toString(), [SensioClass::IS_GRANTED, SymfonyClass::IS_GRANTED], true)) {
2837
return [];
2938
}
3039

@@ -33,12 +42,10 @@ public function processNode(Node $node, Scope $scope): array
3342
return [];
3443
}
3544

36-
return [
37-
RuleErrorBuilder::message(
38-
sprintf('Instead of "%s" string, use enum constant for #[IsGranted]', $isGrantedExpr->value)
39-
)
40-
->identifier('symfony.requiredIsGrantedEnum')
41-
->build(),
42-
];
45+
$ruleError = RuleErrorBuilder::message(sprintf(self::ERROR_MESSAGE, $isGrantedExpr->value))
46+
->identifier(SymfonyRuleIdentifier::REQUIRED_IS_GRANTED_ENUM)
47+
->build();
48+
49+
return [$ruleError];
4350
}
4451
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Sensio\Bundle\FrameworkExtraBundle\Configuration;
4+
5+
#[\Attribute]
6+
class IsGranted
7+
{
8+
public function __construct(string $resource)
9+
{
10+
}
11+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\PHPStanRules\Tests\Rules\Symfony\RequireIsGrantedEnumRule\Fixture;
6+
7+
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
8+
use Symplify\PHPStanRules\Tests\Rules\Symfony\RequireIsGrantedEnumRule\Source\SomePermission;
9+
10+
#[IsGranted(SomePermission::ACCESS)]
11+
final class SkipConstantResource
12+
{
13+
public function run()
14+
{
15+
}
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\PHPStanRules\Tests\Rules\Symfony\RequireIsGrantedEnumRule\Fixture;
6+
7+
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
8+
9+
#[IsGranted('some_resource')]
10+
final class SomeControllerWithStringyAttribute
11+
{
12+
public function run()
13+
{
14+
}
15+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\PHPStanRules\Tests\Rules\Symfony\RequireIsGrantedEnumRule;
6+
7+
use Iterator;
8+
use PHPStan\Rules\Rule;
9+
use PHPStan\Testing\RuleTestCase;
10+
use PHPUnit\Framework\Attributes\DataProvider;
11+
use Symplify\PHPStanRules\Rules\Symfony\RequireIsGrantedEnumRule;
12+
13+
final class RequireIsGrantedEnumRuleTest extends RuleTestCase
14+
{
15+
/**
16+
* @param mixed[] $expectedErrorMessagesWithLines
17+
*/
18+
#[DataProvider('provideData')]
19+
public function testRule(string $filePath, array $expectedErrorMessagesWithLines): void
20+
{
21+
$this->analyse([$filePath], $expectedErrorMessagesWithLines);
22+
}
23+
24+
public static function provideData(): Iterator
25+
{
26+
yield [__DIR__ . '/Fixture/SkipConstantResource.php', []];
27+
28+
yield [__DIR__ . '/Fixture/SomeControllerWithStringyAttribute.php', [
29+
[sprintf(RequireIsGrantedEnumRule::ERROR_MESSAGE, 'some_resource'), 9],
30+
]];
31+
}
32+
33+
protected function getRule(): Rule
34+
{
35+
return new RequireIsGrantedEnumRule();
36+
}
37+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symplify\PHPStanRules\Tests\Rules\Symfony\RequireIsGrantedEnumRule\Source;
4+
5+
final class SomePermission
6+
{
7+
public const ACCESS = 'access';
8+
}

0 commit comments

Comments
 (0)