Logo   espend.de
Symfony Support

Support for Symfony framework / components.

Links

GitHub

Issues & Source Code

JetBrains Marketplace

Buy a license

Legacy Documentation

Open Source Documentation

PhpStorm Documentation

PhpStorm Symfony Documentation Section

Features

Premium

Full Line Completion: Complete and inject service classes via property
IncompletePropertyServiceInjectionContributor
2024-04-07

Completion PHP Paid

Completes an unresolved controller or service property and inserts the matching constructor dependency so the property is backed by a real Symfony service.

This premium completion uses indexed autowireable services and keeps the generated property, constructor argument, and method-call completion together.

Before completion:

final class ProductController
{
    public function index(): Response
    {
        $products = $this->productRepository->findAll();
    }
}

After applying the suggestion:

final class ProductController
{
    public function __construct(
        private readonly ProductRepository $productRepository,
    ) {
    }

    public function index(): Response
    {
        $products = $this->productRepository->findAll();
    }
}
Full Line Completion: Doctrine QueryBuilder
IncompleteQueryBuilderJoinContributor
2024-04-14

Completion PHP Doctrine Paid

Completes Doctrine QueryBuilder joins and parameter bindings from the current query chain, including known aliases, relations, and unresolved DQL parameters.

The premium completion proposes whole method calls such as join(...) or setParameter(...) instead of only method names.

Join completion:

$qb = $this->createQueryBuilder(alias: 'bike');
$qb->join('bike.category', 'category');

Parameter completion:

$qb->andWhere('bike.id = :bikeId');
$qb->setParameter('bikeId', $bikeId);


Deprecated Doctrine Table attribute arguments
DoctrineTableAttributeDeprecatedPropertiesInspection
2026-05-04
Inspection PHP Doctrine Paid

Reports Doctrine ORM #[ORM\Table] attributes that still pass indexes or uniqueConstraints. Doctrine ORM deprecates these arguments because they no longer have an effect and will be removed in ORM 4.0.

Use standalone #[ORM\Index] and #[ORM\UniqueConstraint] attributes instead.

Deprecated Table arguments:

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(indexes: [
    new ORM\Index(name: 'idx_product_sku', columns: ['sku']),
])]
class Product
{
}

Use dedicated attributes:

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Index(name: 'idx_product_sku', columns: ['sku'])]
class Product
{
}
Bundle registerCommands() is deprecated
RegisterCommandsDeprecationInspection
2026-06-02
Inspection PHP Paid

Reports application bundles that override the deprecated Symfony Bundle::registerCommands() hook when the installed vendor method is marked deprecated since Symfony 8.1.

Use #[AsCommand] on command classes or the console.command service tag instead.

Deprecated bundle hook:

use Symfony\Component\Console\Application;
use Symfony\Component\HttpKernel\Bundle\Bundle;

final class AppBundle extends Bundle
{
    public function registerCommands(Application $application): void
    {
        $application->add(new ReindexProductsCommand());
    }
}

Attribute-based command registration:

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

#[AsCommand(name: 'app:reindex-products')]
final class ReindexProductsCommand extends Command
{
}
Doctrine join column nullable is ignored
DoctrineJoinColumnNullableDeprecationInspection
2026-06-03
Inspection PHP XML Yaml Doctrine Paid

Reports Doctrine ORM mapping metadata that explicitly sets nullable on join columns where Doctrine ORM 3.6 ignores the value and Doctrine ORM 4.0 rejects it.

The inspection covers many-to-many join columns and identifier to-one join columns in PHP attributes, XML mapping files, and YAML mapping files.

Deprecated PHP attribute metadata:

#[ORM\ManyToMany(targetEntity: Group::class)]
#[ORM\JoinTable(joinColumns: [
    new ORM\JoinColumn(name: 'user_id', nullable: true),
])]
private Collection $groups;

Remove the ignored nullable flag:

#[ORM\ManyToMany(targetEntity: Group::class)]
#[ORM\JoinTable(joinColumns: [
    new ORM\JoinColumn(name: 'user_id'),
])]
private Collection $groups;

XML mapping is covered too:

<join-column name="group_id" referenced-column-name="id" nullable="false" />
Doctrine mapping ArrayAccess is deprecated
DoctrineMappingArrayAccessDeprecationInspection
2026-06-02
Inspection PHP Doctrine Paid

Reports deprecated array access on Doctrine ORM mapping value objects that use Doctrine\ORM\Mapping\ArrayAccessImplementation.

The quick fix rewrites safe array reads to public property access when Doctrine's vendor deprecation is available in the project.

Deprecated mapping array access:

$metadata = $entityManager->getClassMetadata(Entity::class);
$fieldMapping = $metadata->getFieldMapping('fieldName');
$length = $fieldMapping['length'] ?? null;

Use property access:

$metadata = $entityManager->getClassMetadata(Entity::class);
$fieldMapping = $metadata->getFieldMapping('fieldName');
$length = $fieldMapping->length ?? null;
Doctrine current date/time string defaults are deprecated
DoctrineCurrentDateTimeDefaultExpressionInspection
2026-06-02
Inspection PHP XML Yaml Doctrine Paid

Reports Doctrine date, time, and timestamp field defaults that still use SQL strings such as CURRENT_TIMESTAMP.

Doctrine ORM 3.6 deprecates these string defaults for date/time fields; use DBAL DefaultExpression value objects instead. The inspection covers PHP attributes, XML, and YAML metadata when the matching vendor support is installed.

Deprecated string default:

#[ORM\Column(
    type: Types::DATETIME_IMMUTABLE,
    options: ['default' => 'CURRENT_TIMESTAMP'],
)]
private \DateTimeImmutable $createdAt;

Use a DBAL DefaultExpression:

use Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp;

#[ORM\Column(
    type: Types::DATETIME_IMMUTABLE,
    options: ['default' => new CurrentTimestamp()],
)]
private \DateTimeImmutable $createdAt;
Doctrine discriminator map duplicate classes
DoctrineDiscriminatorMapDuplicateClassInspection
2026-06-02
Inspection PHP XML Doctrine Paid

Reports discriminator maps where the same class is mapped to multiple discriminator values.

Doctrine ORM 3.4 deprecates duplicate class entries in a discriminator map, and Doctrine ORM 4.0 turns this into an error. The inspection covers PHP attributes, ClassMetadata::setDiscriminatorMap(), and XML mapping files.

Deprecated duplicate class mapping:

#[ORM\DiscriminatorMap([
    'user' => User::class,
    'legacy_user' => User::class,
])]
abstract class BaseUser
{
}

Keep one discriminator value per class:

#[ORM\DiscriminatorMap([
    'user' => User::class,
])]
abstract class BaseUser
{
}
Doctrine Criteria ordering API deprecations
DoctrineCollectionsCriteriaOrderingDeprecationInspection
2026-06-02
Inspection PHP Doctrine Paid

Reports deprecated Doctrine Collections Criteria APIs around ordering and null offsets.

The inspection detects Criteria::getOrderings(), string order directions passed to orderBy(), and explicit null first-result offsets.

Deprecated Criteria calls:

$criteria->getOrderings();
$criteria->orderBy(['name' => 'ASC']);
$criteria->setFirstResult(null);
new Criteria($expr, [], null);

Use the newer API:

use Doctrine\Common\Collections\Order;

$criteria->orderings();
$criteria->orderBy(['name' => Order::Ascending]);
$criteria->setFirstResult(0);
new Criteria($expr, [], 0);

Inspections

You probably dont want to inject a Controller here
AutowireControllerAsServiceInspection
2022-03-19
Inspection PHP Paid

Reports when a Symfony Controller is injected as a dependency into another service. Controllers are designed to be invoked by the framework via routing, not used as dependencies in other services.

This inspection helps identify incorrect service injection patterns that may lead to architectural issues.

Avoid:

public function __construct(private ProductController $controller) {}
2022-03-19
Inspection PHP Paid

Reports constructor parameters that reference classes which cannot be resolved to a valid service in the container. This typically occurs when:

  • Using a concrete class instead of an interface (e.g., EntityManager instead of EntityManagerInterface)
  • Referencing a class that is not registered as a service
  • Using a deprecated or non-existent class name

Instead of:

public function __construct(private EntityManager $em) {}

Use the interface:

public function __construct(private EntityManagerInterface $em) {}
2025-12-03
Inspection PHP

Reports invokable Symfony Commands using #[AsCommand] attribute whose __invoke() method lacks an int return type. Since Symfony 7.3, commands should declare int as return type for the exit code (e.g., Command::SUCCESS, Command::FAILURE).

Instead of:

#[AsCommand(name: 'app:my-command')]
class MyCommand extends Command
{
    public function __invoke()
    {
        return Command::SUCCESS;
    }
}

Use:

#[AsCommand(name: 'app:my-command')]
class MyCommand extends Command
{
    public function __invoke(): int
    {
        return Command::SUCCESS;
    }
}
Invokable command must return an integer value
CommandInvokableReturnValueInspection
2025-12-03
Inspection PHP

Reports invokable Symfony Commands using #[AsCommand] attribute whose __invoke() method returns non-integer values. Since Symfony 7.3, commands must return an integer exit code (e.g., Command::SUCCESS, Command::FAILURE).

Instead of:

#[AsCommand(name: 'app:my-command')]
class MyCommand extends Command
{
    public function __invoke(): int
    {
        return null; // or return 'success';
    }
}

Use:

#[AsCommand(name: 'app:my-command')]
class MyCommand extends Command
{
    public function __invoke(): int
    {
        return Command::SUCCESS;
        // or: Command::FAILURE
        // or: Command::INVALID
    }
}
2022-03-19
Inspection PHP Paid

