Skip to end of metadata
Go to start of metadata

Redirection Notice

Icon

 

Creating Helper Functions

Everything we've seen so far in this tutorial is great. But what if we want to create our own helper functions that take or return a template, service, entity, translation, route, form or event? The Symfony2 Plugin is intelligent enough to figure out parameter types and return types based on their usage with Symfony2 classes and functions.

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 we can easily redirect users to a known route within our application. Here's the code:

When we call into the redirectToRoute function, we will get completion (Ctrl+Space) and navigation (Ctrl+B (or CMD+B on Mac OS X)) for the $route parameter.

We also get completion and navigation for the returned $request instance.

The reason both of these work is that the Symfony2 Plugin infers the type of $route by analyzing calls and return types for known functions. This type analysis works for most Symfony2 components we have discussed so far in this tutorial (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 Symfony2 Plugin comes with a solution: it provides access to some of its internals through the Method Parameter and Signature Types project settings.

Method Parameter

Imagine having the following function:

In the current implementation, we're not making use of any Symfony2-specific functions. Because of that, the Symfony2 Plugin's 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 that, in several ways:

Let's explore both options.

Option 1: Using Method References

From the Project Settings | Symfony2 Plugin | Method References, we can tell the Symfony2 Plugin about our method. Click the green + to add a new method parameter registration. We will have to provide several values:

  • CallTo: The class that contains the function. (FQN, leading \ required)
  • 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 Symfony2 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, we can enter the key for which to provide completion and navigation here.

Once we save, we now have full completion and navigation support for our helper function's parameters. And even better: since this is a project-level setting, we can add our project settings to a VCS and share these with team members.

Icon

While this is very powerful, making use of hints with hashes is probably easier to work with in most situations and does not require sharing project settings with team members.

Option 2: Using Hashes

Instead of configuring method parameters in the project settings, we can also make use of hinting, similarly to the way we can provide PhpStorm with type hints using PHPDoc.

By adding any of the following in our 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

Here's an example with the function we wrote before. Note the #Route in the description for the $route parameter.

The Symfony2 Plugin will now index our function correctly and provide us with completion and navigation for this parameter.

Signature Types

Consider the following PHP class. It's 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 Symfony2 web application.

Because we 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. We do get completion for PHPUnit's PHPUnit_Framework_MockObject class.

Ideally, invoking completion on our $mock instance would yield all public members of, in this case, the filesystem service. And when invoking getMockService with a service name "mailer", we would expect it to provide completion based on the public members of the mailer service. We can do this!

From the Project Settings | Symfony2 Plugin | Type Provider, we can tell the Symfony2 Plugin about our wishes. Tick the Enable Custom Signature Types checkbox and click the green + to add information about our getMockService function. We'll have to provide:

  • CallTo: The class that contains the function. (FQN, leading \ required)
  • 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 Symfony2 component type that is returned by our function.

Once we save, PhpStorm will provide completion support on our $mock variable.

 

  • No labels