Home » Php » php – How to resolve a path in a non controller class in symfony2

php – How to resolve a path in a non controller class in symfony2

Posted by: admin July 12, 2020 Leave a comment

Questions:

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?

How to&Answers:

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.

Answer:

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

Answer:

You can define this class as a service and inject router service into it.

More info: Service Container.