Find the best Rector rule to solve your problem. Searching through 1009 rules.

Found 101 rules:

RenameCopyOnWindowsOptionToFollowSymlinksRector

Rename copy_on_windows option to follow_symlinks in Filesystem::mirror()

 use Symfony\Component\Filesystem\Filesystem;

 final class Foo
 {
     public function __construct(private Filesystem $filesystem) {}

     public function bar($originDir, $targetDir): void
     {
-        $this->filesystem->mirror(targetDir: $originDir, originDir: $targetDir, options: $options = ['copy_on_windows' => true]);
+        $this->filesystem->mirror(targetDir: $originDir, originDir: $targetDir, options: $options = ['follow_symlinks' => true]);
     }
 }
PACKAGE:  symfony/filesystem >=8.1

ConstraintValidatorValidateToValidateInContextRector

Migrate deprecated ConstraintValidatorInterface::validate() in ConstraintValidatorTestCase tests to $this->validate(), otherwise to validateInContext() (Symfony 8.1+).

 use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;

 final class SomeValidatorTest extends ConstraintValidatorTestCase
 {
     public function test(): void
     {
-        $this->validator->validate($value, $constraint);
+        $this->validate($value, $constraint);
     }
 }
PACKAGE:  symfony/validator >=8.1

AddFormatArgumentToIsValidRector

Add $format argument to Ulid::isValid()

 Symfony\Component\Uid\Ulid;

 final class Foo
 {
     public function bar(string $id): bool
     {
-        return Ulid::isValid($id);
+        return Ulid::isValid($id, Symfony\Component\Uid\Ulid::FORMAT_BASE_32);
     }
 }
SETS:  symfony/uid
PACKAGE:  symfony/uid >=8.1

RemoveEraseCredentialsFromAuthenticatorManagerRector

Remove unused $eraseCredentials argument from AuthenticatorManager constructor

 use Symfony\Component\Security\Http\Authentication\AuthenticatorManager;

 final class Foo
 {
     public function bar(): void
     {
         new AuthenticatorManager(
             $authenticators,
             $tokenStorage,
             $eventDispatcher,
             $firewallName,
-            true
         );
     }
 }
PACKAGE:  symfony/security-http >=8.1

RemoveEraseCredentialsRector

Remove unused UserInterface::eraseCredentials() method, make it part of serialize if needed

 use Symfony\Component\Security\Core\User\UserInterface;

 final class User implements UserInterface
 {
-    public function eraseCredentials()
-    {
-        // some logic here
-    }
 }
PACKAGE:  symfony/security-core >=8.0

AuthorizationCheckerToAccessDecisionManagerInVoterRector

Replaces AuthorizationCheckerInterface with AccessDecisionManagerInterface inside Symfony Voters

-use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
+use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
 use Symfony\Component\Security\Core\Authorization\Voter\Voter;
 use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

 final class AuthorizationCheckerVoter extends Voter
 {
     public function __construct(
-        private AuthorizationCheckerInterface $authorizationChecker
+        private AccessDecisionManagerInterface $accessDecisionManager
     ) {}

     protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
     {
-        return $this->authorizationChecker->isGranted('ROLE_ADMIN', $subject);
+        return $this->accessDecisionManager->decide($token, ['ROLE_ADMIN'], $subject);
     }
 }
PACKAGE:  symfony/security-core >=7.3

CommandDefaultNameAndDescriptionToAsCommandAttributeRector

Replace getDefaultName() and getDefaultDescription() by #[AsCommand] attribute

+use Symfony\Component\Console\Attribute\AsCommand;
 use Symfony\Component\Console\Command\Command;

+#[AsCommand(
+    name: 'app:some-command',
+    description: 'This is some command description'
+)]
 final class SomeCommand extends Command
 {
-    public static function getDefaultName(): string
-    {
-        return 'app:some-command';
-    }
-
-    public static function getDefaultDescription(): string
-    {
-        return 'This is some command description';
-    }
 }
SETS:  symfony/console
PACKAGE:  symfony/console >=7.3

CommandHelpToAttributeRector

Moves $this->setHelp() to the "help" named argument of #[AsCommand]

 use Symfony\Component\Console\Attribute\AsCommand;
 use Symfony\Component\Console\Command\Command;

-#[AsCommand(name: 'app:some')]
+#[AsCommand(name: 'app:some', help: <<<'TXT'
+Some help text
+TXT)]
 final class SomeCommand extends Command
 {
-    protected function configure(): void
-    {
-        $this->setHelp('Some help text');
-    }
 }
SETS:  symfony/console
PACKAGE:  symfony/console >=7.3

ConstraintOptionsToNamedArgumentsRector

Refactor Symfony constraints using array options to named arguments syntax for better readability and type safety.

 use Symfony\Component\Validator\Constraints\NotBlank;

-$constraint = new NotBlank(['message' => 'This field should not be blank.']);
+$constraint = new NotBlank(message: 'This field should not be blank.');
PACKAGE:  symfony/validator >=7.3

AddVoteArgumentToVoteOnAttributeRector

Adds a new $voter argument in protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token, ?Vote $vote = null): bool

 use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
 use Symfony\Component\Security\Core\Authorization\Voter\Voter;

 final class MyVoter extends Voter
 {
     protected function supports(string $attribute, mixed $subject): bool
     {
         return true;
     }

-    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
+    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token, ?\Symfony\Component\Security\Core\Authorization\Voter\Vote $vote = null): bool
     {
         return true;
     }
 }
PACKAGE:  symfony/security-core >=7.3

InvokableCommandInputAttributeRector

Change Symfony Command with execute() + configure() to __invoke() with attributes

 use Symfony\Component\Console\Attribute\AsCommand;
 use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Argument;
+use Symfony\Component\Console\Option;

 #[AsCommand(name: 'some_name')]