Reports when RequestStack::getCurrentRequest() is called inside a service constructor. The current Request is not available during service construction, resulting in null.

Avoid:

public function __construct(private RequestStack $requestStack)
{
    $request = $requestStack->getCurrentRequest(); // Returns null!
}

Instead, inject RequestStack and use it in your methods:

public function someMethod()
{
    $request = $this->requestStack->getCurrentRequest();
}
Avoid heavy construction in non lazy Command
ConstructorCommandHeavyConstructorInspection
2022-05-31
Inspection PHP Paid

Reports Console Commands with heavy dependencies in their constructor. Commands with heavy services (like database connections) should be marked as lazy to improve container compilation performance.

See Symfony Documentation for more details.

// Add 'lazy: true' to make the command lazy-loaded:
#[AsCommand(name: 'app:my-command', lazy: true)]
class MyCommand extends Command
{
    public function __construct(private HeavyService $service)
    {
        parent::__construct();
    }
}
2022-03-19
Inspection PHP Paid

Reports when a Session is started or accessed inside a service constructor. The Session may not be available during service construction, similar to the Request.

Avoid:

public function __construct(private SessionInterface $session)
{
    $session->set('key', 'value'); // May not work!
}

Use session in your methods instead:

public function someMethod()
{
    $this->session->set('key', 'value');
}
2022-03-19
Inspection PHP Paid

Reports when the security token is fetched via TokenStorageInterface::getToken() inside a constructor. The security context is not yet initialized during service construction.

Avoid:

public function __construct(private TokenStorageInterface $tokenStorage)
{
    $token = $tokenStorage->getToken(); // Returns null!
    $user = $token->getUser(); // Error!
}
2022-03-19
Inspection PHP Paid

Reports when the current User is fetched from the TokenStorage in a constructor. The security context (including User) is not available during service construction.

Avoid:

public function __construct(private TokenStorageInterface $tokenStorage)
{
    $user = $tokenStorage->getToken()->getUser(); // Error!
}

Use the security helper or fetch user in your methods:

#[Autowire(service: 'security.helper')]
private SecurityHelper $security;

public function someMethod()
{
    $user = $this->security->getUser();
}
Avoid heavy construction in Twig extension
ConstructorTwigExtensionHeavyConstructorInspection
2022-03-24
Inspection PHP Paid

Reports Twig extensions with heavy constructor dependencies (like database connections). Twig extensions are instantiated early during container compilation, which can significantly slow down the application if they have complex dependencies.

Consider making your Twig extension lazy-loaded or refactoring to avoid heavy dependencies in the constructor.

See Symfony Documentation for more details.

Avoid:

class MyExtension extends AbstractExtension
{
    public function __construct(private ProductRepository $repository) {}
}

Instead, use a runtime loader for lazy loading:

class MyExtension extends AbstractExtension
{
    public function getFunctions(): array
    {
        return [
            new TwigFunction('product_count', [ProductRuntime::class, 'getCount']),
        ];
    }
}

class ProductRuntime
{
    public function __construct(private ProductRepository $repository) {}

    public function getCount(): int
    {
        return $this->repository->count([]);
    }
}
2025-12-01
Inspection PHP Validator

Reports deprecated usage of arrays as first argument in Symfony Constraint constructors. Symfony deprecated passing constraint options as arrays in favor of named arguments.

Instead of:

new Assert\Choice(['choices' => ['a', 'b']]);
new Assert\NotBlank(['message' => 'This value is required']);

Use:

new Assert\Choice(choices: ['a', 'b']);
new Assert\NotBlank(message: 'This value is required');
2022-03-19
Inspection PHP Paid

Reports usage of the deprecated kernel.root_dir parameter. Since Symfony 4.2, this parameter is deprecated in favor of kernel.project_dir.

Instead of:

$dir = $this->getParameter('kernel.root_dir');

Use:

$dir = $this->getParameter('kernel.project_dir');
2022-06-04
Inspection PHP Paid

Reports form type classes that do not properly implement Symfony's form type interface. Valid form types must extend AbstractType or implement FormTypeInterface.

// Make sure your form type extends AbstractType:
use Symfony\Component\Form\AbstractType;

class ProductType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('name', TextType::class);
    }
}
2022-06-01
Inspection PHP Paid

Reports when Doctrine QueryBuilder method chaining accidentally overwrites previous conditions. Calling where() after andWhere() or orWhere() will reset the WHERE clause.

Incorrect - second where() overwrites andWhere():

$qb->andWhere('x.status = :status')
   ->where('x.active = true'); // Overwrites previous condition!

Correct - use andWhere/orWhere consistently:

$qb->where('x.active = true')
   ->andWhere('x.status = :status');
2025-12-02
Inspection PHP Doctrine Paid

Reports deprecated usage of Doctrine QueryBuilder update() and delete() methods without providing the alias parameter. In Doctrine ORM 3.0, these methods require the alias parameter to be provided explicitly.

Instead of:

$qb->delete('User u')->where('u.id = :user_id');
$qb->update('User u')->set('u.status', ':status');

Use:

$qb->delete('User', 'u')->where('u.id = :user_id');
$qb->update('User', 'u')->set('u.status', ':status');
QueryBuilder array arguments deprecated (Doctrine DBAL 2.11+)
DoctrineQueryBuilderArrayDeprecationInspection
2025-12-09
Inspection PHP Doctrine Paid

Reports deprecated array usage in Doctrine DBAL QueryBuilder methods (select(), addSelect(), groupBy(), addGroupBy()). In Doctrine DBAL 2.11+, these methods no longer accept arrays and require individual arguments.

Instead of:

$qb->select(['u.id', 'p.id']);
$qb->addSelect(['u.name', 'p.name']);
$qb->groupBy(['u.category']);
$qb->addGroupBy(['u.status']);

Use:

$qb->select('u.id', 'p.id');
$qb->addSelect('u.name', 'p.name');
$qb->groupBy('u.category');
$qb->addGroupBy('u.status');
Use ON instead of WITH for arbitrary joins
DoctrineQueryBuilderJoinWithToOnInspection
2026-01-08
Inspection PHP Paid Doctrine

Reports deprecated WITH usage in Doctrine ORM QueryBuilder join methods and DQL for arbitrary joins. Since Doctrine ORM 3.x, WITH should only be used for association joins (defined relations), while ON should be used for arbitrary joins (joins with entity class and join condition). The inspection only triggers when the Doctrine ORM version has this deprecation.

QueryBuilder - Before (Deprecated):

$qb->join(Partner::class, 'p', Expr\Join::WITH, 'p.id = u.myId');
$qb->leftJoin('App\Entity\Geo', 'g', 'WITH', 'g.id = u.geoId');

QueryBuilder - After (Correct):

$qb->join(Partner::class, 'p', Expr\Join::ON, 'p.id = u.myId');
$qb->leftJoin('App\Entity\Geo', 'g', 'ON', 'g.id = u.geoId');

DQL - Before (Deprecated):

$em->createQuery('SELECT u FROM User u JOIN Banlist b WITH u.email = b.email');
$em->createQuery('SELECT u, p FROM User u JOIN ' . CmsPhonenumber::class . ' p WITH u = p.user');

DQL - After (Correct):

$em->createQuery('SELECT u FROM User u JOIN Banlist b ON u.email = b.email');
$em->createQuery('SELECT u, p FROM User u JOIN ' . CmsPhonenumber::class . ' p ON u = p.user');

Association joins (WITH is still valid):

// No warning - this is an association join (u.orders has a defined relation)
$qb->join('u.orders', 'o', 'WITH', 'o.status = :status');
QueryBuilder setParameters() array deprecated (Doctrine ORM 3.0)
DoctrineQueryBuilderSetParametersArrayDeprecationInspection
2025-12-02
Inspection PHP Doctrine Paid

Reports deprecated array usage in Doctrine QueryBuilder setParameters() method. In Doctrine ORM 3.0, setParameters() only accepts ArrayCollection of Parameter objects, not plain arrays.

Instead of:

$qb->setParameters([
    'user_id1' => 1,
    'user_id2' => 2
]);

Use:

$qb->setParameters(new ArrayCollection([
    new Parameter('user_id1', 1),
    new Parameter('user_id2', 2)
]));
Empty Table attribute on entities is useless
DoctrineEmptyTableAttributeInspection
2026-01-09
Inspection PHP Paid Doctrine

Reports empty #[ORM\Table] attributes on Doctrine entities. An empty Table attribute (with no arguments) provides no additional configuration beyond the default table name and can be safely removed. The inspection only reports when an Entity attribute is also present on the class.

Before:

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table]  class Product
{
    // ...
}

After:

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Product
{
    // ...
}

Table attribute is only useful when you need custom configuration:

#[ORM\Entity]
#[ORM\Table(name: 'products', schema: 'app')]
class Product
{
    // ...
}
2022-10-20
Inspection PHP Paid

In controller actions, suggests injecting Request directly instead of RequestStack and then calling getCurrentRequest(). This is cleaner and more straightforward.

Instead of:

public function index(RequestStack $requestStack): Response
{
    $request = $requestStack->getCurrentRequest();
    $id = $request->query->get('id');
}

Use:

public function index(Request $request): Response
{
    $id = $request->query->get('id');
}
2021-09-29
Inspection PHP Paid

Reports constructor parameters using deprecated classes or interfaces that should no longer be injected directly. Symfony deprecates certain injection patterns in favor of accessing these services through other means for better architecture.

Detected deprecated injections:

  • SessionInterface - deprecated since Symfony 5.3
  • FlashBagInterface - deprecated since Symfony 5.1

Example 1 - SessionInterface (deprecated since Symfony 5.3):

Instead of:

