Reputation: 573
I wanted to override the default Doctrine\ORM\EntityRepository
class in my Symfony2 project so that I can have access to the @session
service so that all of my repositories have access to a certain session variable if it is set.
On investigation it appeared to be less simple than I had hoped, as the EntityRepository is instantiated from within the Doctrine\ORM\EntityManager
, and this class is instantiated itself using a static "create" method.
I followed the answer in Injecting dependency into entity repository but have hit a roadblock in actually implementing the custom manager class (specifically where the answer's author says "But since you're making a custom entity manager, you can wire it up to the service container and inject whatever dependencies you need").
I have defined my overridden EntityManager class, with an overridden "create" function and have also overridden the "getRepository" function. It is in this function that I believe I need to add the session to the Repository as it is created using a "setSession" method on my overridden EntityRepository class, but I am unsure as to how to actually get the session into the manager in the first place, as the other constructor arguments for the EntityManager class (Connection $conn, Configuration $config, EventManager $eventManager
) are supplied in the Symfony\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension
"ormLoad" method.
I have also specified
doctrine.orm.entity_manager.class: Me\MyBundle\Doctrine\ORM\EntityManager
in my config.yml file.
How can I have Symfony use my custom EntityManager class when creating repositories, and inject the session into it as well?
Upvotes: 2
Views: 1669
Reputation: 9876
In Symfony 4+ you can just make it a ServiceEntityRepository
and with autowiring there's no need for any services.yaml changes.
namespace App\Repository;
use App\Entity\YourEntity;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class YourRepository extends ServiceEntityRepository
{
private $session;
public function __construct(ManagerRegistry $registry, SessionInterface $session)
{
$this->session = $session;
parent::__construct($registry, YourEntity::class);
}
public function findSomethingUsingSession()
{
$someValue = $this->session->get('some_index');
// ...
}
}
Then in your controller (for example)
$repository = $this->getDoctrine()->getRepository(YourEntity::class);
$result = $repository->findSomethingUsingSession();
Or use dependency injection (recommended)
public function someAction(YourRepository $repository)
{
$result = $repository->findSomethingUsingSession();
// ...
}
Upvotes: -1
Reputation: 573
I ended up going with something slightly different:
I overrode the doctrine.orm.entity_manager.class
parameter with my custom class which simple extended the default class with an additional $session
parameter (complete with getter and setter), along with overridden create
and getRepository
functions (to return instances of my class instead of the default.
I then overrode the EntityRepository
class and implemented a "getSession" method which returned
$this->_em->getSession();
and finally, in a custom event listener which has access to the entity manager, I called
$this->entityManager->setSession($session);
which gave me access to the session from every repository.
Upvotes: 1
Reputation: 20201
Florian, here, explained how to create repository via service:
my_service:
class: Doctrine\Common\Persistence\ObjectRepository
factory_service: doctrine # this is an instance of Registry
factory_method: getRepository
arguments: [ %mytest.entity% ]
You could add calls
to invoke setSession
(as deferred DI):
my_service:
...
calls:
- [setSession, ["@session"]]
Is this you're trying to do?
Upvotes: 3