IntelliJ IDEA 2021.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.

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 Ctrl+Space for the $route and , as well as the ability to navigate to the corresponding declaration Ctrl+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/Preferences dialog Ctrl+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/Preferences dialog Ctrl+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: 08 March 2021