use Symfony\Component\HttpFoundation\Session\SessionInterface;

class MyService
{
    public function __construct(private SessionInterface $session)
    {
    }

    public function doSomething()
    {
        $this->session->set('key', 'value');
    }
}

Use:

use Symfony\Component\HttpFoundation\RequestStack;

class MyService
{
    public function __construct(private RequestStack $requestStack)
    {
    }

    public function doSomething()
    {
        $this->requestStack->getSession()->set('key', 'value');
    }
}

Example 2 - FlashBagInterface (deprecated since Symfony 5.1):

Instead of:

use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;

class MyService
{
    public function __construct(private FlashBagInterface $flashBag)
    {
    }

    public function doSomething()
    {
        $this->flashBag->add('notice', 'Success!');
    }
}

Use:

use Symfony\Component\HttpFoundation\RequestStack;

class MyService
{
    public function __construct(private RequestStack $requestStack)
    {
    }

    public function doSomething()
    {
        $this->requestStack->getSession()->getFlashBag()->add('notice', 'Success!');
    }
}
Probably missing 'throw' for exception
ControllerActionMissingExitInspection
2022-11-04
Inspection PHP Paid

Reports when an exception is instantiated but not thrown. This typically happens when you create an exception object but forget the throw keyword.

Wrong - exception created but not thrown:

new \Exception('Error');

Correct:

throw new \Exception('Error');
'redirectToRoute' shortcut can be used
UseControllerShortcutsInspection
2022-11-04
Inspection PHP Paid

Suggests using built-in AbstractController shortcut methods instead of directly accessing services. Shortcuts like render(), redirect(), json() provide cleaner, more concise code.

Instead of:

return new Response($this->twig->render('template.html.twig'));

Use:

return $this->render('template.html.twig');
2023-12-17
Inspection PHP Paid

Reports Commands using the deprecated $defaultName and $defaultDescription static properties. Since Symfony 6.1, use the #[AsCommand] attribute instead.

Instead of:

class MyCommand extends Command
{
    protected static $defaultName = 'app:my-command';
    protected static $defaultDescription = 'My command description';
}

Use:

#[AsCommand(
    name: 'app:my-command',
    description: 'My command description'
)]
class MyCommand extends Command
{
}
Doctrine lifecycle callback methods must be public
DoctrineLifecycleMethodVisibilityInspection
2026-01-06
Inspection PHP Doctrine Paid