-final class SomeCommand extends Command
+final class SomeCommand
 {
-    public function configure()
-    {
-        $this->addArgument('argument', InputArgument::REQUIRED, 'Argument description');
-        $this->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description');
-    }
-
-    public function execute(InputInterface $input, OutputInterface $output)
-    {
-        $someArgument = $input->getArgument('argument');
-        $someOption = $input->getOption('option');
+    public function __invoke(
+        #[Argument(name: 'argument', description: 'Argument description')]
+        string $argument,
+        #[Option(name: 'option', shortcut: 'o', mode: Option::VALUE_NONE, description: 'Option description')]
+        bool $option = false,
+    ) {
+        $someArgument = $argument;
+        $someOption = $option;

         // ...

         return Command::SUCCESS;
     }
 }
PACKAGE:  symfony/console >=7.3

PushRequestToRequestStackConstructorRector

Move push(request) to "Symfony\Component\HttpFoundation\RequestStack" constructor

 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
 use PHPUnit\Framework\TestCase;

-final class SomeClass extends TestCase
+class SomeClass extends TestCase
 {
     public function run()
     {
-        $requestStack = new RequestStack();
         $request = new Request();
-        $requestStack->push($request);
+        $requestStack = new RequestStack([$request]);
     }
 }
PACKAGE:  symfony/http-foundation >=7.2

ParamAndEnvAttributeRector

Make param/env use in #[Attribute] more precise

 namespace App\Service;

 use Symfony\Component\DependencyInjection\Attribute\Autowire;

 class MessageGenerator
 {
     public function __construct(
-        #[Autowire('%kernel.debug%')]
+        #[Autowire(param: 'kernel.debug')]
         bool $debugMode,

-        #[Autowire('%env(SOME_ENV_VAR)%')]
+        #[Autowire(env: 'SOME_ENV_VAR')]
         string $senderName,
     ) {
     }
 }
PACKAGE:  symfony/dependency-injection >=6.3

SignalableCommandInterfaceReturnTypeRector

Return int or false from SignalableCommandInterface::handleSignal() instead of void

-public function handleSignal(int $signal): void
+public function handleSignal(int $signal): int|false
     {
+        return false;
     }
SETS:  symfony/console
PACKAGE:  symfony/console >=6.3

SecurityAttributeToIsGrantedAttributeRector

Replaces #[Security] framework-bundle attribute with Symfony native #[IsGranted] one

-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
+use Symfony\Component\ExpressionLanguage\Expression;
+use Symfony\Component\Security\Http\Attribute\IsGranted;

 class PostController extends Controller
 {
-    #[Security("is_granted('ROLE_ADMIN')")]
+    #[IsGranted(attribute: 'ROLE_ADMIN')]
     public function index()
     {
     }

-    #[Security("is_granted('ROLE_ADMIN') and is_granted('ROLE_FRIENDLY_USER')")]
+    #[IsGranted(attribute: new Expression("is_granted('ROLE_ADMIN') and is_granted('ROLE_FRIENDLY_USER')"))]
     public function list()
     {
     }
 }
PACKAGE:  symfony/security-http >=6.2

MessageHandlerInterfaceToAttributeRector

Replaces MessageHandlerInterface with AsMessageHandler attribute

-use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
+use Symfony\Component\Messenger\Attribute\AsMessageHandler;

-class SmsNotificationHandler implements MessageHandlerInterface
+#[AsMessageHandler]
+class SmsNotificationHandler
 {
     public function __invoke(SmsNotification $message)
     {
         // ... do some work - like sending an SMS message!
     }
 }
PACKAGE:  symfony/messenger >=6.2

MessageSubscriberInterfaceToAttributeRector

Replace MessageSubscriberInterface with AsMessageHandler attribute(s)

-use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
+use Symfony\Component\Messenger\Attribute\AsMessageHandler;

-class SmsNotificationHandler implements MessageSubscriberInterface
+class SmsNotificationHandler
 {
-    public function __invoke(SmsNotification $message)
+    #[AsMessageHandler]
+    public function handleSmsNotification(SmsNotification $message)
     {
         // ...
     }

+    #[AsMessageHandler(priority: 0, bus: 'messenger.bus.default']
     public function handleOtherSmsNotification(OtherSmsNotification $message)
     {
         // ...
-    }
-
-    public static function getHandledMessages(): iterable
-    {
-        // handle this message on __invoke
-        yield SmsNotification::class;
-
-        // also handle this message on handleOtherSmsNotification
-        yield OtherSmsNotification::class => [
-            'method' => 'handleOtherSmsNotification',
-            'priority' => 0,
-            'bus' => 'messenger.bus.default',
-        ];
     }
 }
PACKAGE:  symfony/messenger >=6.2

ParamConverterAttributeToMapEntityAttributeRector

Replace ParamConverter attribute with mappings with the MapEntity attribute

+use Symfony\Bridge\Doctrine\Attribute\MapEntity;
+
 class SomeController
 {
-    #[ParamConverter('post', options: ['mapping' => ['date' => 'date', 'slug' => 'slug']])]
-    #[ParamConverter('comment', options: ['mapping' => ['comment_slug' => 'slug']])]
     public function showComment(
+        #[MapEntity(mapping: ['date' => 'date', 'slug' => 'slug'])]
         Post $post,

+        #[MapEntity(mapping: ['comment_slug' => 'slug'])]
         Comment $comment
     ) {
     }
 }
PACKAGE:  symfony/doctrine-bridge >=6.2

ArgumentValueResolverToValueResolverRector

Replaces ArgumentValueResolverInterface by ValueResolverInterface with supports logic moved to resolve() method

-use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
+use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;

-final class EntityValueResolver implements ArgumentValueResolverInterface
+final class EntityValueResolver implements ValueResolverInterface
 {
-    public function supports(Request $request, ArgumentMetadata $argument): bool
-    {
-    }
-
     public function resolve(Request $request, ArgumentMetadata $argument): iterable
     {
     }
 }
PACKAGE:  symfony/http-kernel >=6.2

SingleConditionSecurityAttributeToIsGrantedRector

Narrow #[Security] attribute with inner single "is_granted/has_role" condition string to #[IsGranted] attribute

-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
+use Symfony\Component\Security\Http\Attribute\IsGranted;

-#[Security("is_granted('ROLE_USER')")]
+#[IsGranted('ROLE_USER')]
 class SomeClass
 {
 }
PACKAGE:  symfony/security-http >=6.2

SplitAndSecurityAttributeToIsGrantedRector

Split #[Security] attribute with "and" condition string to multiple #[IsGranted] attributes with sole values

-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
+use Symfony\Component\Security\Http\Attribute\IsGranted;

-#[Security("is_granted('ROLE_USER') and has_role('ROLE_ADMIN')")]
+#[IsGranted('ROLE_USER')]
+#[IsGranted('ROLE_ADMIN')]
 class SomeClass
 {
 }
PACKAGE:  symfony/security-http >=6.2

RouteRequirementStringToConstantRector

Replace regex string in #[Route] requirements with a Requirement constant

 use Symfony\Component\Routing\Attribute\Route;
+use Symfony\Component\Routing\Requirement\Requirement;

 final class SomeController
 {
     #[Route('/detail/{id}', requirements: [
-        'id' => '[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}',
+        'id' => Requirement::UUID_V4,
     ])]
     public function detail()
     {
     }
 }
