1

I have a question about Symfony2 Controller extending. For the moment, I was always extending the FrameworkBundle one for every controller in my app. But I'm getting sick of always retrieving the user by making a

$this->get('security.context')->getToken()->getUser()

or a

$this->getDoctrine()->getEntityManager()

each time I need the user or the entity manager (I need them a lot). I wanted to be able to retrieve them just by doing $this->em and $this->user. So I decided to create a bundle named MyApp/RootBundle, which contains a new controller extending the FrameworkBundle one. This controller would be extended by every other controller in the app. Here is the code :

<?php

namespace MyApp\RootBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;

class RootController extends Controller
{
    protected $em;

    protected $user;

    public function setContainer(ContainerInterface $container = null)
    {
        parent::setContainer($container);

        $this->onContainerSet();
    }

    public function onContainerSet()
    {
        $this->em = $this->getDoctrine()->getEntityManager();
        $this->user = $this->get('security.context')->getToken()->getUser();
    }
}

I couldn't load the $this->em and $this->user in a __construct() function since the container is not loaded at the construction time.

So my questions are :

  • Is that a good idea or should I continue to make the verbose calls ?
  • Would it be better to just create functions getEm() and getUser() that would do the same job ?

Thanks !

4 Answers 4

4

I had the same problem, I just created a custom controller that had getUser() and getEntityManager() methods. It works perfectly. I would recommend using getter methods instead of class instances in this case just to keep consistent with how Symfony2 expects you to request services.

For reference, here is my getUser method:

public function getUser() {
        $user = $this->get('security.context')->getToken()->getUser();
        return $user;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Ok, that's what I thought. And is that a good idea to make a "RootBundle" or not ?
You could, but I keep my custom controller in the vendor directory. I didn't see the need to put it in its own bundle. Either way should work fine though, so it comes down to personal preference.
0

I created a MyController but also a MyRepository. Then all Controllers and Repositories extends these classes. I also call $this->getRepository("User"), instead of $this->getDocrine()->getEntityManager()->getrepository("MyappBundle:User");

2 Comments

Good idea, I'll do the same :)
Here is the snippet : public function getEm(){ return $this->getDoctrine()->getEntityManager(); } public function getRepository($shortEntityName){ return $this->getEm()->getRepository("SicoStockBundle:$shortEntityName"); }
0

Another option is that you define your controllers as services and assign what gets passed to your constructor to any private variable you wish, but the downside might be that you won't like all the setup this route needs

Comments

0

you can inject EntityManager(or any other services) even without controller extantion as:

use JMS\DiExtraBundle\Annotation as DI;

    class IndexController extends Controller 
    {  
       /**
         * @DI\Inject("doctrine.orm.entity_manager")
         * @var \Doctrine\ORM\EntityManager $em
         */
        protected $em;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.