Reports methods with Doctrine lifecycle callback attributes that are not public. Doctrine lifecycle callback methods (like #[PostLoad], #[PrePersist], etc.) must be public to work correctly.

Instead of:

#[PostLoad]
private function afterLoad(): void
{
    // ...
}

Use:

#[PostLoad]
public function afterLoad(): void
{
    // ...
}
Entity class must have #[HasLifecycleCallbacks] attribute
DoctrineLifecycleMissingCallbacksAttributeInspection
2026-01-06
Inspection PHP Doctrine Paid

Reports entity classes using Doctrine lifecycle callback attributes (like #[PostLoad], #[PrePersist], etc.) without the #[HasLifecycleCallbacks] attribute. Doctrine requires this attribute on the entity class to enable lifecycle callbacks.

Instead of:

class User
{
    #[PostLoad]
    public function afterLoad(): void
    {
        // ...
    }
}

Use:

#[HasLifecycleCallbacks]
class User
{
    #[PostLoad]
    public function afterLoad(): void
    {
        // ...
    }
}
2022-04-17
Inspection Twig Paid

Reports when a template that extends another template has content outside of {% block %} tags. Content outside blocks is ignored and not rendered.

Incorrect - content outside blocks is ignored:

{% extends 'base.html.twig' %}
<div>This content is ignored!</div>
{% block content %}{% endblock %}

Correct - all content inside blocks:

{% extends 'base.html.twig' %}
{% block content %}
<div>This content is rendered.</div>
{% endblock %}
2022-07-11
Inspection Twig Paid

Reports the deprecated if condition in for loops. Since Twig 2.10, use the filter tag instead.

Deprecated:

{% for item in items if item.active %}
    {{ item.name }}
{% endfor %}

Use filter instead:

{% for item in items|filter(item => item.active) %}
    {{ item.name }}
{% endfor %}
2020-01-03
Inspection Twig

Reports deprecated Twig extensions including tags, filters, and functions. The inspection detects usage of deprecated Twig features like {% spaceless %} tag and various deprecated filters/functions.

Deprecated:

{% spaceless %}{{ content }}{% endspaceless %}
{{ content }}
{{ value|deprecated_filter }}
{{ deprecated_function() }}

Use alternative Twig features instead.

Route exists for using 'path'
TwigPathReplacementInspection
2023-07-02
Inspection Twig Paid

Suggests using path() instead of url() for internal URLs. The path() function generates relative URLs, which is typically what you want for internal links. Use url() only when you need absolute URLs.

For internal links, use path():

<a href="{{ path('product_show', {id: product.id}) }}">View Product</a>

Use url() only when you need absolute URLs (e.g., for emails):

<a href="{{ url('product_show', {id: product.id}) }}">View Product</a>


2016-03-02
Inspection Twig

Reports deprecated methods, properties, fields, and classes used through Twig variables. When Twig accesses PHP members through property syntax or method calls, this inspection detects deprecations on the resolved PHP target.

Example:

{{ user.getDeprecatedMethod() }}
{{ user.deprecatedProperty }}
{{ deprecated_service.someMethod() }}

The inspection will warn when calling deprecated methods like:

Method 'User::getDeprecatedMethod' is deprecated
Field 'User::$deprecatedProperty' is deprecated
Method 'DeprecatedService::someMethod' is deprecated
2026-02-27
Inspection Twig UX

Reports when Twig block syntax {% block name %} is used inside HTML component syntax <twig:Component>. Inside component contexts, you should use the HTML-compatible <twig:block> tag instead.

Invalid - Twig block syntax inside HTML component:

<twig:Card>
    {% block footer %}
        Footer content
    {% endblock %}  <!-- ERROR: Cannot use Twig block syntax inside HTML component -->
</twig:Card>

Valid - Use twig:block HTML syntax:

<twig:Card>
    <twig:block name="footer">
        Footer content
    </twig:block>
</twig:Card>
2026-02-27
Inspection Twig UX

Reports when {% from _self import ... %} is used inside a Symfony UX Twig Component. Inside a component context, _self does not refer to the current template, so macro imports via _self will silently fail at runtime.

Invalid - _self does not work inside components:

<twig:Alert>
    {% from _self import message_formatter %}  <!-- ERROR: _self doesn't work here -->

    {{ message_formatter(message) }}
</twig:Alert>

{% macro message_formatter(message) %}
    {{ message }}
{% endmacro %}

Valid - Use the full template path:

<twig:Alert>
    {% from 'components/alert.html.twig' import message_formatter %}

    {{ message_formatter(message) }}
</twig:Alert>
Twig Enum Function Validation
TwigEnumFunctionInspection
2026-01-01
Inspection Twig

Validates class references in Twig enum() and enum_cases() functions. The inspection checks that the provided class names exist in the project and are actually PHP enum types, not regular classes.

Detects:

  • Missing class: The specified class cannot be found in the project
  • Not an enum: The class exists but is not an enum type

Valid usage:

{# Valid: enum class exists #}
{{ enum('App\\Enum\\Status') }}

{# Valid: returns all cases of the enum #}
{% for status in enum_cases('App\\Enum\\Status') %}
    {{ status.value }}
{% endfor %}

Error - class doesn't exist:

{# Error: class doesn't exist #}
{{ enum('App\\Enum\\MissingEnum') }}

Warning - class exists but is not an enum:

{# Warning: class exists but is not an enum #}
{{ enum('App\\Entity\\User') }}

Various contexts supported:

{{ enum('App\\Enum\\Status') }}
{{ enum_cases('App\\Enum\\Status') }}
{% if enum('App\\Enum\\Status') == 'value' %}{% endif %}
{% set options = enum_cases('App\\Enum\\Status') %}
OneToMany mapping requires the 'mappedBy' attribute
DoctrineOneToManyMappedByRequiredInspection
2024-03-21
Inspection PHP Paid

Reports OneToMany relationships without the required mappedBy attribute. In Doctrine, the OneToMany side is always the inverse side and must specify which field on the target entity owns the relationship via ManyToOne.

class Category
{
    #[ORM\OneToMany(targetEntity: Product::class, mappedBy: 'category')]
    private array $products = [];
}

class Product
{
    #[ORM\ManyToOne(targetEntity: Category::class, inversedBy: 'products')]
    #[ORM\JoinColumn(name: 'category_id')]
    private ?Category $category = null;
}
JoinColumn not allowed on inverse side of one-to-one associations
DoctrineOneToOneOwingSideDeprecationInspection
2023-12-23
Inspection PHP Doctrine Paid

Reports #[JoinColumn] configuration on the inverse side of one-to-one associations. In Doctrine ORM 3.0+, JoinColumn is only allowed on the owning side of bidirectional one-to-one associations (the side without mappedBy).

Instead of:

#[OneToOne(mappedBy: 'customer')]
#[JoinColumn]  // Error: JoinColumn not allowed here
private ?Customer $customer = null;

Use:

#[OneToOne(mappedBy: 'customer')]
private ?Customer $customer = null;

JoinColumn should be on the owning side:

#[OneToOne(inversedBy: 'customer')]
#[JoinColumn]
private ?Address $address = null;
2024-04-04
Inspection PHP Paid

Suggests using PHP 8.1+ first-class callable syntax instead of callable array notation. First-class callables provide better type safety and are more concise.

Instead of:

array_map([$this, 'processItem'], $items);

Use first-class callable syntax:

array_map($this->processItem(...), $items);

Works with static methods too:

array_map([MyClass::class, 'method'], $items);
// becomes:
array_map(MyClass::method(...), $items);
2023-12-17
Inspection PHP Attribute Paid

Reports usage of the deprecated Symfony\Component\Routing\Annotation\Route namespace. Since Symfony 6.3, Route attributes should use the Attribute namespace instead of Annotation.

Instead of:

use Symfony\Component\Routing\Annotation\Route;

#[Route('/product', name: 'app_product')]
public function index(): Response {}

Use:

use Symfony\Component\Routing\Attribute\Route;

#[Route('/product', name: 'app_product')]
public function index(): Response {}
2024-04-18
Inspection PHP Paid

Reports calls to EntityManager::clear() with arguments. Since Doctrine ORM 2.11, calling clear() with entity class names is deprecated and will be removed in Doctrine ORM 3.0.

Instead of:

$entityManager->clear(Foo::class); // Deprecated!

Use:

$entityManager->clear(); // Clears all entities

Or manage entity state manually:

$entityManager->detach($entity);
Missing Service
MissingServiceInspection
2017-08-30
Inspection PHP Attribute

Reports when #[Autowire] attributes reference services that don't exist in the container. This helps catch typos or references to services that haven't been registered yet.

#[Autowire(service: 'app.product_repository')] // Service exists
private ProductRepository $productRepository;

#[Autowire(service: 'non_existent_service')] // Error: service not found
private ?SomeService $someService;
Named argument does not exists
ServiceNamedArgumentExistsInspection
2022-06-17
Inspection Yaml

Reports YAML service configurations that reference non-existent container parameters via named arguments (using $parameterName syntax).

# config/services.yaml
parameters:
    app.admin_email: 'admin@example.com'

services:
    App\Service\NotificationService:
        arguments:
            $adminEmail: '%app.admin_email%' # Correct
            $unknownParam: '%app.unknown%' # Error: parameter doesn't exist
2026-03-31
Inspection PHP Service

Reports PHP service configuration arguments whose resolved service class does not match the expected constructor parameter type.

The inspection works for array-style definitions, fluent ->args([...]) calls, service(), ref(), raw @service_id strings, and class constant service IDs.

When a better matching service is available, the inspection offers a replacement suggestion directly from the PHP service file.

PHP service configuration with a wrong service type:

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

return [
    App\Service\Mailer::class => [
        'arguments' => [
            service('logger'),
        ],
    ],
];

Fluent configuration is checked as well:

$services->set(App\Service\Mailer::class)
    ->args([
        service('logger'),
    ]);

Suggested replacement:

// Constructor expects App\Contract\MailTransportInterface
// Inspection can suggest app.mail_transport instead of logger.
Controller action is deprecated
RouteControllerDeprecatedInspection
2026-05-26
Inspection PHP Twig Yaml XML Routing

Reports routes and route usages that point to controller actions marked as deprecated. This helps identify outdated routes that should be removed or updated.

The inspection covers YAML/XML route definitions, PHP route references, and Twig path()/url() calls.

// Controller with deprecated action:
class ProductController extends AbstractController
{
    #[Route('/old-product', name: 'app_old_product')]
    #[Deprecated('Use app_product_show instead')]
    public function oldAction(): Response
    {
        // ...
    }
}

Twig route usage:

{{ url('app_old_product') }}
{{ path('app_old_product') }}

Intentions

2025-12-03
Intention PHP Attribute

Adds a #[Route] attribute to a public method in a Symfony controller class. The route path and name are automatically generated based on the controller and method name.

Before:

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class ProductController extends AbstractController
{
    public function index(): Response
    {
        return $this->render('product/index.html.twig');
    }
}

After:

namespace App\Controller;

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

class ProductController extends AbstractController
{
    #[Route('/product', name: 'app_product_index')]
    public function index(): Response
    {
        return $this->render('product/index.html.twig');
    }
}
2025-11-29
Intention PHP Command

Converts traditional Symfony Command with execute() method to invokable command style using __invoke() with Argument and Option attributes.

This intention automatically:

  • Removes extends Command and parent::__construct() calls
  • Migrates configure() arguments/options to method parameters with attributes
  • Replaces $input->getArgument() and $input->getOption() with direct variable access
  • Removes redundant type casts and self-assignments

Before:

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class CreateUserCommand extends Command
{
    public function __construct()
    {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addArgument('username', InputArgument::REQUIRED, 'The username')
            ->addOption('admin', null, InputOption::VALUE_NONE, 'Make user admin');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $username = $input->getArgument('username');
        $isAdmin = $input->getOption('admin');

        $output->writeln("Creating user: $username");

        if ($isAdmin) {
            $output->writeln('User will be admin');
        }

        return Command::SUCCESS;
    }
}

After:

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\Attribute\Argument;
use Symfony\Component\Console\Input\Attribute\Option;
use Symfony\Component\Console\Output\OutputInterface;

class CreateUserCommand
{
    public function __construct()
    {
    }

    public function __invoke(
        OutputInterface $output,
        #[Argument(description: 'The username')]
        string $username,
        #[Option(description: 'Make user admin')]
        bool $admin = false
    ): int {
        $output->writeln("Creating user: $username");

        if ($admin) {
            $output->writeln('User will be admin');
        }

        return 0;
    }
}
2025-12-03
Intention PHP Command

Adds a supported parameter to invokable Symfony Command __invoke method. The intention is only available when the class does not extend Command and has an __invoke() method.

Before:

<?php

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'app:example')]
class ExampleCommand
{
    public function __invoke(): int
    {
        return 0;
    }
}

After:

<?php

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(name: 'app:example')]
class ExampleCommand
{
    public function __invoke(SymfonyStyle $io): int
    {
        return 0;
    }
}
2015-02-21
Intention Yaml XML PHP

Generates a complete Symfony service definition from a PHP class by analyzing the constructor parameters. Opens an interactive dialog that allows customization of service ID, output format, and options.

Supported output formats include YAML, XML, PHP array config, and PHP fluent configurator code.

Perfect for quickly creating service definitions for existing PHP classes in Symfony applications.

Before:

# PHP class constructor not in sync with services.yaml
# class OrderProcessor
# {
#     public function __construct(
#         private LoggerInterface $logger,
#         private OrderRepository $orderRepository,
#         private EmailService $emailService,
#     ) {
#     }
# }

services:
    App\Service\OrderProcessor:
        arguments:
            - '@logger'

After:

# Generated service definition (YAML format)
# After using the dialog and clicking "Insert" or "Copy"

services:
    App\Service\OrderProcessor:
        arguments:
            - '@logger'
            - '@App\Repository\OrderRepository'
            - '@App\Service\EmailService'
2017-10-19
Intention Yaml XML

Automatically updates service definition arguments in YAML or XML configuration files to match the constructor parameters of the PHP class. When you modify a service class constructor by adding, removing, or reordering parameters, this intention synchronizes the service definition to match the new constructor signature.

Create and register CompilerPass
PhpBundleCompilerPassIntention
2015-05-01
Intention PHP

Creates a new CompilerPass file in the DependencyInjection/Compiler directory and automatically registers it in the bundle's build() method.

Before:

namespace App;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class AppBundle extends Bundle
{
}

After:

namespace App;

use App\DependencyInjection\Compiler\CustomCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class AppBundle extends Bundle
{
    public function build(ContainerBuilder $container): void
    {
        parent::build($container);

        $container->addCompilerPass(new CustomCompilerPass());
    }
}
Add parameter to route action method
RouteActionParameterIntention
2025-12-04
Intention PHP

Adds a parameter (e.g., Request) to a Symfony route action method. Available when the cursor is inside a public method that has a Route attribute or annotation, or inside an __invoke method where the class has a Route attribute or annotation.

Before:

<?php
use Symfony\Component\Routing\Attribute\Route;

class MyController
{
    #[Route('/hello')]
    public function index(): Response
    {
    }
}

After:

<?php
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;

class MyController
{
    #[Route('/hello')]
    public function index(Request $request): Response
    {
    }
}
Migrate Twig Extension to PHP attributes
TwigExtensionToAttributeIntention
2025-12-10
Intention PHP Twig Attribute

Migrates Twig Extension from getFilters(), getFunctions(), and getTests() methods to PHP attributes.

Before:

<?php

namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;
use Twig\TwigTest;
use Twig\Environment;

class MyExtension extends AbstractExtension
{
    public function getFilters()
    {
        return [
            new TwigFilter('filter_name', [$this, 'filterMethod'], ['needs_environment' => true]),
        ];
    }

    public function getFunctions()
    {
        return [
            new TwigFunction('function_name', [$this, 'functionMethod'], [
                'needs_environment' => true,
                'needs_context' => true,
                'is_safe' => ['html']
            ]),
        ];
    }

    public function getTests()
    {
        return [
            new TwigTest('test_name', [$this, 'testMethod']),
        ];
    }

    public function filterMethod(Environment $env, $value)
    {
        return $value;
    }

    public function functionMethod(Environment $env, $context, $value)
    {
        return $value;
    }

    public function testMethod($value)
    {
        return $value;
    }
}

After:

<?php

namespace App\Twig;

use Twig\Attribute\AsTwigFilter;
use Twig\Attribute\AsTwigFunction;
use Twig\Attribute\AsTwigTest;
use Twig\Environment;

class MyExtension
{
    #[AsTwigFilter('filter_name', needsEnvironment: true)]
    public function filterMethod(Environment $env, $value)
    {
        return $value;
    }

    #[AsTwigFunction('function_name', needsEnvironment: true, needsContext: true, isSafe: ['html'])]
    public function functionMethod(Environment $env, $context, $value)
    {
        return $value;
    }

    #[AsTwigTest('test_name')]
    public function testMethod($value)
    {
        return $value;
    }
}
Add missing service tags (YAML)
YamlServiceTagIntention
2015-04-24
Intention Yaml

Automatically adds missing service tags to a YAML service definition based on the PHP class's interfaces and attributes. This intention analyzes your PHP class and suggests appropriate tags, opening a popup if multiple tags are detected.

Before:

# config/services.yaml
#
# PHP class implements EventSubscriberInterface:
# class OrderEventSubscriber implements EventSubscriberInterface
# {
#     public static function getSubscribedEvents(): array
#     {
#         return [OrderPlacedEvent::class => 'onOrderPlaced'];
#     }
# }
#
# But the service definition is missing the kernel.event_subscriber tag:

services:
    App\EventSubscriber\OrderEventSubscriber:
        arguments:
            - '@logger'

After:

# config/services.yaml
#
# After applying the intention, the kernel.event_subscriber tag is added:

services:
    App\EventSubscriber\OrderEventSubscriber:
        arguments:
            - '@logger'
        tags:
            - kernel.event_subscriber
Add missing service tags (XML)
XmlServiceTagIntention
2015-04-23
Intention XML

Automatically adds missing <tag> elements to an XML service definition based on the PHP class's interfaces and attributes. This intention analyzes your PHP class and suggests appropriate tags, opening a popup if multiple tags are detected.

Before:

<!-- config/services.xml -->
<!--
PHP class implements EventSubscriberInterface:
class OrderEventSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [OrderPlacedEvent::class => 'onOrderPlaced'];
    }
}

But the service definition is missing the kernel.event_subscriber tag:
-->

<services>
    <service id="App\EventSubscriber\OrderEventSubscriber" class="App\EventSubscriber\OrderEventSubscriber">
        <argument type="service" id="logger"/>
    </service>
</services>

After:

<!-- config/services.xml -->
<!--
After applying the intention, the kernel.event_subscriber tag is added:
-->

<services>
    <service id="App\EventSubscriber\OrderEventSubscriber" class="App\EventSubscriber\OrderEventSubscriber">
        <argument type="service" id="logger"/>
        <tag name="kernel.event_subscriber"/>
    </service>
</services>
2015-04-12
Intention XML

Suggests appropriate service IDs for <argument> elements based on the constructor parameter types. Available when your cursor is on an <argument> element.

Before:

<!-- config/services.xml -->
<!--
PHP class constructor:
public function __construct(
    private LoggerInterface $logger,
    private OrderRepository $orderRepository,
    private EmailService $emailService,
) {}

But XML service definition has only one argument:
-->

<services>
    <service id="App\Service\OrderProcessor" class="App\Service\OrderProcessor">
        <argument type="service" id="logger"/>
    </service>
</services>

After:

<!-- config/services.xml -->
<!--
After applying the intention, all constructor arguments are present:
-->

<services>
    <service id="App\Service\OrderProcessor" class="App\Service\OrderProcessor">
        <argument type="service" id="logger"/>
        <argument type="service" id="App\Repository\OrderRepository"/>
        <argument type="service" id="App\Service\EmailService"/>
    </service>
</services>
Suggest service ID for XML argument
XmlServiceSuggestIntention
2016-03-06
Intention XML

Suggests appropriate service IDs for an <argument> element based on the constructor parameter type. Available when your cursor is on an <argument> element.

Before:

<!-- config/services.xml -->
<services>
    <service id="App\Service\OrderProcessor" class="App\Service\OrderProcessor">
        <argument type="service" id="logger"/>
        <argument/>
        <!-- Empty argument - need to fill in service ID -->
    </service>
</services>

After:

<!-- config/services.xml -->
<services>
    <service id="App\Service\OrderProcessor" class="App\Service\OrderProcessor">
        <argument type="service" id="logger"/>
        <argument type="service" id="App\Repository\OrderRepository"/>
        <!-- Service ID filled in from suggestion popup -->
    </service>
</services>
Convert Doctrine entity string to class constant
DoctrineRepositoryClassConstantIntention
2015-12-13
Intention PHP Doctrine

Converts deprecated shortcut notation like 'AppBundle:Product' or 'App:Product' to Product::class. This modernization provides better refactoring support and is the recommended approach since Doctrine 2.5 and Symfony 4.

Before:

namespace App\Controller;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class ProductController extends AbstractController
{
    public function __construct(
        private EntityManagerInterface $entityManager
    ) {
    }

    public function show(int $id)
    {
        $repository = $this->entityManager->getRepository('App:Product');
        $product = $this->entityManager->find('App:Product', $id);

        return $this->render('product/show.html.twig', [
            'product' => $product
        ]);
    }
}

After:

namespace App\Controller;

use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class ProductController extends AbstractController
{
    public function __construct(
        private EntityManagerInterface $entityManager
    ) {
    }

    public function show(int $id)
    {
        $repository = $this->entityManager->getRepository(Product::class);
        $product = $this->entityManager->find(Product::class, $id);

        return $this->render('product/show.html.twig', [
            'product' => $product
        ]);
    }
}
Convert Form type string alias to class constant
FormStringToClassConstantIntention
2015-12-12
Intention PHP Form

Converts legacy form type aliases like 'text' to TextType::class.

Before:

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class ProductType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name', 'text')
            ->add('description', 'textarea')
            ->add('price', 'number')
            ->add('category', 'entity', [
                'class' => 'App\Entity\Category',
            ])
            ->add('submit', 'submit');
    }
}

