IntelliJ IDEA 2023.1 Help

Creating Helper Functions

The Symfony Plugin provides parameter types and return types inference based on their usage with Symfony classes and functions. This lets you create your own helper functions that take or return a template, a service, an entity, a translation, a route, a form, or an event.

Install the required plugins

This functionality relies on the PHP, Symfony Support, and PHP Annotations plugins that should be installed and enabled in your IDE.

The plugins are available only in IntelliJ IDEA Ultimate.

  1. Press Control+Alt+S to open the IDE settings and select Plugins.

  2. Switch to the Marketplace tab and use the search field to find the plugins.

  3. Click Install next to each plugin and restart the IDE if prompted.

As an example, let's create a redirectToRoute function that can be used in controllers. This function will combine the Controller class' redirect and generateUrl function, so that you can easily redirect users to a known route within our application. The code will look as follows:

protected function redirectToRoute($route) { return $this->redirect($this->generateUrl($route)); }

When we call this function, we will get code completion Control+Space for the $route and , as well as the ability to navigate to the corresponding declaration Control+B.

Symfony route name completion in a helper function

Code completion and navigation for the returned $response instance are available, too.

Symfony response name completion in a helper function

The reason both of these work is that the Symfony Plugin infers the $route's type by analyzing calls and return types for known functions. This type analysis works for most Symfony components (template, service, entity, translation, route, form, or event), but there are cases where it will not work as-is.

Whenever completion and navigation for helper functions that we create ourselves or utilize from a third-party library do not seem to work, the Symfony Plugin comes with a solution: it provides access to some of its internals through the Method Parameter and Signature Types project settings.

Method Parameter

Consider the following function, which doesn't use any Symfony-specific functions:

/** * Translate route * * @param $route string Route to translate the URL for * @param $locale string Locale to translate into */ protected function translateRoute($route, $locale) { // ... }

The Symfony Plugin in this case will not be able to figure out that the $route string parameter should hold a route name and provide completion and navigation for it. We can fix this by using any of the following techniques:

Method references

To tell the Symfony Plugin about our method, in the Settings dialog (Control+Alt+S), navigate to Languages & Frameworks | PHP | Symfony | Method References. Then, click the Add button to add a new method parameter registration.

Symfony MethodParameterSetting dialog

Provide the following:

  • CallTo: The FQN of the class (with leading \) that contains the function.

  • Method: The function name.

  • Index: The index of the parameter that we want to have completion and navigation for.

  • Provider: The provider of potential data. This is where we choose the Symfony component we want to accept for our function parameter.

  • Contributor: (optional) If our function parameter is an array, and we want completion in the array key or value, we can specify that using these options.

  • ContributorData: (optional) In case we want array value completion, here we can enter the key for which to provide completion and navigation.

Once we apply changes, full completion and navigation support for our helper function's parameters will be available. Since this is a project-level setting, you can share it with your team.

Symfony method parameter completion in a helper function

While this technique is powerful, using hints with hashes is probably easier to work with in most situations and does not require sharing your project settings with team members.

Hashes

Instead of configuring method parameters in the settings, we can use hinting, similarly to the way we provide IntelliJ IDEA with type hints using PHPDoc.

By adding any of the following in the function's PHPDoc block, we can specify the type of data that a given parameter will take:

  • #Entity

  • #Service

  • #FormType

  • #Template

  • #Route

  • #Class

  • #TranslationKey

  • #TranslationDomain

  • #FormOption

  • #Interface

The example function with the added hints will look like as follows. Note the #Route in the description for the $route parameter.

/** * Translate route * * @param $route string #Route to translate the URL for * @param $locale string Locale to translate into */ protected function translateRoute($route, $locale) { // ... }

The Symfony Plugin will now index the function correctly and provide completion and navigation for the $route parameter.

Symfony hash parameter completion in a helper function

Signature Types

Consider a test class, in which we will be writing a test in the testIndex function. The class comes with a helper function that can mock a service registered with our Symfony web application.

class SomeTest extends PHPUnit_Framework_TestCase { /** * @param $service string #Service to mock * @return PHPUnit_Framework_MockObject_MockObject */ protected function getMockService($service) { // ... resolve interface from $service ... $serviceInterface = ''; return $this->getMock($serviceInterface); } function testIndex() { // TODO: our code will go here... } }

Since we've added the #Service type hint to the $service parameter of our getMockService function, we now get completion and navigation when calling it.

Symfony mock completion in a helper function

Unfortunately, we don't get completion for our mocked service: only completion for PHPUnit's PHPUnit_Framework_MockObject class is available.

Symfony mock completion in a helper function not available

Ideally, invoking completion on the $mock instance would yield all public members of, in this case, the filesystem service. When invoking getMockService with the mailer service name, we would expect it to provide completion based on the public members of the mailer service.

To achieve this, in the Settings dialog (Control+Alt+S), navigate to Languages & Frameworks | PHP | Symfony | Type Provider. Then, select the Enable Custom Signature Types checkbox and click the Add button to add information about the getMockService function.

Create Symfony helper function custom signature

Provide the following:

  • CallTo: The FQN of the class (with leading \) that contains the function.

  • Method: The function name.

  • Index: The index of the parameter that determines the return type.

  • Provider: The provider of potential data. This is where we choose the Symfony component type that is returned by the function.

Once we apply changes, code completion for our $mock variable will be available.

Symfony mock completion in a helper function available
Last modified: 21 June 2023