I have a form builder class which inherits from AbstractType
and I need to resolve a path like this:
$uri = $router->generate('blog_show', array('slug' => 'my-blog-post'));
Since the class is not a child of Controller
I have no access to the router. Any ideas?
What about passing the router to the class on construction time?
You can pass the router
service via constructor to your form type. Register your form as a service with the form.type
tag and inject the router
service to it.
<?php
namespace Vendor\Bundle\AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
class PostType extends AbstractType
{
/**
* @var Router
*/
private $router;
/**
* @param Router
*/
public function __construct(Router $router)
{
$this->router = $router;
}
/**
* @return string
*/
public function getName()
{
return 'post';
}
// ...
}
Register it as a service:
services:
form.type.post:
class: Vendor\Bundle\AppBundle\Form\Type\PostType
arguments: [ @router ]
tags:
- { name: form.type }
And use it in your controller like this:
public function addAction(Request $request)
{
$post = new Post();
$form = $this->createForm('post', $post);
// ...
}
Since you registered your form type as a service with the form.type
tag, you can simply use its name instead of new PostType()
. And you can access the router
service as $this->router
in your type.
If you going to use your form builder class in some controller, you can do it more simpler and your form builder going more flexible:
public function someAction() {
//...
$task = new Task();
$form = $this->createForm(new TaskType(), $task, array(
'action' => $this->generateUrl('target_route'),
'method' => 'GET',
));
}
There is no need to set the URL in the form type class.
Read more here:
http://symfony.com/doc/current/form/action_method.html
You can define this class as a service and inject router service into it.
More info: Service Container.