After:

namespace App\Form;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

class ProductType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name', TextType::class)
            ->add('description', TextareaType::class)
            ->add('price', NumberType::class)
            ->add('category', EntityType::class, [
                'class' => 'App\Entity\Category',
            ])
            ->add('submit', SubmitType::class);
    }
}
2022-04-21
Intention PHP

Automatically injects a missing service property through the constructor when you reference $this->serviceProperty that doesn't exist in the class.

Before:

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class ProductController extends AbstractController
{
    public function index(): Response
    {
        $products = $this->productRepository->findAll();

        return $this->render('product/index.html.twig', [
            'products' => $products
        ]);
    }
}

After:

namespace App\Controller;

use App\Repository\ProductRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class ProductController extends AbstractController
{
    public function __construct(
        private ProductRepository $productRepository,
    ) {
    }

    public function index(): Response
    {
        $products = $this->productRepository->findAll();

        return $this->render('product/index.html.twig', [
            'products' => $products
        ]);
    }
}
Create missing translation key
TwigTranslationKeyIntention
2017-03-06
Intention Twig Translation

Creates a missing translation key in the appropriate translation file when using trans or transchoice filters in Twig templates.

Before:

<h1>product.title</h1>
<p>product.description</p>
<button>product.add_to_cart</button>

After:

# translations/messages.fr.yaml
# After using the intention and entering the French translation:

product:
    title: 'Produit'
    description: 'Description du produit'
    add_to_cart: 'Ajouter au panier'

Completion

Form type class constant completion for builder

Completion PHP

Doctrine entity class constant completion

Completion PHP

Constraint message translation completion
ConstraintMessageGotoCompletionRegistrar
2026-04-25

Completion PHP Attribute Navigation

Completes and navigates validation translation keys used in Symfony Constraint messages.

In addition to named message: arguments, the completion now supports array-style 'message' keys in PHP constraint configuration.

Attribute message argument:

#[Assert\NotBlank(message: 'product.name.not_blank')]
private string $name;

Array message key:

new Assert\NotBlank([
    'message' => 'product.name.not_blank',
]);
Tag completion inside Attributes

Completion PHP Attribute



Service completion inside Autowire Attribute

Completion PHP Attribute

Parameter completion inside Autowire Attribute

Completion PHP Attribute

Service completion inside Autowire AsDecorator

Completion PHP Attribute

Doctrine QueryBuilder: Field completion

Completion PHP Doctrine



Prioritized extends templates

Completion Twig

Incomplete Yaml named argument

Completion Yaml



PHP service config argument completion
PhpServiceConfigCompletion
2026-04-01

Completion PHP Service Navigation

Completes service references for PHP array-style and fluent service definitions by looking at the configured service class constructor and setter signatures.

Navigation and completion also cover ServicesConfigurator::alias() targets in PHP service configuration files.

Array-style service arguments:

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

return [
    App\Service\Mailer::class => [
        'arguments' => [
            service('mailer.transport'),
        ],
    ],
];

Fluent service config and alias target:

$services->set('app.mailer', App\Service\Mailer::class)
    ->args([service('mailer.transport')]);

$services->alias('App\Contracts\MailerInterface', 'app.mailer');
!tagged_iterator tag name

Completion Yaml

Prioritized include templates

Completion Twig



Prioritized embed templates

Completion Twig

Incomplete Completion for extends tags

Completion Twig

Incomplete Completion for include tags

Completion Twig



Incomplete Completion for embed tags

Completion Twig

HTML attribute completion with "function print block"

Completion Twig

Environment variable completion for env() expressions
EnvironmentVariableContributor
2026-03-31

Completion PHP Yaml XML Navigation

Completes environment variable names inside Symfony env() expressions and navigates to the matching .env declaration.

The contributor reuses indexed dotenv variables so PHP, YAML, and XML service configuration can reference the same variables consistently.

PHP service config:

return [
    'parameters' => [
        'dsn' => env('DATABASE_URL'),
    ],
];

YAML service config:

parameters:
  dsn: '%env(DATABASE_URL)%'
Form translation key completion
FormTranslationCompletion
2015-12-01

Completion PHP Navigation

Completes and navigates translation domains and translation keys inside PHP form builders.

