mirror of
https://github.com/rectorphp/rector.git
synced 2025-03-14 04:19:44 +01:00
[Symfony 5.1] Add LogoutHandlerToLogoutEventSubscriberRector (#5346)
This commit is contained in:
parent
8e3e3fd6e1
commit
f9f12d9109
@ -10,6 +10,8 @@ use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Renaming\Rector\String_\RenameStringRector;
|
||||
use Rector\Renaming\ValueObject\MethodCallRename;
|
||||
use Rector\Renaming\ValueObject\RenameClassAndConstFetch;
|
||||
use Rector\Symfony5\Rector\Class_\LogoutHandlerToLogoutEventSubscriberRector;
|
||||
use Rector\Symfony5\Rector\Class_\LogoutSuccessHandlerToLogoutEventSubscriberRector;
|
||||
use Rector\Transform\Rector\New_\NewArgToMethodCallRector;
|
||||
use Rector\Transform\Rector\StaticCall\StaticCallToNewRector;
|
||||
use Rector\Transform\ValueObject\NewArgToMethodCall;
|
||||
@ -24,6 +26,10 @@ use Symplify\SymfonyPhpConfig\ValueObjectInliner;
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
// see https://github.com/symfony/symfony/pull/36243
|
||||
$services->set(LogoutHandlerToLogoutEventSubscriberRector::class);
|
||||
$services->set(LogoutSuccessHandlerToLogoutEventSubscriberRector::class);
|
||||
|
||||
$services->set(RenameClassRector::class)
|
||||
->call('configure', [[
|
||||
RenameClassRector::OLD_TO_NEW_CLASSES => [
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Rector\EarlyReturn\Tests\Rector\Return_\ReturnBinaryAndToEarlyReturnRector\Fixture;
|
||||
|
||||
class NotIdentical
|
||||
final class SomeNotIdentical
|
||||
{
|
||||
public function accept($something, $somethingelse)
|
||||
{
|
||||
@ -16,7 +16,7 @@ class NotIdentical
|
||||
|
||||
namespace Rector\EarlyReturn\Tests\Rector\Return_\ReturnBinaryAndToEarlyReturnRector\Fixture;
|
||||
|
||||
class NotIdentical
|
||||
final class SomeNotIdentical
|
||||
{
|
||||
public function accept($something, $somethingelse)
|
||||
{
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\SymfonyCodeQuality\Contract;
|
||||
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
|
||||
interface EventReferenceToMethodNameInterface
|
||||
{
|
||||
public function getClassConstFetch(): ClassConstFetch;
|
||||
|
||||
public function getMethodName(): string;
|
||||
}
|
@ -26,8 +26,9 @@ use Rector\Symfony\Contract\Tag\TagInterface;
|
||||
use Rector\Symfony\ValueObject\ServiceDefinition;
|
||||
use Rector\Symfony\ValueObject\Tag;
|
||||
use Rector\Symfony\ValueObject\Tag\EventListenerTag;
|
||||
use Rector\SymfonyCodeQuality\Contract\EventReferenceToMethodNameInterface;
|
||||
use Rector\SymfonyCodeQuality\ValueObject\EventNameToClassAndConstant;
|
||||
use Rector\SymfonyCodeQuality\ValueObject\EventReferenceToMethodName;
|
||||
use Rector\SymfonyCodeQuality\ValueObject\EventReferenceToMethodNameWithPriority;
|
||||
|
||||
final class GetSubscribedEventsClassMethodFactory
|
||||
{
|
||||
@ -83,7 +84,7 @@ final class GetSubscribedEventsClassMethodFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EventReferenceToMethodName[] $eventReferencesToMethodNames
|
||||
* @param EventReferenceToMethodNameInterface[] $eventReferencesToMethodNames
|
||||
*/
|
||||
public function create(array $eventReferencesToMethodNames): ClassMethod
|
||||
{
|
||||
@ -92,8 +93,10 @@ final class GetSubscribedEventsClassMethodFactory
|
||||
$eventsToMethodsArray = new Array_();
|
||||
|
||||
foreach ($eventReferencesToMethodNames as $eventReferencesToMethodName) {
|
||||
$priority = $eventReferencesToMethodName instanceof EventReferenceToMethodNameWithPriority ? $eventReferencesToMethodName->getPriority() : null;
|
||||
|
||||
$eventsToMethodsArray->items[] = $this->createArrayItemFromMethodAndPriority(
|
||||
null,
|
||||
$priority,
|
||||
$eventReferencesToMethodName->getMethodName(),
|
||||
$eventReferencesToMethodName->getClassConstFetch()
|
||||
);
|
||||
|
@ -5,8 +5,9 @@ declare(strict_types=1);
|
||||
namespace Rector\SymfonyCodeQuality\ValueObject;
|
||||
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use Rector\SymfonyCodeQuality\Contract\EventReferenceToMethodNameInterface;
|
||||
|
||||
final class EventReferenceToMethodName
|
||||
final class EventReferenceToMethodName implements EventReferenceToMethodNameInterface
|
||||
{
|
||||
/**
|
||||
* @var ClassConstFetch
|
||||
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\SymfonyCodeQuality\ValueObject;
|
||||
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use Rector\SymfonyCodeQuality\Contract\EventReferenceToMethodNameInterface;
|
||||
|
||||
final class EventReferenceToMethodNameWithPriority implements EventReferenceToMethodNameInterface
|
||||
{
|
||||
/**
|
||||
* @var ClassConstFetch
|
||||
*/
|
||||
private $classConstFetch;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $methodName;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $priority;
|
||||
|
||||
public function __construct(ClassConstFetch $classConstFetch, string $methodName, int $priority)
|
||||
{
|
||||
$this->classConstFetch = $classConstFetch;
|
||||
$this->methodName = $methodName;
|
||||
$this->priority = $priority;
|
||||
}
|
||||
|
||||
public function getClassConstFetch(): ClassConstFetch
|
||||
{
|
||||
return $this->classConstFetch;
|
||||
}
|
||||
|
||||
public function getMethodName(): string
|
||||
{
|
||||
return $this->methodName;
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Symfony5\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
|
||||
final class BareLogoutClassMethodFactory
|
||||
{
|
||||
/**
|
||||
* @var NodeFactory
|
||||
*/
|
||||
private $nodeFactory;
|
||||
|
||||
/**
|
||||
* @var PhpVersionProvider
|
||||
*/
|
||||
private $phpVersionProvider;
|
||||
|
||||
public function __construct(NodeFactory $nodeFactory, PhpVersionProvider $phpVersionProvider)
|
||||
{
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
}
|
||||
|
||||
public function create(): ClassMethod
|
||||
{
|
||||
$classMethod = $this->nodeFactory->createPublicMethod('onLogout');
|
||||
|
||||
$variable = new Variable('logoutEvent');
|
||||
$classMethod->params[] = $this->createLogoutEventParam($variable);
|
||||
|
||||
if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::VOID_TYPE)) {
|
||||
$classMethod->returnType = new Identifier('void');
|
||||
}
|
||||
|
||||
return $classMethod;
|
||||
}
|
||||
|
||||
private function createLogoutEventParam(Variable $variable): Param
|
||||
{
|
||||
$param = new Param($variable);
|
||||
$param->type = new FullyQualified('Symfony\Component\Security\Http\Event\LogoutEvent');
|
||||
|
||||
return $param;
|
||||
}
|
||||
}
|
@ -7,14 +7,10 @@ namespace Rector\Symfony5\NodeFactory;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\NetteKdyby\NodeManipulator\ListeningClassMethodArgumentManipulator;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
||||
@ -29,16 +25,6 @@ final class OnLogoutClassMethodFactory
|
||||
'token' => 'getToken',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var NodeFactory
|
||||
*/
|
||||
private $nodeFactory;
|
||||
|
||||
/**
|
||||
* @var PhpVersionProvider
|
||||
*/
|
||||
private $phpVersionProvider;
|
||||
|
||||
/**
|
||||
* @var ListeningClassMethodArgumentManipulator
|
||||
*/
|
||||
@ -49,25 +35,45 @@ final class OnLogoutClassMethodFactory
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
|
||||
/**
|
||||
* @var BareLogoutClassMethodFactory
|
||||
*/
|
||||
private $bareLogoutClassMethodFactory;
|
||||
|
||||
public function __construct(
|
||||
NodeFactory $nodeFactory,
|
||||
PhpVersionProvider $phpVersionProvider,
|
||||
ListeningClassMethodArgumentManipulator $listeningClassMethodArgumentManipulator,
|
||||
NodeNameResolver $nodeNameResolver
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
BareLogoutClassMethodFactory $bareLogoutClassMethodFactory
|
||||
) {
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
$this->listeningClassMethodArgumentManipulator = $listeningClassMethodArgumentManipulator;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->bareLogoutClassMethodFactory = $bareLogoutClassMethodFactory;
|
||||
}
|
||||
|
||||
public function createFromLogoutClassMethod(ClassMethod $logoutClassMethod): ClassMethod
|
||||
{
|
||||
$classMethod = $this->nodeFactory->createPublicMethod('onLogout');
|
||||
$classMethod = $this->bareLogoutClassMethodFactory->create();
|
||||
|
||||
$logoutEventVariable = new Variable('logoutEvent');
|
||||
$classMethod->params[] = $this->createLogoutEventParam($logoutEventVariable);
|
||||
$assignStmts = $this->createAssignStmtFromOldClassMethod($logoutClassMethod);
|
||||
$classMethod->stmts = array_merge($assignStmts, (array) $logoutClassMethod->stmts);
|
||||
|
||||
return $classMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Stmt[]
|
||||
*/
|
||||
private function createAssignStmtFromOldClassMethod(ClassMethod $onLogoutSuccessClassMethod): array
|
||||
{
|
||||
$usedParams = $this->resolveUsedParams($onLogoutSuccessClassMethod);
|
||||
return $this->createAssignStmts($usedParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Param[]
|
||||
*/
|
||||
private function resolveUsedParams(ClassMethod $logoutClassMethod): array
|
||||
{
|
||||
$usedParams = [];
|
||||
foreach ($logoutClassMethod->params as $oldParam) {
|
||||
if (! $this->listeningClassMethodArgumentManipulator->isParamUsedInClassMethodBody(
|
||||
@ -79,30 +85,17 @@ final class OnLogoutClassMethodFactory
|
||||
|
||||
$usedParams[] = $oldParam;
|
||||
}
|
||||
|
||||
if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::VOID_TYPE)) {
|
||||
$classMethod->returnType = new Identifier('void');
|
||||
}
|
||||
|
||||
$assignStmts = $this->createAssignStmts($usedParams, $logoutEventVariable);
|
||||
$classMethod->stmts = array_merge($assignStmts, (array) $logoutClassMethod->stmts);
|
||||
|
||||
return $classMethod;
|
||||
}
|
||||
|
||||
private function createLogoutEventParam(Variable $logoutEventVariable): Param
|
||||
{
|
||||
$param = new Param($logoutEventVariable);
|
||||
$param->type = new FullyQualified('Symfony\Component\Security\Http\Event\LogoutEvent');
|
||||
return $param;
|
||||
return $usedParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Param[] $params
|
||||
* @return Expression[]
|
||||
*/
|
||||
private function createAssignStmts(array $params, Variable $logoutEventVariable): array
|
||||
private function createAssignStmts(array $params): array
|
||||
{
|
||||
$logoutEventVariable = new Variable('logoutEvent');
|
||||
|
||||
$assignStmts = [];
|
||||
foreach ($params as $param) {
|
||||
foreach (self::PARAMETER_TO_GETTER_NAMES as $parameterName => $getterName) {
|
||||
|
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Symfony5\NodeFactory;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\If_;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
||||
|
||||
final class OnSuccessLogoutClassMethodFactory
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const LOGOUT_EVENT = 'logoutEvent';
|
||||
|
||||
/**
|
||||
* @var NodeFactory
|
||||
*/
|
||||
private $nodeFactory;
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
|
||||
/**
|
||||
* @var SimpleCallableNodeTraverser
|
||||
*/
|
||||
private $simpleCallableNodeTraverser;
|
||||
|
||||
/**
|
||||
* @var BareLogoutClassMethodFactory
|
||||
*/
|
||||
private $bareLogoutClassMethodFactory;
|
||||
|
||||
public function __construct(
|
||||
NodeFactory $nodeFactory,
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
|
||||
BareLogoutClassMethodFactory $bareLogoutClassMethodFactory
|
||||
) {
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
|
||||
$this->bareLogoutClassMethodFactory = $bareLogoutClassMethodFactory;
|
||||
}
|
||||
|
||||
public function createFromOnLogoutSuccessClassMethod(ClassMethod $onLogoutSuccessClassMethod): ClassMethod
|
||||
{
|
||||
$classMethod = $this->bareLogoutClassMethodFactory->create();
|
||||
|
||||
$getResponseMethodCall = new MethodCall(new Variable(self::LOGOUT_EVENT), 'getResponse');
|
||||
$notIdentical = new NotIdentical($getResponseMethodCall, $this->nodeFactory->createNull());
|
||||
|
||||
$if = new If_($notIdentical);
|
||||
$if->stmts[] = new Return_();
|
||||
|
||||
// replace `return $response;` with `$logoutEvent->setResponse($response)`
|
||||
$this->replaceReturnResponseWithSetResponse($onLogoutSuccessClassMethod);
|
||||
$this->replaceRequestWithGetRequest($onLogoutSuccessClassMethod);
|
||||
|
||||
$oldClassStmts = (array) $onLogoutSuccessClassMethod->stmts;
|
||||
$classStmts = array_merge([$if], $oldClassStmts);
|
||||
$classMethod->stmts = $classStmts;
|
||||
|
||||
return $classMethod;
|
||||
}
|
||||
|
||||
private function replaceReturnResponseWithSetResponse(ClassMethod $classMethod): void
|
||||
{
|
||||
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($classMethod, function (Node $node): ?Expression {
|
||||
if (! $node instanceof Return_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($node->expr === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$args = $this->nodeFactory->createArgs([$node->expr]);
|
||||
$methodCall = new MethodCall(new Variable(self::LOGOUT_EVENT), 'setResponse', $args);
|
||||
|
||||
return new Expression($methodCall);
|
||||
});
|
||||
}
|
||||
|
||||
private function replaceRequestWithGetRequest(ClassMethod $classMethod): void
|
||||
{
|
||||
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($classMethod, function (Node $node): ?MethodCall {
|
||||
if (! $node instanceof Variable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->isName($node, 'request')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new MethodCall(new Variable(self::LOGOUT_EVENT), 'getRequest');
|
||||
});
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ final class LogoutHandlerToLogoutEventSubscriberRector extends AbstractRector
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change logout handler to an event listener that listens to LogoutEent', [
|
||||
return new RuleDefinition('Change logout handler to an event listener that listens to LogoutEvent', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
|
||||
|
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Symfony5\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Symfony5\NodeFactory\OnSuccessLogoutClassMethodFactory;
|
||||
use Rector\SymfonyCodeQuality\NodeFactory\GetSubscribedEventsClassMethodFactory;
|
||||
use Rector\SymfonyCodeQuality\ValueObject\EventReferenceToMethodNameWithPriority;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see https://github.com/symfony/symfony/pull/36243
|
||||
*
|
||||
* @see \Rector\Symfony5\Tests\Rector\Class_\LogoutSuccessHandlerToLogoutEventSubscriberRector\LogoutSuccessHandlerToLogoutEventSubscriberRectorTest
|
||||
*/
|
||||
final class LogoutSuccessHandlerToLogoutEventSubscriberRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const LOGOUT_SUCCESS_HANDLER_TYPE = 'Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface';
|
||||
|
||||
/**
|
||||
* @var GetSubscribedEventsClassMethodFactory
|
||||
*/
|
||||
private $getSubscribedEventsClassMethodFactory;
|
||||
|
||||
/**
|
||||
* @var OnSuccessLogoutClassMethodFactory
|
||||
*/
|
||||
private $onSuccessLogoutClassMethodFactory;
|
||||
|
||||
public function __construct(
|
||||
OnSuccessLogoutClassMethodFactory $onSuccessLogoutClassMethodFactory,
|
||||
GetSubscribedEventsClassMethodFactory $getSubscribedEventsClassMethodFactory
|
||||
) {
|
||||
$this->getSubscribedEventsClassMethodFactory = $getSubscribedEventsClassMethodFactory;
|
||||
$this->onSuccessLogoutClassMethodFactory = $onSuccessLogoutClassMethodFactory;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change logout success handler to an event listener that listens to LogoutEvent', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
final class SomeLogoutHandler implements LogoutSuccessHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @var HttpUtils
|
||||
*/
|
||||
private $httpUtils;
|
||||
|
||||
public function __construct(HttpUtils $httpUtils)
|
||||
{
|
||||
$this->httpUtils = $httpUtils;
|
||||
}
|
||||
|
||||
public function onLogoutSuccess(Request $request)
|
||||
{
|
||||
$response = $this->httpUtils->createRedirectResponse($request, 'some_url');
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Security\Http\Event\LogoutEvent;
|
||||
|
||||
final class SomeLogoutHandler implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var HttpUtils
|
||||
*/
|
||||
private $httpUtils;
|
||||
|
||||
public function onLogout(LogoutEvent $logoutEvent): void
|
||||
{
|
||||
if ($logoutEvent->getResponse() !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = $this->httpUtils->createRedirectResponse($logoutEvent->getRequest(), 'some_url');
|
||||
$logoutEvent->setResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
LogoutEvent::class => [['onLogout', 64]],
|
||||
];
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isObjectType($node, self::LOGOUT_SUCCESS_HANDLER_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->refactorImplements($node);
|
||||
|
||||
// 2. refactor logout() class method to onLogout()
|
||||
$onLogoutSuccessClassMethod = $node->getMethod('onLogoutSuccess');
|
||||
if (! $onLogoutSuccessClassMethod instanceof ClassMethod) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$node->stmts[] = $this->onSuccessLogoutClassMethodFactory->createFromOnLogoutSuccessClassMethod(
|
||||
$onLogoutSuccessClassMethod
|
||||
);
|
||||
|
||||
// 3. add getSubscribedEvents() class method
|
||||
$classConstFetch = $this->createClassConstReference('Symfony\Component\Security\Http\Event\LogoutEvent');
|
||||
|
||||
$eventReferencesToMethodNames = [new EventReferenceToMethodNameWithPriority($classConstFetch, 'onLogout', 64)];
|
||||
$getSubscribedEventsClassMethod = $this->getSubscribedEventsClassMethodFactory->create(
|
||||
$eventReferencesToMethodNames
|
||||
);
|
||||
$node->stmts[] = $getSubscribedEventsClassMethod;
|
||||
|
||||
$this->removeNode($onLogoutSuccessClassMethod);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function refactorImplements(Class_ $class): void
|
||||
{
|
||||
$class->implements[] = new FullyQualified('Symfony\Component\EventDispatcher\EventSubscriberInterface');
|
||||
|
||||
foreach ($class->implements as $key => $implement) {
|
||||
if (! $this->isName($implement, self::LOGOUT_SUCCESS_HANDLER_TYPE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unset($class->implements[$key]);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Symfony5\Tests\Rector\Class_\LogoutHandlerToLogoutEventSubscriberRector\Fixture;
|
||||
|
||||
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
final class LogoutHandlerWithoutAnyUsage implements LogoutHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $value;
|
||||
|
||||
public function logout(Request $request, Response $response, TokenInterface $token)
|
||||
{
|
||||
$this->value = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Symfony5\Tests\Rector\Class_\LogoutHandlerToLogoutEventSubscriberRector\Fixture;
|
||||
|
||||
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
final class LogoutHandlerWithoutAnyUsage implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $value;
|
||||
public function onLogout(\Symfony\Component\Security\Http\Event\LogoutEvent $logoutEvent): void
|
||||
{
|
||||
$this->value = 1000;
|
||||
}
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [\Symfony\Component\Security\Http\Event\LogoutEvent::class => 'onLogout'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Symfony5\Tests\Rector\Class_\LogoutSuccessHandlerToLogoutEventSubscriberRector\Fixture;
|
||||
|
||||
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
final class SimpleLogoutSuccessHandler implements LogoutSuccessHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @var HttpUtils
|
||||
*/
|
||||
private $httpUtils;
|
||||
|
||||
public function __construct(HttpUtils $httpUtils)
|
||||
{
|
||||
$this->httpUtils = $httpUtils;
|
||||
}
|
||||
|
||||
public function onLogoutSuccess(Request $request)
|
||||
{
|
||||
$response = $this->httpUtils->createRedirectResponse($request, 'some_url');
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Symfony5\Tests\Rector\Class_\LogoutSuccessHandlerToLogoutEventSubscriberRector\Fixture;
|
||||
|
||||
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
final class SimpleLogoutSuccessHandler implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var HttpUtils
|
||||
*/
|
||||
private $httpUtils;
|
||||
|
||||
public function __construct(HttpUtils $httpUtils)
|
||||
{
|
||||
$this->httpUtils = $httpUtils;
|
||||
}
|
||||
public function onLogout(\Symfony\Component\Security\Http\Event\LogoutEvent $logoutEvent): void
|
||||
{
|
||||
if ($logoutEvent->getResponse() !== null) {
|
||||
return;
|
||||
}
|
||||
$response = $this->httpUtils->createRedirectResponse($logoutEvent->getRequest(), 'some_url');
|
||||
$logoutEvent->setResponse($response);
|
||||
}
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [\Symfony\Component\Security\Http\Event\LogoutEvent::class => ['onLogout', 64]];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Symfony5\Tests\Rector\Class_\LogoutSuccessHandlerToLogoutEventSubscriberRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Symfony5\Rector\Class_\LogoutSuccessHandlerToLogoutEventSubscriberRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class LogoutSuccessHandlerToLogoutEventSubscriberRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return LogoutSuccessHandlerToLogoutEventSubscriberRector::class;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user