I think I solved my problem. If someone else has a more elegant way to achieve these results, feel free to explain. To change all my queries, I created my own EntityManager and a custom EntityRepository.
In my custom EntityManager, I overwrote 2 methods. create () and getRepository ()
public static function create($conn, Configuration $config, EventManager $eventManager = null) { if ( ! $config->getMetadataDriverImpl()) { throw ORMException::missingMappingDriverImpl(); } switch (true) { case (is_array($conn)): $conn = \Doctrine\DBAL\DriverManager::getConnection( $conn, $config, ($eventManager ?: new EventManager()) ); break; case ($conn instanceof Connection): if ($eventManager !== null && $conn->getEventManager() !== $eventManager) { throw ORMException::mismatchedEventManager(); } break; default: throw new \InvalidArgumentException("Invalid argument: " . $conn); } return new MyCustomEntityManager($conn, $config, $conn->getEventManager()); }
The only thing that has changed in this method is that I return my own EntityManger ( MyCustomEntityManager ). Then I overlaid the getRepository method as follows:
public function getRepository($entityName) { $entityName = ltrim($entityName, '\\'); if (isset($this->repositories[$entityName])) { return $this->repositories[$entityName]; } $metadata = $this->getClassMetadata($entityName); $repositoryClassName = $metadata->customRepositoryClassName; if ($repositoryClassName === null) { $repositoryClassName = "Acme\DemoBundle\Doctrine\ORM\MyCustomEntityRepository"; } $repository = new $repositoryClassName($this, $metadata); $this->repositories[$entityName] = $repository; return $repository; }
Here I only changed one line. Instead of relying on the DBAL configuration to restore the default value of $ repositoryClassName, I specified my own default repository Acme \ DemoBundle \ Doctrine \ ORM \ MyCustomEntityRepository .
Once you have created your own EntityRepository, the sky is the limit. You can embed services in the repository (I currently use the JMS Di annotations described below) or perform custom actions against QueryBuilder in the createQueryBuilder method, for example:
use JMS\DiExtraBundle\Annotation as DI; class MyCustomEntityRepository extends EntityRepository { private $myService; public function createQueryBuilder($alias) { $queryBuilder = parent::createQueryBuilder($alias); return $queryBuilder; } public function setMyService(MyServiceInterface $myService) { $this->myService = $myService; } }
Once you have created your own EntityRepository, you should have all of your repositories that need this custom functionality, expanding MyCustomEntityRepository. You can even take it one step further and create your own QueryBuilder for further expansion.