SETS:  symfony/routing
PACKAGE:  symfony/routing >=6.1

ErrorNamesPropertyToConstantRector

Turns old Constraint::$errorNames properties to use Constraint::ERROR_NAMES instead

 use Symfony\Component\Validator\Constraints\NotBlank;

 class SomeClass
 {
-    NotBlank::$errorNames
+    NotBlank::ERROR_NAMES

 }
PACKAGE:  symfony/validator >=6.1

CommandConfigureToAttributeRector

Add Symfony\Component\Console\Attribute\AsCommand to Symfony Commands from configure()

+use Symfony\Component\Console\Attribute\AsCommand;
 use Symfony\Component\Console\Command\Command;

+#[AsCommand(name: 'sunshine', description: 'Some description')]
 final class SunshineCommand extends Command
 {
-    public function configure()
-    {
-        $this->setName('sunshine');
-        $this->setDescription('Some description');
-
-    }
 }
SETS:  symfony/console
PACKAGE:  symfony/console >=6.1

MagicClosureTwigExtensionToNativeMethodsRector

Change TwigExtension function/filter magic closures to inlined and clear callables

 use Twig\Extension\AbstractExtension;
 use Twig\TwigFunction;

 final class TerminologyExtension extends AbstractExtension
 {
     public function getFunctions(): array
     {
         return [
-            new TwigFunction('resolve', [$this, 'resolve']);
+            new TwigFunction('resolve', $this->resolve(...)),
         ];
     }

     private function resolve($value)
     {
         return $value + 100;
     }
 }
PACKAGE:  symfony/twig-bridge >=6.1

CommandPropertyToAttributeRector

Add Symfony\Component\Console\Attribute\AsCommand to Symfony Commands and remove the deprecated properties

+use Symfony\Component\Console\Attribute\AsCommand;
 use Symfony\Component\Console\Command\Command;

+#[AsCommand(name: 'sunshine', description: 'some description')]
 final class SunshineCommand extends Command
 {
-    public static $defaultName = 'sunshine';
-
-    public static $defaultDescription = 'some description';
 }
SETS:  symfony/console
PACKAGE:  symfony/console >=6.1

GetHelperControllerToServiceRector

Replace $this->getDoctrine() and $this->dispatchMessage() calls in AbstractController with direct service use

 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Doctrine\Persistence\ManagerRegistry;

 final class SomeController extends AbstractController
 {
+    public function __construct(
+        private ManagerRegistry $managerRegistry
+    ) {
+    }
+
     public function run()
     {
-        $productRepository = $this->getDoctrine()->getRepository(Product::class);
+        $productRepository = $this->managerRegistry->getRepository(Product::class);
     }
 }
PACKAGE:  symfony/framework-bundle >=6.0

ContainerInterfaceServiceToServiceContainerRector

Replace removed ContainerInterface alias with "service_container" service id in service() call

 use function Symfony\Component\DependencyInjection\Loader\Configurator\service;

-return service(ContainerInterface::class);
+return service('service_container');
PACKAGE:  symfony/dependency-injection >=6.0

KernelTestCaseContainerPropertyDeprecationRector

Simplify use of assertions in WebTestCase

 use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

 class SomeTest extends KernelTestCase
 {
     protected function setUp(): void
     {
-        $container = self::$container;
+        $container = self::getContainer();
     }
 }
PACKAGE:  symfony/framework-bundle >=5.3

DefinitionAliasSetPrivateToSetPublicRector

Migrates from deprecated Definition/Alias->setPrivate() to Definition/Alias->setPublic()

 use Symfony\Component\DependencyInjection\Alias;
 use Symfony\Component\DependencyInjection\Definition;

 class SomeClass
 {
     public function run()
     {
         $definition = new Definition('Example\Foo');
-        $definition->setPrivate(false);
+        $definition->setPublic(true);

         $alias = new Alias('Example\Foo');
-        $alias->setPrivate(false);
+        $alias->setPublic(true);
     }
 }
PACKAGE:  symfony/dependency-injection >=5.2

ReflectionExtractorEnableMagicCallExtractorRector

Migrates from deprecated enable_magic_call_extraction context option in ReflectionExtractor

 use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;

 class SomeClass
 {
     public function run()
     {
         $reflectionExtractor = new ReflectionExtractor();
         $readInfo = $reflectionExtractor->getReadInfo(Dummy::class, 'bar', [
-            'enable_magic_call_extraction' => true,
+            'enable_magic_methods_extraction' => ReflectionExtractor::MAGIC_CALL | ReflectionExtractor::MAGIC_GET | ReflectionExtractor::MAGIC_SET,
         ]);
     }
 }
PACKAGE:  symfony/property-info >=5.2

ValidatorBuilderEnableAnnotationMappingRector

Migrates from deprecated ValidatorBuilder->enableAnnotationMapping($reader) to ValidatorBuilder->enableAnnotationMapping(true)->setDoctrineAnnotationReader($reader)

 use Doctrine\Common\Annotations\Reader;
 use Symfony\Component\Validator\ValidatorBuilder;

 class SomeClass
 {
     public function run(ValidatorBuilder $builder, Reader $reader)
     {
-        $builder->enableAnnotationMapping($reader);
+        $builder->enableAnnotationMapping(true)->setDoctrineAnnotationReader($reader);
     }
 }
PACKAGE:  symfony/validator >=5.2

FormBuilderSetDataMapperRector

Migrates from deprecated Form Builder->setDataMapper(new PropertyPathMapper()) to Builder->setDataMapper(new DataMapper(new PropertyPathAccessor()))

 use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
 use Symfony\Component\Form\FormConfigBuilderInterface;
+use Symfony\Component\Form\Extension\Core\DataMapper\DataMapper;
+use Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor;

 class SomeClass
 {
     public function run(FormConfigBuilderInterface $builder)
     {
-        $builder->setDataMapper(new PropertyPathMapper());
+        $builder->setDataMapper(new DataMapper(new PropertyPathAccessor()));
     }
 }
SETS:  symfony/form
PACKAGE:  symfony/form >=5.2

BinaryFileResponseCreateToNewInstanceRector

Change deprecated BinaryFileResponse::create() to use __construct() instead

 use Symfony\Component\HttpFoundation;

 class SomeClass
 {
     public function run()
     {
-        $binaryFile = BinaryFileResponse::create();
+        $binaryFile = new BinaryFileResponse(null);
     }
 }
