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.
Press Control+Alt+S to open the IDE settings and select
.Switch to the Marketplace tab and use the search field to find the plugins.
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:
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.
Code completion and navigation for the returned $response
instance are available, too.
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:
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 . Then, click to add a new method parameter registration.
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.
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.
The Symfony Plugin will now index the function correctly and provide completion and navigation for the $route
parameter.
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.
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.
Unfortunately, we don't get completion for our mocked service: only completion for PHPUnit's PHPUnit_Framework_MockObject
class is 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 . Then, select the Enable Custom Signature Types checkbox and click to add information about the getMockService
function.
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.