Meet the bundle: ControllerExtraBundle

NOTE: This is the first post of a new series called "Meet the bundle" dedicated to promote Symfony bundles developed by the community and which are not well-known yet.


Annotations are one of the favorite topics to engage in a discussion with other developers. Some of them think that using annotations is a bad practice full of drawbacks, while others love how annotations reduce a fair amount of boilerplate code in their applications.

As usual, Symfony position is friendly for both sides: if you don't like annotations, don't use them. If you like them, Symfony supports and provides you with several useful annotations via the SensioFrameworkExtraBundle.

In this article we'll introduce ControllerExtraBundle, which is a bundle that provides even more annotations to perform common controller tasks. One of those annotations is called Pagination and it allows you to create and inject paginator objects:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
use Doctrine\ORM\Tools\Pagination\Paginator;
use Mmoreram\ControllerExtraBundle\Annotation\Paginator as CreatePaginator;

/**
 * @CreatePaginator(class = "AppBundle:Product")
 */
public function listAction(Paginator $paginator)
{
    // ...
}

This annotation defines a lot of configuration options: the number of elements per page, the default result page number, the properties used for ordering results, the conditions used to filter results, etc.

Another useful annotation is Form, which creates Symfony forms based on the type class or the type service id, as shown in the following example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
use Mmoreram\ControllerExtraBundle\Annotation\Form as CreateForm;
use Symfony\Component\Form\Form;

/**
 * @CreateForm(class = "user_type", name = "user")
 */
public function registerAction(Form $user)
{
    // ...
}

This annotation can even be combined with Symfony's @ParamConverter to create a form object with an previously created entity:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Form\Form;
use Mmoreram\ControllerExtraBundle\Annotation\Form as CreateForm;
use AppBundle\Entity\User;

/**
 * @Route(path = "/user/{id}", name = "user_view")
 *
 * @ParamConverter("user", class="AppBundle:User")
 * @CreateForm(class = "user_type", entity = "user", name = "form")
 */
public function viewAction(User $user, Form $form)
{
}

Read the bundle's documentation to learn about the rest of annotations: @Entity @ObjectManager, @Flush, @JsonResponse, @Log, @Get and @Post.

About the author

ControllerExtraBundle is developed by Marc Morera, a Symfony veteran from Barcelona (Spain). In addition to leading the Symfony Barcelona group, he is the chief architect of Elcodi, an e-commerce platform developed with Symfony components.

We're looking for the next bundle

Do you know any other useful Symfony bundle which is not well-known by the community yet? Tell us about it in the comments below or send us an email to javier.eguiluz@sensiolabs.com and we'll feature it in the next article of this series!

Comments

Nice bundle !

Some correction in the article:
The annotation is not called Pagination but CreatePaginator.
The annotation is not called Form but CreateForm
@Jérémy the annotations are in fact called after generic names ("Pagination", "Form", etc.) but I've changed those names in the "use" statement to make them more expressive. Example:

use Mmoreram\ControllerExtraBundle\Annotation\Paginator as CreatePaginator;
@Javier I think this is confusing. People will use "CreateForm" without realizing that there is a use statement. Heck, I thought those were walled CreateForm and CreatePaginator.
The problem is that the annotations use generic names (example: "Form") which collide with the Symfony class names. In the original bundle documentation, he uses "use ...\Form as FormAnnotation" but I find "... as CreateForm" more expressive because it describes its purpose.

In fact, given that the annotations "do things", I think they should be named with a verb, to clearly show their purpose: "@ParamConverter" could be "@ConvertParameter" and "@Template" could be "@RenderTemplate".
Great news!
I agree with @javier.
I agree with @javier as well... In fact, I will create those annotations in order to give the possibility of using them in a more descriptive way...

@createForm
@createPaginator
@mapEntity
@log
...

Do you think this is a good idea? I mean, just creating these entities extending old ones should work as expected, right?
I agrer with @javier.

Also @marc you should do that so no BC and also keeping the Liskov Substiution Principle.

Great new serie
Nice! This is a good bundle.
Annotation is good. However, I could not stick with yet. Hope I use it asap :) Thanks for the introduction.
@Javier good point about the naming issue. An other possibility would be using a namespace like we do in entities with @ORM\Table() , @ORM\Column() .... ? You could have something like @Extra\Form ... ( or something other than "Extra" ).
@Nicolas You can do @ORM\Table() because you have defined the namespace of ORM at the beginning of the file

use Doctrine\ORM;

Of course you can do the same by doing this

use Mmoreram\ControllerExtraBundle\Annotation as ControllerAnnotation;
@ControllerAnnotation\Form()
Is the initiative "Meet the Bundle" still going on?
@Niels yes, of course. We already have prepared the second post, but we're waiting for the bundle's author review. If you know any other interesting bundle, please send it to us. Thanks!

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.