PACKAGE:  symfony/http-foundation >=5.2

PropertyAccessorCreationBooleanToFlagsRector

Changes first argument of PropertyAccessor::__construct() to flags from boolean

 use Symfony\Component\PropertyAccess\PropertyAccessor;

 class SomeClass
 {
     public function run()
     {
-        $propertyAccessor = new PropertyAccessor(true);
+        $propertyAccessor = new PropertyAccessor(PropertyAccessor::MAGIC_CALL | PropertyAccessor::MAGIC_GET | PropertyAccessor::MAGIC_SET);
     }
 }
PACKAGE:  symfony/property-access >=5.2

PropertyPathMapperToDataMapperRector

Migrate from PropertyPathMapper to DataMapper and PropertyPathAccessor

 use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;

 class SomeClass
 {
     public function run()
     {
-        return new PropertyPathMapper();
+        return new \Symfony\Component\Form\Extension\Core\DataMapper\DataMapper(new \Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor());
     }
 }
SETS:  symfony/form
PACKAGE:  symfony/form >=5.2

LoadValidatorMetadataToAttributeRector

Move metadata from loadValidatorMetadata() to property/getter/class attributes

 use Symfony\Component\Validator\Constraints as Assert;
 use Symfony\Component\Validator\Mapping\ClassMetadata;

 final class SomeClass
 {
+    #[Assert\NotBlank(message: 'City can\'t be blank.')]
     private $city;
-
-    public static function loadValidatorMetadata(ClassMetadata $metadata): void
-    {
-        $metadata->addPropertyConstraint('city', new Assert\NotBlank([
-            'message' => 'City can\'t be blank.',
-        ]));
-    }
 }
PACKAGE:  symfony/validator >=5.2

LogoutHandlerToLogoutEventSubscriberRector

Change logout handler to an event listener that listens to LogoutEvent

-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;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\Security\Http\Event\LogoutEvent;

-final class SomeLogoutHandler implements LogoutHandlerInterface
+final class SomeLogoutHandler implements EventSubscriberInterface
 {
-    public function logout(Request $request, Response $response, TokenInterface $token)
+    public function onLogout(LogoutEvent $logoutEvent): void
+    {
+        $request = $logoutEvent->getRequest();
+        $response = $logoutEvent->getResponse();
+        $token = $logoutEvent->getToken();
+    }
+
+    /**
+     * @return array<string, string[]>
+     */
+    public static function getSubscribedEvents(): array
     {
+        return [
+            LogoutEvent::class => ['onLogout'],
+        ];
     }
 }
PACKAGE:  symfony/security-http >=5.1

LogoutSuccessHandlerToLogoutEventSubscriberRector

Change logout success handler to an event listener that listens to LogoutEvent

-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;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\Security\Http\Event\LogoutEvent;

-final class SomeLogoutHandler implements LogoutSuccessHandlerInterface
+final class SomeLogoutHandler implements EventSubscriberInterface
 {
     /**
       * @var HttpUtils
       */
     private $httpUtils;

-    public function __construct(HttpUtils $httpUtils)
+    public function onLogout(LogoutEvent $logoutEvent): void
     {
-        $this->httpUtils = $httpUtils;
+        if ($logoutEvent->getResponse() !== null) {
+            return;
+        }
+
+        $response = $this->httpUtils->createRedirectResponse($logoutEvent->getRequest(), 'some_url');
+        $logoutEvent->setResponse($response);
     }

-    public function onLogoutSuccess(Request $request)
+    /**
+     * @return array<string, mixed>
+     */
+    public static function getSubscribedEvents(): array
     {
-        $response = $this->httpUtils->createRedirectResponse($request, 'some_url');
-        return $response;
+        return [
+            LogoutEvent::class => [['onLogout', 64]],
+        ];
     }
 }
PACKAGE:  symfony/security-http >=5.1

RouteCollectionBuilderToRoutingConfiguratorRector

Change RouteCollectionBuilder to RoutingConfiguratorRector

 use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
 use Symfony\Component\HttpKernel\Kernel;
-use Symfony\Component\Routing\RouteCollectionBuilder;
+use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

 final class ConcreteMicroKernel extends Kernel
 {
     use MicroKernelTrait;

-    protected function configureRoutes(RouteCollectionBuilder $routes)
+    protected function configureRouting(RoutingConfigurator $routes): void
     {
-        $routes->add('/admin', 'App\Controller\AdminController::dashboard', 'admin_dashboard');
-    }
-}
+        $routes->add('admin_dashboard', '/admin')
+            ->controller('App\Controller\AdminController::dashboard')
+    }}
PACKAGE:  symfony/framework-bundle >=5.1

CommandConstantReturnCodeRector

Changes int return from execute to use Symfony Command constants.

 class SomeCommand extends Command
 {
     protected function execute(InputInterface $input, OutputInterface $output): int
     {
-        return 0;
+        return \Symfony\Component\Console\Command\Command::SUCCESS;
     }

 }
SETS:  symfony/console
PACKAGE:  symfony/console >=5.1

AuthorizationCheckerIsGrantedExtractorRector

