Find the best Rector rule to solve your problem
Change visibility of method from parent class.
class FrameworkClass
{
protected function someMethod()
{
}
}
class MyClass extends FrameworkClass
{
- public function someMethod()
+ protected function someMethod()
{
}
}
Change static call to new instance
class SomeClass
{
public function run()
{
- $dotenv = JsonResponse::create(['foo' => 'bar'], Response::HTTP_OK);
+ $dotenv = new JsonResponse(['foo' => 'bar'], Response::HTTP_OK);
}
}
Change new Object to static call
class SomeClass
{
public function run()
{
- new Cookie($name);
+ Cookie::create($name);
}
}
Wrap return value of specific method
final class SomeClass
{
public function getItem()
{
- return 1;
+ return [1];
}
}
This Rector adds new default arguments in calls of defined methods and class types.
$someObject = new SomeExampleClass;
-$someObject->someMethod();
+$someObject->someMethod(true);
class MyCustomClass extends SomeExampleClass
{
- public function someMethod()
+ public function someMethod($value = true)
{
}
}
Replaces defined map of arguments in defined methods and their calls.
$someObject = new SomeClass;
-$someObject->someMethod(SomeClass::OLD_CONSTANT);
+$someObject->someMethod(false);
Turns method names to new ones.
$someObject = new SomeExampleClass;
-$someObject->oldMethod();
+$someObject->newMethod();
Turns defined function call new one.
-view("...", []);
+Laravel\Templating\render("...", []);
Replaces defined class constants in their calls.
-$value = SomeClass::OLD_CONSTANT;
-$value = SomeClass::OTHER_OLD_CONSTANT;
+$value = SomeClass::NEW_CONSTANT;
+$value = DifferentClass::NEW_CONSTANT;
Replaces defined old properties by new ones.
-$someObject->someOldProperty;
+$someObject->someNewProperty;
Change string value
class SomeClass
{
public function run()
{
- return 'ROLE_PREVIOUS_ADMIN';
+ return 'IS_IMPERSONATOR';
}
}
Replaces defined classes by new ones.
namespace App;
-use SomeOldClass;
+use SomeNewClass;
-function someFunction(SomeOldClass $someOldClass): SomeOldClass
+function someFunction(SomeNewClass $someOldClass): SomeNewClass
{
- if ($someOldClass instanceof SomeOldClass) {
- return new SomeOldClass;
+ if ($someOldClass instanceof SomeNewClass) {
+ return new SomeNewClass;
}
}
Rename attribute class names
-#[SimpleRoute()]
+#[BasicRoute()]
class SomeClass
{
}
Change annotation to attribute
use Symfony\Component\Routing\Annotation\Route;
class SymfonyRoute
{
- /**
- * @Route("/path", name="action") api route
- */
+ #[Route(path: '/path', name: 'action')] // api route
public function action()
{
}
}
Removes defined arguments in defined methods and their calls.
$someObject = new SomeClass;
-$someObject->someMethod(true);
+$someObject->someMethod();
Add param types where needed
class SomeClass
{
- public function process($name)
+ public function process(string $name)
{
}
}
Changes defined return typehint of method and class.
class SomeClass
{
- public function getData()
+ public function getData(): array
{
}
}
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;
}
}
Turns old event name with EXCEPTION to ERROR constant in Console in Symfony
-"console.exception"
+Symfony\Component\Console\ConsoleEvents::ERROR
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);
}
}
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,
]);
}
}
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);
}
}
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()));
}
}
Change deprecated BinaryFileResponse::create() to use __construct() instead
use Symfony\Component\HttpFoundation;
class SomeClass
{
public function run()
{
- $binaryFile = BinaryFileResponse::create();
+ $binaryFile = new BinaryFileResponse(null);
}
}
Changes first argument of PropertyAccessor::__construct() to flags from boolean
class SomeClass
{
public function run()
{
- $propertyAccessor = new PropertyAccessor(true);
+ $propertyAccessor = new PropertyAccessor(PropertyAccessor::MAGIC_CALL | PropertyAccessor::MAGIC_GET | PropertyAccessor::MAGIC_SET);
}
}
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());
}
}
Symplify form rendering by not calling ->createView()
on render
function
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class ReplaceFormCreateViewFunctionCall extends AbstractController
{
public function form(): Response
{
return $this->render('form.html.twig', [
- 'form' => $form->createView(),
+ 'form' => $form,
]);
}
}
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('ROLE_ADMIN')]
public function index()
{
}
- #[Security("is_granted('ROLE_ADMIN') and is_granted('ROLE_FRIENDLY_USER')")]
+ #[IsGranted(new Expression("is_granted('ROLE_ADMIN') and is_granted('ROLE_FRIENDLY_USER')"))]
public function list()
{
}
}
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!
}
}
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',
- ];
}
}
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
) {
}
}
Replaces ArgumentValueResolverInterface by ValueResolverInterface
-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
{
}
}
Turns old Constraint::$errorNames properties to use Constraint::ERROR_NAMES instead
use Symfony\Component\Validator\Constraints\NotBlank;
class SomeClass
{
- NotBlank::$errorNames
+ NotBlank::ERROR_NAMES
}
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');
-
- }
}
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;
}
}
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';
}
Change $this->authorizationChecker->isGranted([$a, $b])
to $this->authorizationChecker->isGranted($a) || $this->authorizationChecker->isGranted($b)
, also updates AbstractController usages
-if ($this->authorizationChecker->isGranted(['ROLE_USER', 'ROLE_ADMIN'])) {
+if ($this->authorizationChecker->isGranted('ROLE_USER') || $this->authorizationChecker->isGranted('ROLE_ADMIN')) {
}
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;
}
}
Turns old option names to new ones in FormTypes in Form in Symfony
$builder = new FormBuilder;
-$builder->add("...", ["precision" => "...", "virtual" => "..."];
+$builder->add("...", ["scale" => "...", "inherit_data" => "..."];
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);
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,
]);
}
}
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);
}
}
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]]);
}
Rename getBlockPrefix()
if it returns the default value - class to underscore, e.g. UserFormType = user_form
use Symfony\Component\Form\AbstractType;
class TaskType extends AbstractType
{
- public function getBlockPrefix()
- {
- return 'task';
- }
}
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;
}
}
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)
{
- $this->getRequest()->...();
+ $request->...();
}
}
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,
) {
}
}
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;
}
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');
};
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);
};
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);
};
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);
};
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/*');
};
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);
}
}
Replace defined service() argument in Symfony PHP config
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
-return service(ContainerInterface::class);
+return service('service_container');
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'],
+ ];
}
}
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]],
+ ];
}
}
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')
+ }}
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;
}
}
Turns fetching of dependencies via $container->get()
in ContainerAware to constructor injection in Command and Controller in Symfony
final class SomeCommand extends ContainerAwareCommand
{
+ public function __construct(SomeService $someService)
+ {
+ $this->someService = $someService;
+ }
+
public function someMethod()
{
// ...
- $this->getContainer()->get('some_service');
- $this->container->get('some_service');
+ $this->someService;
+ $this->someService;
}
}
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();
Changes Process string argument to an array
use Symfony\Component\Process\Process;
-$process = new Process('ls -l');
+$process = new Process(['ls', '-l']);
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');
}
}
Simplify use of assertions in WebTestCase
use PHPUnit\Framework\TestCase;
class SomeClass extends TestCase
{
public function test()
{
- $this->assertSame(200, $this->client->getResponse()->getStatusCode());
+ $this->assertResponseIsSuccessful();
}
}
Simplify use of assertions in WebTestCase
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
final class SomeClass extends WebTestCase
{
public function test()
{
- $response = self::getClient()->getResponse();
-
- $this->assertSame(301, $response->getStatusCode());
- $this->assertSame('https://example.com', $response->headers->get('Location'));
+ $this->assertResponseStatusCodeSame(301);
+ $this->assertResponseRedirects('https://example.com');
}
}
Change Twig template short name to bundle syntax in render calls from controllers
class BaseController extends Controller {
function indexAction()
{
- $this->render('appBundle:Landing\Main:index.html.twig');
+ $this->render('@app/Landing/Main/index.html.twig');
}
}
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();
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']);
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();
}
}
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();
}
}
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 = "");
Adds $form->isSubmitted()
validation to all $form->isValid()
calls in Form in Symfony
-if ($form->isValid()) {
+if ($form->isSubmitted() && $form->isValid()) {
}
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);
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]);
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],
]);
}
}
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();
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],
]);
Change $container->get("some_name") 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);
}
}
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)
{
}
}
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()
{
}
}
Remove service from Sensio @Route
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
final class SomeClass
{
/**
- * @Route(service="some_service")
+ * @Route()
*/
public function run()
{
}
}
Changes setBody() method call on Swift_Message into a html() or plain() based on second argument
$message = new Swift_Message();
-$message->setBody('...', 'text/html');
+$message->html('...');
-$message->setBody('...', 'text/plain');
-$message->setBody('...');
+$message->text('...');
+$message->text('...');
Changes createMessage() into a new Symfony\Component\Mime\Email
-$email = $this->swift->createMessage('message');
+$email = new \Symfony\Component\Mime\Email();
Convert \Swift_Message into an \Symfony\Component\Mime\Email
-$message = (new \Swift_Message('Hello Email'))
- ->setFrom('send@example.com')
- ->setTo(['recipient@example.com' => 'Recipient'])
- ->setBody(
- $this->renderView(
- 'emails/registration.html.twig',
- ['name' => $name]
- ),
- 'text/html'
- )
+$message = (new Email())
+ ->from(new Address('send@example.com'))
+ ->to(new Address('recipient@example.com', 'Recipient'))
+ ->subject('Hello Email')
+ ->html($this->renderView(
+ 'emails/registration.html.twig',
+ ['name' => $name]
+ ))
+;
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);
}
}
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());
}
}
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) {
}
}
}
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
{
+ /**
+ * @return string[]
+ */
+ public static function getSubscribedEvents(): array
+ {
+ return ['some_event' => 'methodToBeCalled'];
+ }
+
public function methodToBeCalled()
{
}
-}
-
-// in config.yaml
-services:
- SomeListener:
- tags:
- - { name: kernel.event_listener, event: 'some_event', method: 'methodToBeCalled' }
+}
Move metadata from loadValidatorMetadata() to property/getter/method annotations
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.',
- ]));
- }
}
Removes Action suffixes from methods in Symfony Controllers
class SomeController
{
- public function indexAction()
+ public function index()
{
}
}
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;
}
}
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)
{
}
}
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');
}
}
Turns redirect to route to short helper method in Controller in Symfony
-$this->redirect($this->generateUrl("homepage"));
+$this->redirectToRoute("homepage");