Supported form options include translation_domain, choice_translation_domain, label, help, help_block, help_inline, placeholder, and translated choice labels.

Form option translations:

<?php
$builder->add('status', ChoiceType::class, [
    'translation_domain' => 'admin',
    'label' => 'product.status',
    'help' => 'product.status.help',
    'choices' => [
        'product.status.draft' => 'draft',
        'product.status.published' => 'published',
    ],
]);

Domain completion:

<?php
$builder->add('category', ChoiceType::class, [
    'choice_translation_domain' => 'admin',
]);
Include and embed context key completion
TwigIncludeEmbedContextKeyCompletion
2026-05-10

Completion Twig Navigation

Completes top-level variable names inside Twig include and embed context hashes from the target template.

The same context key can navigate back to the variable usage in the included template, so forwarded values stay connected to the template that expects them.

Included template variables:

{# product/_card.html.twig #}
{{ product.name }}
{{ currentView }}

Context key completion:

{% include 'product/_card.html.twig' with {
    product: product,
    currentView: 'grid'
} only %}

{% embed 'product/_card.html.twig' with { product: product } %}
    {% block body %}{{ product.name }}{% endblock %}
{% endembed %}
Controller render parameter key completion
ControllerRenderParameterKeyCompletion
2019-08-21

Completion Twig PHP Navigation

Completes keys in controller render parameter arrays from the variables used by the rendered Twig template.

Completion is limited to root-level template variables and also works for templates whose visible variables come from include or embed context handling.

Rendered template variables:

{# product/show.html.twig #}
{{ product.name }}
{{ breadcrumbs.items|length }}

{% include 'product/_teaser.html.twig' with { teaser: teaser } %}

Controller parameter keys:

return $this->render('product/show.html.twig', [
    'product' => $product,
    'breadcrumbs' => $breadcrumbs,
    'teaser' => $teaser,
]);

Merged context arrays:

$context = ['product' => $product];

return $this->render('product/show.html.twig', array_merge(
    $context,
    ['breadcrumbs' => $breadcrumbs],
));
Twig method-chain type resolution
TwigMethodChainTypeResolution
2026-05-18

Completion Twig Navigation

Improves Twig completion, navigation, and inspections across chained method calls, property shortcuts, function return types, and filter return types.

This enables suggestions on expressions like entry.children.entries, method-call chains, and values returned by Twig functions or filters.

For-loop path resolution:

{# @var root \App\Dto\CategoryTree #}
{% for entry in root.children.entries %}
    {{ entry.name }}
{% endfor %}

Function/filter return type chains:

{{ product_for_sku(sku).manufacturer.name }}
{{ order|latest_invoice.number }}
Complete Twig constant() references
TwigConstantEnumResolver
2026-05-28

Completion Twig Navigation Find Usages

Completes and resolves PHP constants in Twig constant() calls, including fully qualified class constants, namespaced global constants, and object-relative constants.

The same resolver is used by navigation and Find Usages, so constant references in Twig stay connected to their PHP declarations.

Class and namespaced constants:

{{ constant('App\\Enum\\Status::ACTIVE') }}
{{ constant('BugDemo\\NAMESPACED_CONST') }}

Object-relative constants:

{# @var suite \BugDemo\CardSuite #}
{{ constant('CLUBS', suite) }}

Types

Twig @var type resolving
TwigVarTypeResolving
2014-10-26

Type Twig Annotation Completion Navigation

Resolves Twig type comments into PHP types so template variables can use class-aware completion, navigation, inspections, and member lookup.

Supported formats include variable-first declarations, class-first declarations, array types, multi-line comments, and union types.

Variable-first and class-first declarations:

{# @var user \App\Entity\User #}
{# @var \App\Entity\Product product #}
{# @var items \App\Entity\Item[] #}

Multi-line declarations:

{#
    @var foo \App\Foo
    @var bar \App\Bar
#}

Union types:

{# @var item \App\Entity\User|\App\Entity\Admin #}
{{ item.email }}
{{ item.displayName }}
Controller render variables for Twig types
TwigControllerRenderVariableTypes
2019-08-21

Type Twig PHP Completion Navigation

Collects variables passed from Symfony controllers and render-like calls so Twig templates get typed root variables for completion, navigation, and inspections.

Supported calls include render(), renderView(), stream(), renderBlock(), renderBlockView(), and Template attribute or annotation return arrays.

Supported parameter sources include inline arrays, local array variables, returned arrays, spread array entries, array_merge(), array_merge_recursive(), array_replace(), array_push(), array union, and array self-assignment.

Controller render context:

final class ProductController
{
    public function show(Product $product): Response
    {
        return $this->render('product/show.html.twig', [
            'product' => $product,
            ...$this->sidebarContext(),
        ]);
    }
}

Render-like methods:

$this->render('product/show.html.twig', ['product' => $product]);
$this->renderView('product/show.html.twig', ['product' => $product]);
$this->stream('product/show.html.twig', ['product' => $product]);
$this->renderBlock('product/show.html.twig', 'content', ['product' => $product]);
$this->renderBlockView('product/show.html.twig', 'content', ['product' => $product]);

Parameter source formats:

$context = ['product' => $product];
$context += ['reviews' => $reviews];

return $this->render('product/show.html.twig', array_merge(
    $context,
    ['sidebar' => $sidebar],
    $this->extraTemplateData(),
));

Template attribute return arrays:

#[Template('product/show.html.twig')]
public function show(Product $product): array
{
    return ['product' => $product];
}

Resolved Twig variables:

{{ product.name }}
{{ sidebar.items|length }}
Twig include and embed context type resolution
TwigIncludeContextParser
2026-05-10

Type Twig Navigation

Resolves Twig template variables from include and embed context hashes so included templates receive the correct root variables for completion, navigation, and inspections.

Context handling supports explicit keys, inherited parent variables, only isolation, with_context: false, and array or ternary template targets.

Include and embed context keys:

{% include 'product/_card.html.twig' with {
    product: product,
    currentView: 'grid'
} only %}

{% embed 'product/_panel.html.twig' with { product: product } %}
    {% block body %}{{ product.name }}{% endblock %}
{% endembed %}
Twig loop context type resolution
TwigLoopContextTypeResolution
2026-05-18

Type Twig

Resolves loop variables and the surrounding loop scope through included templates, so repeated row templates keep type-aware completion and inspections.

This also preserves parent context inheritance when a template is included from inside a for block.

Loop context inheritance:

{% for product in category.products %}
    {% include 'product/_row.html.twig' with { product: product } %}
{% endfor %}

{# product/_row.html.twig #}
{{ loop.index }} {{ product.name }}
Twig @var annotation highlighting
TwigVarCommentAnnotator
2026-02-25

Type Twig Annotation

Highlights Twig @var doc comment annotations so the keyword, variable name, class names, array suffixes, and union type separators are easier to read inside templates.

The highlighting supports variable-first declarations, class-first declarations, array types, multi-line comments, and union types.

Variable-first and class-first declarations:

{# @var user \App\Entity\User #}
{# @var \App\Entity\Product product #}
{# @var items \App\Entity\Item[] #}

{# Multiple declarations:
   @var foo \App\Foo
   @var bar \App\Bar
#}

Union type declarations:

{# @var item \App\Entity\User|\App\Entity\Admin #}
{# @var \App\Dto\SearchResult[] results #}
!tagged_iterator tag name

Navigation Yaml

Tag navigation in Attributes

Navigation PHP Attribute

Doctrine QueryBuilder: Field navigation

Navigation PHP Doctrine

Config navigation and resource line markers
PhpConfigGotoDeclarationHandler
2026-03-31

Navigation PHP Yaml Linemarker

Navigates from root keys in PHP Symfony configuration files to their bundle configuration class, including conditional when@env sections.

PHP and YAML resource entries get line markers for imported files, directories, and globbed service resources, so generated resource-based services still navigate back to the matching config entry.

Root config key navigation:

return [
    'framework' => [
        'mailer' => null,
    ],
    'when@prod' => [
        'twig' => [
            'strict_variables' => false,
        ],
    ],
];

Imported PHP resource line marker:

return [
    'imports' => [
        ['resource' => 'packages/security.php'],
    ],
];

YAML service resource glob:

services:
    _defaults:
        autowire: true

    App\Service\:
        resource: '../src/Service/*'
        exclude:
            - '../src/Service/Internal/*'

PHP service resource glob:

return [
    'services' => [
        'App\\' => [
            'resource' => '../src/',
            'exclude' => ['../src/Entity/', '../src/Kernel.php'],
        ],
    ],
];
PHP RoutingConfigurator route support
PhpRouteReferenceContributorRoutingConfigurator
2026-04-16

Navigation PHP Routing

Indexes routes declared with Symfony's PHP RoutingConfigurator API and enables completion/navigation for route names, controller targets, methods, defaults, prefixes, and name prefixes.

Routes declared in config/routes.php are available to route completion, route inspections, controller related navigation, and Search Everywhere route lookup.

PHP route configuration:

use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

return static function (RoutingConfigurator $routes): void {
    $routes->add('app_product_show', '/product/{id}')
        ->controller('App\Controller\ProductController::show')
        ->methods(['GET']);
};
Navigation for typed and named default service bindings
YamlDefaultServiceBindingNavigation
2026-05-28

Navigation Yaml Service

Navigates from YAML _defaults.bind entries to the matching PHP type, parameter, or class target.

This covers both typed bindings and named argument bindings, so default wiring rules remain traceable in larger service files.

Typed and named bindings:

services:
  _defaults:
    bind:
      Psr\Log\LoggerInterface: '@monolog.logger'
      string $projectDir: '%kernel.project_dir%'

Linemarker

Annotation routing loading

Linemarker Yaml XML



Autowired resources classes

Linemarker Yaml XML



Linked class to "data_class" configuration

Linemarker PHP

Generator

Prioritized extends generator
Generator Twig
Block Overwrite
Generator Twig

UX

Symfony type icons for PHP classes
PhpClassFileIconProvider
2026-06-08

Other PHP UX Doctrine Form Console

Decorates PHP class files with Symfony-specific icons so controllers, entities, repositories, form types, and console commands are easier to distinguish in the project tree.

The icon decoration is configurable in the Symfony plugin settings and uses the same Symfony metadata that powers navigation and inspections.

Decorated PHP class types:

#[AsCommand(name: 'app:reindex-products')]
final class ReindexProductsCommand extends Command
{
}

#[ORM\Entity(repositoryClass: ProductRepository::class)]
final class Product
{
}

final class ProductType extends AbstractType
{
}

#[Route('/products')]
final class ProductController extends AbstractController
{
}
Component Template Navigation

Linemarker PHP Twig

Component Usage Navigation
TwigLineMarkerProvider
2026-02-27

Linemarker Twig

Navigate from a UX component template to all its usages. Supports all Twig component syntaxes with target resolution.

Function syntax:

{{ component('Alert', { type: 'success' }) }}

Tag syntax:

{% component 'Alert' type='success' %}
    Content here
{% endcomponent %}

HTML syntax:

<twig:Alert type="success">
    Content here
</twig:Alert>
AsTwigTemplate Template

Completion PHP Twig

Variable Expose

Other Completion Navigation Twig









Component HTML Syntax

Other Navigation Completion Twig





Component Function

Navigation Twig



Incomplete Component Completion

Completion Navigation Twig

Stimulus Controller Completion
StimulusControllerCompletionRegistrar
2026-01-17

Completion UX HTML Twig

Auto-completes Stimulus controller names in HTML data-controller attributes and Twig stimulus_controller() function calls. The completion shows all registered Stimulus controllers from the project, including those from Symfony UX packages.

In HTML, normalized names are provided (e.g., symfony--ux-chartjs--chart). In Twig, both normalized names and original module names (e.g., @symfony/ux-chartjs/chart) are supported. Navigation from controller name to the source JavaScript file is also available.

HTML - data-controller attribute:

<div data-controller="symfony--ux-chartjs--chart">
    <canvas data-symfony--ux-chartjs--chart-target="canvas"></canvas>
</div>

Twig - stimulus_controller() function:

{{ stimulus_controller('symfony--ux-chartjs--chart', {
    'data': chartData
}) }}
Twig {% types %} Tag Class Completion
TwigTypesTagCompletion
2026-03-01

Completion Twig Navigation

Provides class completion for the {% types %} Twig tag, which is used to declare variable types in templates. The completion suggests PHP class names including namespace support.

Supports the optional marker syntax (?:) for nullable types and array notation ([]) for collections. Navigate to class definitions via Ctrl+Click or Cmd+Click.

Basic type declaration:

{% types {
    user: '\App\Entity\User',
    product: '\App\Entity\Product'
} %}

Optional types and arrays:

{% types {
    user?: '\App\Entity\User|null',
    items: '\App\Entity\Item[]',
    orders?: '\App\Entity\Order[]'
} %}

Completion in action:

{% types { user: 'App\Ent' } %}
{# Completion suggests: Entity, Entity\User, Entity\Product #}
Twig Route Parameter Completion
TwigPathParameterCompletion
2013-10-27

Completion Twig Routing Navigation

Provides autocompletion for route parameters in Twig path() and url() functions. The plugin reads route definitions and suggests available parameters for each route.

Supports multiple hash key syntaxes: quoted keys {{'slug': value}}, unquoted keys {{slug: value}}, and shorthand syntax {{slug}}. Navigate to route definitions via Ctrl+Click or Cmd+Click.

Quoted hash key syntax:

{{ path('product_show', {{''}}) }}
{{ path('product_show', {{'slug': product.slug}}) }}

Unquoted hash key syntax:

{{ path('product_show', {}) }}
{{ path('product_show', {slug: product.slug}) }}

Shorthand syntax:

{{ path('product_show', {slug}) }}

Navigation support:

{{ path('product_show', {slug}) }}
{# Ctrl+Click navigates to route definition #}
Twig Component <twig:block> Tag Completion
TwigComponentBlockCompletion
2026-03-01

Completion Twig UX Component

Provides completion for <twig:block> tags inside Symfony UX Twig components. When editing a component usage at the root level, the plugin suggests block names defined in the component template and automatically inserts the full block tag structure.

Block tag completion:

<twig:Alert>
    <caret>  {# Suggests: <twig:block name="message">, <twig:block name="actions"> #}
</twig:Alert>
Twig Component Block Name Completion
TwigComponentBlockNameCompletion
2026-03-01

Completion Twig UX Component

Provides completion for block names inside the name="" attribute of <twig:block> tags. The plugin suggests block names defined in the component template.

Block name completion:

<twig:Alert>
    <twig:block name="<caret>">  {# Suggests: message, actions #}
    </twig:block>
</twig:Alert>
Twig {{ enum_cases() }} Function Completion
EnumCasesTwigFunction
2026-01-01

Completion Twig Navigation

Provides autocompletion for PHP enum classes in the Twig enum_cases() function. The plugin suggests enum class names with namespace support and filters results to show only enum classes.

Supports namespace completion with backslash separators. Navigate to enum class definitions via Ctrl+Click or Cmd+Click.

Basic enum completion:

{{ enum_cases('') }}
{{ enum_cases('App\\Enum\\Status') }}

Namespace completion:

{{ enum_cases('App\\') }}
{{ enum_cases('App\\Enum\\Status') }}

Using in control structures:

{% for status in enum_cases('App\\Enum\\Status') %}
    
{% endfor %}

Navigation support:

{{ enum_cases('App\\Enum\\Status') }}
{# Ctrl+Click navigates to enum class definition #}

Search Everywhere

Route pattern match search

Other Navigation

MCP Tools

2026-01-11
MCP PHP

Lists all Symfony console commands available in the project. This MCP tool provides access to configured console commands with their class names, file paths, options, and arguments.

The tool accepts an Ant-style fileGlob on command class paths for scoped command inventories.

name,className,filePath,options,arguments
cache:clear,\App\Command\CacheClearCommand,src/Command/CacheClearCommand.php,,
app:sync,\App\Command\SyncCommand,src/Command/SyncCommand.php,"[{name: --dry-run}]","[{name: target}]"
Doctrine Entity Fields MCP Tool
DoctrineEntityFieldsMcpToolset
2026-01-11
MCP Doctrine PHP

Lists all fields of a Doctrine entity as CSV. This MCP tool provides detailed field information for a specific entity class including field names, column names, types, and relations.

The tool returns CSV format with columns: name, column, type, relation, relationType, enumType, propertyType.

name,column,type,relation,relationType,enumType,propertyType
id,id,integer,,,,int
username,username,string,,,string
status,status,string,,,\App\Enum\Status,\App\Enum\Status
orders,orders,,App\Entity\Order,OneToMany,,
Doctrine Entities MCP Tool
DoctrineEntityMcpToolset
2026-01-11
MCP Doctrine PHP

Lists all Doctrine ORM entities in the project as CSV. This MCP tool provides access to all configured Doctrine entities with their class names and file paths.

The tool returns CSV format with columns: className, filePath.

className,filePath
App\Entity\User,src/Entity/User.php
App\Entity\Product,src/Entity/Product.php
App\Entity\Order,src/Entity/Order.php
2026-01-11
MCP Form PHP

Lists all Symfony form types configured in the project. This MCP tool provides access to form type aliases, class names, and their file locations.

The tool returns CSV format with columns: name, className, filePath.

name,className,filePath
user,App\Form\UserType,src/Form/UserType.php
email,Symfony\Component\Form\Extension\Core\Type\EmailType,vendor/symfony/form/Extension/Core/Type/EmailType.php
Symfony Form Type Options MCP Tool
FormTypeOptionsMcpToolset
2026-01-14
MCP Form PHP

Lists all available options for a specific Symfony form type. This MCP tool provides detailed information about option names, their types (DEFAULT, REQUIRED, DEFINED), and the source classes that define them.

The tool accepts a form type name or FQN and returns CSV format with columns: name, type, source.

name,type,source
label,DEFAULT,Symfony\Component\Form\Extension\Core\Type\FormType
required,DEFAULT,Symfony\Component\Form\Extension\Core\Type\FormType
data,DEFAULT,Symfony\Component\Form\Extension\Core\Type\FormType
Symfony Profiler Requests MCP Tool
ProfilerRequestsMcpToolset
2026-01-14
MCP Profiler PHP

Lists the last 10 Symfony profiler requests with detailed information about HTTP requests, controllers, routes, templates, and form types used. This MCP tool provides optional filtering by URL, hash, controller, and route name.

The tool returns CSV format with columns: hash, method, url, statusCode, profilerUrl, controller, route, template, formTypes.

hash,method,url,statusCode,profilerUrl,controller,route,template,formTypes
18e6b8,GET,http://127.0.0.1:8000/user/1,200,_profiler/18e6b8,App\Controller\UserController::show,user_show,user/show.html.twig,
Symfony MCP exposed tools integration
SymfonyMcpToolsetIntegration
2026-04-02
MCP PHP

Registers Symfony MCP tools through JetBrains' MCP server toolset API, so Symfony tools are managed from the IDE's exposed tools UI instead of a plugin-specific tool registry.

Route, command, template usage, and template variable tools also support Ant-style fileGlob filters for scoped project analysis.

Scoped MCP requests:

list_symfony_routes_url_controllers
fileGlob: src/Controller/Admin/**/*.php

list_symfony_commands
fileGlob: src/Command/**/*.php

list_twig_template_variables
fileGlob: templates/admin/**/*.html.twig
2026-04-02
MCP Routing PHP

Lists Symfony routes with URL mappings, controller mappings, file paths, line numbers, and rendered Twig templates.

The unified route tool supports filtering by route name, controller, URL path, or Ant-style controller fileGlob, so AI assistants can move from request URLs to controllers, source locations, and templates without a second lookup.

name,controller,path,filePath,lineNumber,templates
app_home,App\Controller\HomeController::index,/,src/Controller/HomeController.php,12,home/index.html.twig
api_users_list,App\Controller\UserController::list,/api/users,src/Controller/UserController.php,28,user/list.html.twig;user/_pagination.html.twig
2026-04-02
MCP Service PHP Generator

Generates Symfony service definitions for one or more PHP classes. This MCP tool analyzes constructors and setter methods to identify dependencies and creates explicit service arguments.

The tool supports YAML, XML, PHP array, and PHP fluent output, with per-argument suggestions and service-ID strategy options.

YAML example:

App\Service\EmailService:
    arguments: ['@mailer', '@logger']

XML example:

<service id="App\Service\EmailService">
    <argument type="service" id="mailer"/>
</service>

PHP fluent example:

$services->set(App\Service\EmailService::class)
    ->args([
        service('mailer'),
        service('logger'),
    ]);
2026-04-08
MCP Service PHP

Locates where a Symfony service is defined in configuration files by service name or class name. This MCP tool provides access to service definitions with their file paths and line numbers.

The service-locator output now uses structured text as well, so agents can read locator mappings without guessing from raw dumps.

The tool returns CSV format with columns: serviceName, className, filePath, lineNumber.

serviceName,className,filePath,lineNumber
app.service.my_service,\App\Service\MyService,config/services.yaml,15
app.my_service_alias,\App\Service\MyService,config/services.yaml,25

serviceLocator,serviceName,className,filePath,lineNumber
App\Controller\ProductController::getSubscribedServices,product.repository,\App\Repository\ProductRepository,config/services.yaml,42
Twig Extensions MCP Tool
TwigExtensionMcpToolset
2026-01-11
MCP Twig PHP

Lists available Twig template extensions for code generation and template assistance. This MCP tool provides unified access to all Twig extensions including filters, functions, tests, and tags.

The tool returns CSV format with columns: extension_type, name, className, methodName, parameters.

extension_type,name,className,methodName,parameters
filter,upper,\Twig\Extension\CoreExtension,upper,"value,encoding"
function,path,\Twig\Extension\AssetExtension,path,"url,name"
filter,date,\Twig\Extension\CoreExtension,date,"date,format"
2026-02-28
MCP Twig UX PHP

Lists Symfony UX Twig components and their composition metadata. This MCP tool provides access to all Twig components with their templates, syntax variants, props, and blocks.

Supports partial component name search (case-insensitive).

component_name,template_relative_path,component_tag,twig_component_syntax,component_print_block_syntax,twig_tag_composition_syntax,props,template_blocks
Alert,templates/components/Alert.html.twig,,{{ component('Alert') }},{{ block('footer') }},{% component 'Alert' %}...{% endcomponent %},message;type,content;footer
Admin:Card,templates/components/Admin/Card.html.twig,,{{ component('Admin:Card') }},,{% component 'Admin:Card' %}...{% endcomponent %},title,body
Twig Template Usages MCP Tool
TwigTemplateUsageMcpToolset
2026-02-28
MCP Twig Routing PHP

Lists usages of Twig templates across the project. This MCP tool finds all locations where a template is used, including controllers, includes, extends, embeds, and more.

Accepts a partial template name, a project-relative file path (e.g. "templates/home/index.html.twig" resolves to "home/index.html.twig"), or an Ant-style fileGlob for scoped template usage scans.

Includes Symfony route information: For templates rendered by controllers, the output includes the associated route name and path.

template,controller,twig_include,twig_embed,twig_extends,twig_import,twig_use,twig_form_theme,twig_component,route_name,route_path
partials/nav.html.twig,App\Controller\BaseController::index,templates/layouts/base.html.twig,,,,,,,app_base_index,/
layouts/base.html.twig,,,,,templates/pages/home.html.twig;templates/pages/about.html.twig,,,,
Twig Template Variables MCP Tool
TwigTemplateVariablesMcpToolset
2026-04-12
MCP Twig PHP

Lists all variables available in one or more Twig templates with their PHP types and first-level accessible properties. Accepts template names, project-relative file paths, or Ant-style fileGlob filters.

Variables are collected from controller render calls, include/embed contexts, Twig {% types %} tags, and @var annotations.

variable,type,properties
user,\App\Entity\User,"id,email,name,roles,createdAt"
app,\Symfony\Bridge\Twig\AppVariable,"user,request,session,environment,debug,token,flashes"
products,\App\Entity\Product[],"id,title,price,category,isActive"

Other

IntelliJ Endpoints Tool Window Integration
SymfonyEndpointProvider
2026-03-02

Other Routing Intellij-ultimate

Integrates Symfony routes with IntelliJ Ultimate's Endpoints tool window. Routes are displayed with HTTP methods, paths, and controller information.

Find Usages for Symfony routes
RouteFindUsagesHandler
2026-04-09

Other Routing PHP Twig Find Usages

Runs IntelliJ's Find Usages on route declarations and returns PHP and Twig route references in one result view.

Twig route usages are indexed from path(), url(), route comparisons, and other route-aware Twig contexts, while PHP usages are filtered to real route references.

Route declaration:

#[Route('/product/{id}', name: 'app_product_show')]
public function show(Product $product): Response
{
}

Twig and PHP usages:

<a href="{{ path('app_product_show', {id: product.id}) }}">
    {{ product.name }}
</a>
$url = $urlGenerator->generate('app_product_show', [
    'id' => $product->getId(),
]);
Find Usages for PHP symbols from Twig
TwigFindUsagesHandlerFactory
2026-04-15

Other Twig PHP Find Usages

Runs Find Usages from Twig variables, properties, methods, functions, filters, constants, enum cases, and @var type declarations, then delegates to the resolved PHP target.

Usages are grouped as Twig usages so a PHP method or field search also shows property-style Twig shortcuts such as product.name and method calls such as product.getName().

PHP member usages in Twig:

{# @var product \App\Entity\Product #}
{{ product.name }}
{{ product.getName() }}

Twig extension and constant usages:

{{ product_number(product) }}
{{ product.sku|product_label }}
{{ constant('App\\Enum\\Status::ACTIVE') }}
Find Usages for Twig Templates
TwigTemplateReferencesSearchExecutor
2026-03-03

Other Twig Navigation Find Usages

Use IntelliJ's Find Usages (Alt+F7) on any Twig template to see all references grouped by semantic type: extends, include, embed, import, from, form_theme, controller, and component.

extends:

{% extends 'base.html.twig' %}

include:

{% include 'partials/nav.html.twig' %}
{{ include('partials/nav.html.twig') }}
{{ source('partials/nav.html.twig') }}

embed:

{% embed 'layout.html.twig' %}
    {% block content %}Override{% endblock %}
{% endembed %}

import / from:

{% import 'macros.html.twig' as macros %}
{% from 'macros.html.twig' import input as text_input %}

form_theme:

{% form_theme form with 'form/div_layout.html.twig' %}

controller:

return $this->render('home/index.html.twig');
return $this->renderView('home/index.html.twig');

component:

{{ component('Alert', { type: 'success' }) }}
{% component Alert type='success' %}{% endcomponent %}
<twig:Alert type="success"></twig:Alert>
Twig block() function template resolution
TwigBlockFunctionTemplateResolution
2026-04-01

Navigation Twig

Resolves template names passed to Twig's block() function and includes them in template navigation, move/rename handling, and template usage classification.

Template argument in block():

{{ block('teaser', 'partials/_teaser.html.twig') }}
PHP attribute implicit usage detection
SymfonyImplicitUsageProvider
2026-04-12

Other PHP

Marks Symfony, Doctrine, and MCP attribute-driven classes and callback methods as used so IDE unused-declaration inspections do not flag framework entry points.

Covered attributes include commands, event listeners, message handlers, schedules, Twig components, Doctrine listeners, Doctrine lifecycle callbacks, validator callbacks, workflow listeners, autoconfigure tags, and MCP capabilities.

Attribute-driven entry points:

<?php

#[AsCommand(name: 'app:sync')]
final class SyncCommand extends Command
{
    public function __invoke(): int {}
}

#[AsEventListener(event: KernelEvents::EXCEPTION, method: 'onKernelException')]
final class ExceptionListener
{
    public function onKernelException(): void {}
}

#[ORM\PrePersist]
public function updateTimestamps(): void {}
AssetMapper: importmap function

Completion Navigation Twig

Controller shortcut: renderBlock

Other Completion Navigation PHP

Related template target

Other Twig

Related method targets

Other PHP

Symfony Console Command Completion in Terminal
CommandNameTerminalCompletionContributor
2025-12-11

Other Terminal Completion

Provides intelligent code completion for Symfony console commands directly in the integrated terminal. When typing bin/console or console commands, the plugin automatically suggests available commands, and for command options after the command name.

Supports completion for:

  • Command names: bin/console cac<Tab> → suggests cache:clear, cache:pool:clear, etc.
  • Command options: bin/console app:greet Fabien -<Tab> → suggests available options like --help, --quiet, -v, etc.
  • Option shortcuts and long forms are both supported

bin/console NAME