Change $this->authorizationChecker->isGranted([$a, $b]) to $this->authorizationChecker->isGranted($a) || $this->authorizationChecker->isGranted($b), also updates AbstractController usages

 use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

 final class SomeController
 {
     public function __construct(
         private AuthorizationCheckerInterface $authorizationChecker
     ) {
     }

     public function hasAccess(): bool
     {
-        if ($this->authorizationChecker->isGranted(['ROLE_USER', 'ROLE_ADMIN'])) {
+        if ($this->authorizationChecker->isGranted('ROLE_USER') || $this->authorizationChecker->isGranted('ROLE_ADMIN')) {
             return true;
         }

         return false;
     }
 }
PACKAGE:  symfony/security-core >=4.4

ConsoleExecuteReturnIntRector

Returns int from Command::execute() command

 use Symfony\Component\Console\Command\Command;

 class SomeCommand extends Command
 {
-    public function execute(InputInterface $input, OutputInterface $output)
+    public function execute(InputInterface $input, OutputInterface $output): int
     {
-        return null;
+        return 0;
     }
 }
SETS:  symfony/console
PACKAGE:  symfony/console >=4.4

MakeDispatchFirstArgumentEventRector

Make event object a first argument of dispatch() method, event name as second

 use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

 class SomeClass
 {
     public function run(EventDispatcherInterface $eventDispatcher)
     {
-        $eventDispatcher->dispatch('event_name', new Event());
+        $eventDispatcher->dispatch(new Event(), 'event_name');
     }
 }
PACKAGE:  symfony/event-dispatcher >=4.3

ConvertRenderTemplateShortNotationToBundleSyntaxRector

Change Twig template short name to bundle syntax in render calls from controllers

 use Symfony\Bundle\FrameworkBundle\Controller\Controller;

 class BaseController extends Controller
 {
     function indexAction()
     {
-        $this->render('appBundle:Landing\Main:index.html.twig');
+        $this->render('@app/Landing/Main/index.html.twig');
     }
 }
PACKAGE:  symfony/framework-bundle >=4.3

GetCurrencyBundleMethodCallsToIntlRector

Intl static bundle method were changed to direct static calls

-$currencyBundle = \Symfony\Component\Intl\Intl::getCurrencyBundle();
-
-$currencyNames = $currencyBundle->getCurrencyNames();
+$currencyNames = \Symfony\Component\Intl\Currencies::getNames();
SETS:  symfony/intl
PACKAGE:  symfony/intl >=4.3

TwigBundleFilesystemLoaderToTwigRector

Change TwigBundle FilesystemLoader to native one

-use Symfony\Bundle\TwigBundle\Loader\FilesystemLoader;
-use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
-use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser;
+use Twig\Loader\FilesystemLoader;

-$filesystemLoader = new FilesystemLoader(new TemplateLocator(), new TemplateParser());
-$filesystemLoader->addPath(__DIR__ . '/some-directory');
+$fileSystemLoader = new FilesystemLoader([__DIR__ . '/some-directory']);
PACKAGE:  symfony/twig-bundle >=4.3

EventDispatcherParentConstructRector

Removes parent construct method call in EventDispatcher class

 use Symfony\Component\EventDispatcher\EventDispatcher;

 final class SomeEventDispatcher extends EventDispatcher
 {
     public function __construct()
     {
         $value = 1000;
+        parent::__construct();
     }
 }
PACKAGE:  symfony/event-dispatcher >=4.3

RootNodeTreeBuilderRector

Changes TreeBuilder with root() call to constructor passed root and getRootNode() call

 use Symfony\Component\Config\Definition\Builder\TreeBuilder;

-$treeBuilder = new TreeBuilder();
-$rootNode = $treeBuilder->root('acme_root');
+$treeBuilder = new TreeBuilder('acme_root');
+$rootNode = $treeBuilder->getRootNode();
 $rootNode->someCall();
SETS:  symfony/config
PACKAGE:  symfony/config >=4.2

StringToArrayArgumentProcessRector

Changes Process string argument to an array

 use Symfony\Component\Process\Process;
-$process = new Process('ls -l');
+$process = new Process(['ls', '-l']);
SETS:  symfony/process
PACKAGE:  symfony/process >=4.2

VarDumperTestTraitMethodArgsRector

Adds a new $filter argument in VarDumperTestTrait->assertDumpEquals() and VarDumperTestTrait->assertDumpMatchesFormat() in Validator in Symfony.

-$varDumperTestTrait->assertDumpEquals($dump, $data, $message = "");
+$varDumperTestTrait->assertDumpEquals($dump, $data, $filter = 0, $message = "");
PACKAGE:  symfony/var-dumper >=4.0

FormIsValidRector

Adds $form->isSubmitted() validation to all $form->isValid() calls in Form in Symfony

-if ($form->isValid()) {
+if ($form->isSubmitted() && $form->isValid()) {
     // ...
 }
SETS:  symfony/form
PACKAGE:  symfony/form >=4.0

ContainerBuilderCompileEnvArgumentRector

Turns old default value to parameter in ContainerBuilder->build() method in DI in Symfony

 use Symfony\Component\DependencyInjection\ContainerBuilder;

 $containerBuilder = new ContainerBuilder();
-$containerBuilder->compile();
+$containerBuilder->compile(true);
PACKAGE:  symfony/dependency-injection >=4.0

ConstraintUrlOptionRector

Turns true value to Url::CHECK_DNS_TYPE_ANY in Validator in Symfony.

-$constraint = new Url(["checkDNS" => true]);
+$constraint = new Url(["checkDNS" => Url::CHECK_DNS_TYPE_ANY]);
PACKAGE:  symfony/validator >=4.0

GetFiltersAndFunctionsToAsTwigAttributeRector

Changes getFilters(), getFunctions() and getTests() in TwigExtension to #[AsTwigFilter], #[AsTwigFunction] and #[AsTwigTest] marker attributes above local class methods

-use Twig\Extension\AbstractExtension;
+use Twig\Attribute\AsTwigFilter;
+use Twig\Attribute\AsTwigFunction;
 use Twig\Environment;

-class SomeClass extends AbstractExtension
+class SomeClass
 {
-    public function getFilters()
-    {
-        return [
-            new \Twig\TwigFilter('filter_name', [$this, 'localMethod'], ['needs_environment' => true]),
-        ];
-    }
-
-    public function getFunctions()
-    {
-        return [
-            new \Twig\TwigFunction('function_name', [$this, 'localMethod'], ['needs_environment' => true]),
-        ];
-    }
-
+    #[AsTwigFilter(name: 'filter_name', needsEnvironment: true)]
+    #[AsTwigFunction(name: 'function_name', needsEnvironment: true)]
     public function localMethod(Environment $env, $value)
     {
         return $value;
     }
 }
SETS:  twig/twig
PACKAGE:  twig/twig >=3.21

AccessorAnnotationToAttributeRector

Changes @Accessor annotation to #[Accessor] attribute with specific "getter" or "setter" keys

 use JMS\Serializer\Annotation\Accessor;

 class User
 {
-    /**
-     * @Accessor("getValue")
-     */
+    #[Accessor(getter: 'getValue')]
     private $value;
 }
SETS:  jms/serializer
PACKAGE:  jms/serializer >=3.14

AccessTypeAnnotationToAttributeRector

Changes @AccessType annotation to #[AccessType] attribute with specific key

 use JMS\Serializer\Annotation\AccessType;

-/** @AccessType("public_method") */
+#[AccessType(values: ['public_method'])]
 class User
 {
 }
SETS:  jms/serializer
PACKAGE:  jms/serializer >=3.14

ContainerGetNameToTypeInTestsRector

Change $container->get("some_name") in tests to bare type, useful since Symfony 3.4

 use PHPUnit\Framework\TestCase;

 final class SomeTest extends TestCase
 {
     public function run()
     {
         $container = $this->getContainer();
-        $someClass = $container->get('some_name');
+        $someClass = $container->get(SomeType::class);
     }
 }
PACKAGE:  symfony/dependency-injection >=3.4

MergeMethodAnnotationToRouteAnnotationRector

Merge removed @Method annotation to @Route one

-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 use Symfony\Component\Routing\Annotation\Route;

 class DefaultController extends Controller
 {
     /**
-     * @Route("/show/{id}")
-     * @Method({"GET", "HEAD"})
+     * @Route("/show/{id}", methods={"GET","HEAD"})
      */
     public function show($id)
     {
     }
 }
SETS:  symfony/routing
PACKAGE:  symfony/routing >=3.4

ReplaceSensioRouteAnnotationWithSymfonyRector

Replace Sensio @Route annotation with Symfony one

-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
+use Symfony\Component\Routing\Annotation\Route;

 final class SomeClass
 {
     /**
      * @Route()
      */
     public function run()
     {
     }
 }
SETS:  symfony/routing
PACKAGE:  symfony/routing >=3.4

RemoveServiceFromSensioRouteRector

Remove service from Sensio @Route

 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

 final class SomeClass
 {
     /**
-     * @Route(service="some_service")
+     * @Route()
      */
     public function run()
     {
     }
 }
SETS:  symfony/routing
PACKAGE:  symfony/routing >=3.4

ConsoleExceptionToErrorEventConstantRector

Turns old event name with EXCEPTION to ERROR constant in Console in Symfony

-"console.exception"
+RectorPrefix202608\Symfony\Component\Console\ConsoleEvents::ERROR
SETS:  symfony/console
PACKAGE:  symfony/console >=3.3

OptionNameRector

Turns old option names to new ones in FormTypes in Form in Symfony

 use Symfony\Component\Form\FormBuilder;

 $formBuilder = new FormBuilder;
-$formBuilder->add("...", ["precision" => "...", "virtual" => "..."];
+$formBuilder->add("...", ["scale" => "...", "inherit_data" => "..."];
SETS:  symfony/form
PACKAGE:  symfony/form >=3.0

StringFormTypeToClassRector

Turns string Form Type references to their CONSTANT alternatives in FormTypes in Form in Symfony. To enable custom types, add link to your container XML dump in "$rectorConfig->symfonyContainerXml(...)"

 $formBuilder = new Symfony\Component\Form\FormBuilder;
-$formBuilder->add('name', 'form.type.text');
+$formBuilder->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class);
SETS:  symfony/form
PACKAGE:  symfony/form >=3.0

ChangeStringCollectionOptionToConstantRector

Change type in CollectionType from alias string to class reference

 use Symfony\Component\Form\AbstractType;
 use Symfony\Component\Form\FormBuilderInterface;
 use Symfony\Component\Form\Extension\Core\Type\CollectionType;

 class TaskType extends AbstractType
 {
     public function buildForm(FormBuilderInterface $builder, array $options)
     {
         $builder->add('tags', CollectionType::class, [
-            'type' => 'choice',
+            'type' => \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class,
         ]);

         $builder->add('tags', 'collection', [
-            'type' => 'choice',
+            'type' => \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class,
         ]);
     }
 }
SETS:  symfony/form
PACKAGE:  symfony/form >=3.0

FormTypeInstanceToClassConstRector

Changes createForm(new FormType), add(new FormType) to ones with "FormType::class"

 use Symfony\Bundle\FrameworkBundle\Controller\Controller;

 final class SomeController extends Controller
 {
     public function action()
     {
-        $form = $this->createForm(new TeamType);
+        $form = $this->createForm(TeamType::class);
     }
 }
PACKAGE:  symfony/framework-bundle >=3.0

ReadOnlyOptionToAttributeRector

Change "read_only" option in form to attribute

 use Symfony\Component\Form\FormBuilderInterface;

 function buildForm(FormBuilderInterface $builder, array $options)
 {
-    $builder->add('cuid', TextType::class, ['read_only' => true]);
+    $builder->add('cuid', TextType::class, ['attr' => ['read_only' => true]]);
 }
SETS:  symfony/form
PACKAGE:  symfony/form >=3.0

FormTypeGetParentRector

Turns string Form Type references to their CONSTANT alternatives in getParent() and getExtendedType() methods in Form in Symfony

 use Symfony\Component\Form\AbstractType;

 class SomeType extends AbstractType
 {
     public function getParent()
     {
-        return 'collection';
+        return \Symfony\Component\Form\Extension\Core\Type\CollectionType::class;
     }
 }
SETS:  symfony/form
PACKAGE:  symfony/form >=3.0

GetToConstructorInjectionRector

Turns fetching of dependencies via $this->get() to constructor injection in Command and Controller

 use Symfony\Bundle\FrameworkBundle\Controller\Controller;

 final class SomeController extend Controller
 {
+    public function __construct(SomeService $someService)
+    {
+        $this->someService = $someService;
+    }
+
     public function someMethod()
     {
-        // ...
-        $this->get('some_service');
+        $this->someService;
     }
 }
PACKAGE:  symfony/framework-bundle >=2.8

ParseFileRector

Replaces deprecated Yaml::parse() of file argument with file contents

 use Symfony\Component\Yaml\Yaml;

-$parsedFile = Yaml::parse('someFile.yml');
+$parsedFile = Yaml::parse(file_get_contents('someFile.yml'));
SETS:  symfony/yaml
PACKAGE:  symfony/yaml >=2.8

ChangeCollectionTypeOptionNameFromTypeToEntryTypeRector

Rename type option to entry_type in CollectionType

 use Symfony\Component\Form\AbstractType;
 use Symfony\Component\Form\FormBuilderInterface;
 use Symfony\Component\Form\Extension\Core\Type\CollectionType;
 use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

 class TaskType extends AbstractType
 {
     public function buildForm(FormBuilderInterface $builder, array $options)
     {
         $builder->add('tags', CollectionType::class, [
-            'type' => ChoiceType::class,
-            'options' => [1, 2, 3],
+            'entry_type' => ChoiceType::class,
+            'entry_options' => [1, 2, 3],
         ]);
     }
 }
SETS:  symfony/form
PACKAGE:  symfony/form >=2.7

RedirectToRouteRector

Turns redirect to route to short helper method in Controller in Symfony

-$this->redirect($this->generateUrl("homepage"));
+$this->redirectToRoute("homepage");
PACKAGE:  symfony/framework-bundle >=2.6

GetRequestRector

Turns fetching of Request via $this->getRequest() to action injection

+use Symfony\Component\HttpFoundation\Request;
+
 class SomeController
 {
-    public function someAction()
+    public function someAction(Request $request)
     {
-        return $this->getRequest()->getContent();
+        return $request->getContent();
     }
 }
PACKAGE:  symfony/framework-bundle >=2.5

AddViolationToBuildViolationRector

Change $context->addViolationAt to $context->buildViolation on Validator ExecutionContext

-$context->addViolationAt('property', 'The value {{ value }} is invalid.', array(
-    '{{ value }}' => $invalidValue,
-));
+$context->buildViolation('The value {{ value }} is invalid.')
+    ->atPath('property')
+    ->setParameter('{{ value }}', $invalidValue)
+    ->addViolation();
PACKAGE:  symfony/validator >=2.5

MaxLengthSymfonyFormOptionToAttrRector

Change form option "max_length" to a form "attr" > "max_length"

 $formBuilder = new Symfony\Component\Form\FormBuilder();

 $form = $formBuilder->create('name', 'text', [
-    'max_length' => 123,
+    'attr' => ['maxlength' => 123],
 ]);
SETS:  symfony/form
PACKAGE:  symfony/form >=2.5

SimpleFunctionAndFilterRector

Changes Twig_Function_Method to Twig_SimpleFunction calls in Twig_Extension.

 class SomeExtension extends Twig_Extension
 {
     public function getFunctions()
     {
         return [
-            'is_mobile' => new Twig_Function_Method($this, 'isMobile'),
+             new Twig_SimpleFunction('is_mobile', [$this, 'isMobile']),
         ];
     }

     public function getFilters()
     {
         return [
-            'is_mobile' => new Twig_Filter_Method($this, 'isMobile'),
+             new Twig_SimpleFilter('is_mobile', [$this, 'isMobile']),
         ];
     }
 }
SETS:  twig/twig 1
PACKAGE:  twig/twig >=1.34

DowngradeSymfonyCommandAttributeRector

Downgrade Symfony Command Attribute

 #[AsCommand(name: 'app:create-user', description: 'some description')]
 class CreateUserCommand extends Command
 {
+    protected function configure(): void
+    {
+        $this->setName('app:create-user');
+        $this->setDescription('some description');
+    }
 }

EnableValidationAttributesRector

Enable "framework.validation.enable_attributes" config, to load validation rules from attributes

 $container->loadFromExtension('framework', [
     'validation' => [
-        'enable_attributes' => false,
+        'enable_attributes' => true,
     ],
 ]);
SETS:  Configs

ServiceArgsToServiceNamedArgRector

Converts order-dependent arguments args() to named arg() call

 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

 return static function (ContainerConfigurator $containerConfigurator): void {
     $services = $containerConfigurator->services();

     $services->set(SomeClass::class)
-        ->args(['some_value']);
+        ->arg('$someCtorParameter', 'some_value');
 };
SETS:  Configs

MergeServiceNameTypeRector

Merge name === type service registration, $services->set(SomeType::class, SomeType::class)

 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

 return static function (ContainerConfigurator $containerConfigurator): void {
     $services = $containerConfigurator->services();
-    $services->set(\App\SomeClass::class, \App\SomeClass::class);
+    $services->set(\App\SomeClass::class);
 };
SETS:  Configs

RemoveConstructorAutowireServiceRector

Remove service that is passed as arg, but already autowired via constructor

 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

 return static function (ContainerConfigurator $containerConfigurator): void {
     $services = $containerConfigurator->services();

     $services->defaults()
         ->autowire();

-    $services->set(\App\SomeClass::class)
-        ->arg('$someService', ref(\App\SomeService::class));
+    $services->set(\App\SomeClass::class);
 };

 final class SomeClass
 {
     public function __construct(private SomeService $someService)
     {
     }
 }
SETS:  Configs

ServiceTagsToDefaultsAutoconfigureRector

Change $services->set(..., ...)->tag(...) to $services->defaults()->autodiscovery() where meaningful

 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
 use App\Command\SomeCommand;

 return static function (ContainerConfigurator $containerConfigurator): void {
     $services = $containerConfigurator->services();
+    $services->defaults()
+        ->autoconfigure();

-    $services->set(SomeCommand::class)
-        ->tag('console.command');
+    $services->set(SomeCommand::class);
 };
SETS:  Configs

FromServicePublicToDefaultsPublicRector

Instead of per service public() call, use it once in $services->defaults()->public()

 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

 return static function (ContainerConfigurator $containerConfigurator): void {
     $services = $containerConfigurator->services();

-    $services->set(SomeCommand::class)
-        ->public();
+    $services->defaults()->public();

-    $services->set(AnotherCommand::class)
-        ->public();
-
-    $services->set(NextCommand::class)
-        ->public();
+    $services->set(SomeCommand::class);
+    $services->set(AnotherCommand::class);
+    $services->set(NextCommand::class);
 };
SETS:  Configs

ServiceSetStringNameToClassNameRector

Change $service->set() string names to class-type-based names, to allow $container->get() by types in Symfony 2.8. Provide XML config via $rectorConfig->symfonyContainerXml(...);

 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

 return static function (ContainerConfigurator $containerConfigurator): void {
     $services = $containerConfigurator->services();

-    $services->set('some_name', App\SomeClass::class);
+    $services->set('app\\someclass', App\SomeClass::class);
 };
SETS:  Configs

ServiceSettersToSettersAutodiscoveryRector

Change $services->set(..., ...) to $services->load(..., ...) where meaningful

 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

-use App\Services\FistService;
-use App\Services\SecondService;
-
 return static function (ContainerConfigurator $containerConfigurator): void {
     $parameters = $containerConfigurator->parameters();

     $services = $containerConfigurator->services();

-    $services->set(FistService::class);
-    $services->set(SecondService::class);
+    $services->load('App\\Services\\', '../src/Services/*');
 };
SETS:  Configs

LiteralGetToRequestClassConstantRector

Replace "GET" string by Symfony Request object class constants

 use Symfony\Component\Form\FormBuilderInterface;

 final class SomeClass
 {
     public function detail(FormBuilderInterface $formBuilder)
     {
-        $formBuilder->setMethod('GET');
+        $formBuilder->setMethod(\Symfony\Component\HttpFoundation\Request::GET);
     }
 }
SETS:  Code Quality

StringCastDebugResponseRector

Cast responses in PHPUnit assert message to string, as required by PHPUnit

 use PHPUnit\Framework\TestCase;

 class SomeClass extends TestCase
 {
     public function run()
     {
         /** @var \Symfony\Component\HttpFoundation\Response $response */
         $response = $this->processResult();

-        $this->assertSame(200, $response->getStatusCode(), $response->getContent());
+        $this->assertSame(200, $response->getStatusCode(), (string) $response->getContent());
     }
 }
SETS:  Code Quality

AssertSameResponseCodeWithDebugContentsRector

Make assertSame(200, $response->getStatusCode()) in tests comparing response code to include response contents for faster feedback

 use PHPUnit\Framework\TestCase;

 class SomeClass extends TestCase
 {
     public function run()
     {
         /** @var \Symfony\Component\HttpFoundation\Response $response */
         $response = $this->processResult();

-        $this->assertSame(200, $response->getStatusCode());
+        $this->assertSame(200, $response->getStatusCode(), $response->getContent());
     }
 }
SETS:  Code Quality

ParameterBagTypedGetMethodCallRector

Make use of specific ParameterBag::get*() method with native return type declaration

 use Symfony\Component\HttpFoundation\Request;

 class SomeClass
 {
     public function run(Request $request)
     {
-        $debug = (bool) $request->query->get('debug', false);
+        $debug = $request->query->getBoolean('debug');
     }
 }
SETS:  Code Quality

AddTraitGetterReturnTypeBasedOnSetterRequiredRector

Add trait getter return type based on setter with @required annotation or #[\Symfony\Contracts\Service\Attribute\Required] attribute

 use stdClass;

 trait SomeTrait
 {
     private $service;

-    public function getService()
+    public function getService(): stdClass
     {
         return $this->service;
     }

     /**
      * @required
      */
     public function setService(stdClass $stdClass)
     {
         $this->stdClass = $stdClass;
     }
 }
SETS:  Code Quality

ResponseStatusCodeRector

Turns status code numbers to constants

 use Symfony\Component\HttpFoundation\Response;

 class SomeController
 {
     public function index()
     {
         $response = new Response();
-        $response->setStatusCode(200);
+        $response->setStatusCode(Response::HTTP_OK);

-        if ($response->getStatusCode() === 200) {
+        if ($response->getStatusCode() === Response::HTTP_OK) {
         }
     }
 }
SETS:  Code Quality

RequestIsMainRector

Turns status code numbers to constants

 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\HttpKernel;

 class SomeController
 {
     public function index(Request $request): bool
     {
-        return $request->getRequestType() === HttpKernel::MASTER_REQUEST;
+        return $request->isMasterRequestType();
     }
 }
SETS:  Code Quality

EventListenerToEventSubscriberRector

Change Symfony Event listener class to Event Subscriber based on configuration in service.yaml file

-class SomeListener
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class SomeEventSubscriber implements EventSubscriberInterface
 {
-     public function methodToBeCalled()
+     /**
+      * @return string[]
+      */
+     public static function getSubscribedEvents(): array
      {
+         return ['some_event' => 'methodToBeCalled'];
      }
-}

-// in config.yaml
-services:
-    SomeListener:
-        tags:
-            - { name: kernel.event_listener, event: 'some_event', method: 'methodToBeCalled' }
+     public function methodToBeCalled()
+     {
+     }
+}
SETS:  Code Quality

InlineClassRoutePrefixRector

Inline class route prefix to all method routes, to make single explicit source for route paths

 use Symfony\Component\Routing\Annotation\Route;

 /**
- * @Route("/api", name="api_")
+ * @Route(name="api_")
  */
 class SomeController
 {
     /**
-     * @Route("/action")
+     * @Route("/api/action")
      */
     public function action()
     {
     }
 }
SETS:  Code Quality

EventSubscriberMethodReturnVoidRector

Event subscriber methods hooked in getSubscribedEvents() must return void, as the event is passed by reference and returning it has no effect

 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Contracts\EventDispatcher\Event;

 final class SomeEventSubscriber implements EventSubscriberInterface
 {
     public static function getSubscribedEvents(): array
     {
         return ['some_event' => 'onEvent'];
     }

-    public function onEvent(Event $event): Event
+    public function onEvent(Event $event): void
     {
-        return $event->setSomething('value');
+        $event->setSomething('value');
     }
 }
SETS:  Code Quality

RemoveUnusedRequestParamRector

Remove unused $request parameter from controller action

 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;

 final class SomeController extends Controller
 {
-    public function run(Request $request, int $id)
+    public function run(int $id)
     {
         echo $id;
     }
 }
SETS:  Code Quality

ParamTypeFromRouteRequiredRegexRector

Complete strict param type declaration based on route annotation

 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use Symfony\Component\Routing\Annotation\Route;

 final class SomeController extends Controller
 {
     /**
      * @Route(
      *     requirements={"number"="\d+"},
      * )
      */
-    public function detailAction($number)
+    public function detailAction(int $number)
     {
     }
 }
SETS:  Code Quality

ResponseReturnTypeControllerActionRector

Add Response object return type to controller actions

 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Annotation\Route;

 final class SomeController extends AbstractController
 {
     #[Route]
-    public function detail()
+    public function detail(): Response
     {
         return $this->render('some_template');
     }
 }

ControllerGetByTypeToConstructorInjectionRector

From $container->get(SomeType::class) in controllers to constructor injection (step 1/x)

 use Symfony\Bundle\FrameworkBundle\Controller\Controller;

 final class SomeCommand extends Controller
 {
+    public function __construct(private SomeType $someType)
+    {
+    }
+
     public function someMethod()
     {
-        $someType = $this->get(SomeType::class);
+        $someType = $this->someType;
     }
 }

GetBySymfonyStringToConstructorInjectionRector

Converts typical Symfony services like $this->get("validator") in commands/controllers to constructor injection (step 3/x)

 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\Validator\Validator\ValidatorInterface;

 final class SomeController extends Controller
 {
+    public function __construct(private ValidatorInterface $validator)
+
     public function someMethod()
     {
-        $someType = $this->get('validator');
+        $someType = $this->validator;
     }
 }

CommandGetByTypeToConstructorInjectionRector

From $container->get(SomeType::class) in commands to constructor injection (step 2/x)

 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

 final class SomeCommand extends ContainerAwareCommand
 {
+    public function __construct(private SomeType $someType)
+    {
+    }
+
     public function someMethod()
     {
-        $someType = $this->get(SomeType::class);
+        $someType = $this->someType;
     }
 }