-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Symfony] Add access control custom method call conversion (#561)
* add fixture to achieve * add more extensoins
- Loading branch information
1 parent
bd312e6
commit 4cde44a
Showing
4 changed files
with
158 additions
and
0 deletions.
There are no files selected for viewing
37 changes: 37 additions & 0 deletions
37
...e/StringExtensionToConfigBuilderRector/Fixture/security_access_control_many_items.php.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
namespace Rector\Symfony\Tests\Rector\Closure\StringExtensionToConfigBuilderRector\Fixture; | ||
|
||
use Rector\Symfony\Tests\CodeQuality\Rector\Closure\StringExtensionToConfigBuilderRector\Source\SomeUserProvider; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; | ||
|
||
return static function (ContainerConfigurator $containerConfigurator): void { | ||
$containerConfigurator->extension('security', [ | ||
'access_control' => [ | ||
[ | ||
'path' => '^/first', | ||
'role' => 'PUBLIC_ACCESS', | ||
], | ||
[ | ||
'path' => '^/second', | ||
'role' => 'PUBLIC_ACCESS', | ||
], | ||
], | ||
]); | ||
}; | ||
|
||
?> | ||
----- | ||
<?php | ||
|
||
namespace Rector\Symfony\Tests\Rector\Closure\StringExtensionToConfigBuilderRector\Fixture; | ||
|
||
use Rector\Symfony\Tests\CodeQuality\Rector\Closure\StringExtensionToConfigBuilderRector\Source\SomeUserProvider; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; | ||
|
||
return static function (\Symfony\Config\SecurityConfig $securityConfig) : void { | ||
$securityConfig->accessControl()->path('^/first')->roles(['PUBLIC_ACCESS']); | ||
$securityConfig->accessControl()->path('^/second')->roles(['PUBLIC_ACCESS']); | ||
}; | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
rules/Configs/ConfigArrayHandler/SecurityAccessControlConfigArrayHandler.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Symfony\Configs\ConfigArrayHandler; | ||
|
||
use PhpParser\Node\Arg; | ||
use PhpParser\Node\Expr\Array_; | ||
use PhpParser\Node\Expr\ArrayItem; | ||
use PhpParser\Node\Expr\MethodCall; | ||
use PhpParser\Node\Expr\Variable; | ||
use PhpParser\Node\Scalar\String_; | ||
use PhpParser\Node\Stmt\Expression; | ||
use Rector\Exception\ShouldNotHappenException; | ||
|
||
final class SecurityAccessControlConfigArrayHandler | ||
{ | ||
/** | ||
* @return array<Expression<MethodCall>> | ||
*/ | ||
public function handle(Array_ $array, Variable $configVariable): array | ||
{ | ||
if (! $array->items[0] instanceof ArrayItem) { | ||
return []; | ||
} | ||
|
||
$nestedAccessControlArrayItem = $array->items[0]; | ||
$nestedAccessControlArray = $nestedAccessControlArrayItem->value; | ||
|
||
if (! $nestedAccessControlArray instanceof Array_) { | ||
return []; | ||
} | ||
|
||
$methodCallStmts = []; | ||
foreach ($nestedAccessControlArray->items as $accessControlArrayItem) { | ||
if (! $accessControlArrayItem instanceof ArrayItem) { | ||
throw new ShouldNotHappenException(); | ||
} | ||
|
||
$nestedAccessControlArrayArray = $accessControlArrayItem->value; | ||
if (! $nestedAccessControlArrayArray instanceof Array_) { | ||
return []; | ||
} | ||
|
||
// build accessControl() method call here | ||
$accessControlMethodCall = new MethodCall($configVariable, 'accessControl'); | ||
|
||
$accessControlMethodCall = $this->decoreateAccessControlArrayArray( | ||
$nestedAccessControlArrayArray, | ||
$accessControlMethodCall | ||
); | ||
|
||
$methodCallStmts[] = new Expression($accessControlMethodCall); | ||
} | ||
|
||
return $methodCallStmts; | ||
} | ||
|
||
private function decoreateAccessControlArrayArray( | ||
Array_ $nestedAccessControlArrayArray, | ||
MethodCall $accessControlMethodCall | ||
): MethodCall { | ||
foreach ($nestedAccessControlArrayArray->items as $nestedAccessControlArrayArrayItem) { | ||
if (! $nestedAccessControlArrayArrayItem instanceof ArrayItem) { | ||
throw new ShouldNotHappenException(); | ||
} | ||
|
||
if ($nestedAccessControlArrayArrayItem->key instanceof String_) { | ||
$methodName = $nestedAccessControlArrayArrayItem->key->value; | ||
|
||
$argValue = $nestedAccessControlArrayArrayItem->value; | ||
|
||
// method correction | ||
if ($methodName === 'role') { | ||
$methodName = 'roles'; | ||
$argValue = new Array_([new ArrayItem($argValue)]); | ||
} | ||
|
||
$accessControlMethodCall = new MethodCall( | ||
$accessControlMethodCall, | ||
$methodName, | ||
[new Arg($argValue)] | ||
); | ||
} | ||
} | ||
|
||
return $accessControlMethodCall; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Symfony\Configs\Enum; | ||
|
||
final class SecurityConfigKey | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
public const ACCESS_CONTROL = 'access_control'; | ||
} |