score:3

Accepted answer

I looked into this a bit. My first hunch is "Well, if you could define EntityRepositories as services, then that would make this easy because you could then just inject the logger"

But how do you inject the logger into repositories that doctrine is creating? It turns out you can specify your own repository factory

I'm going to assume all it needs is to implement the Doctrine\ORM\Repository\RepositoryFactory interface, but you'll probably want to subclass Doctrine\ORM\Repository\DefaultRepositoryFactory.

You will also need to create your own, base repository class that can hold a logger. Let's start there

src/AppBundle/Doctrine/EntityRepository.php

<?php

namespace AppBundle\Doctrine;

use Doctrine\ORM\EntityRepository;
use Psr\Log\LoggerInterface;

class LoggerAwareEntityRepository extends EntityRepository
{
    protected $logger;

    public function setLogger(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }
}

Now, the factory

src/AppBundle/Doctrine/LoggerAwareRepositoryFactory.php

<?php

namespace AppBundle\Doctrine;

use Doctrine\ORM\Repository\DefaultRepositoryFactory;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use AppBundle\Doctrine\LoggerAwareEntityRepository;

class LoggerAwareRepositoryFactory extends DefaultRepositoryFactory
{
    protected $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    protected function createRepository(EntityManagerInterface $entityManager, $entityName)
    {
        $repository = parent::createRepository($entityManager, $entityName);

        if ($repository instanceof LoggerAwareEntityRepository) {
            $repository->setLogger($this->logger);
        }

        return $repository;
    }
}

Now for the confguration glue to make it all work

app/config/services.yml

services:
    logger_aware_repository_factory:
        class: AppBundle\Doctrine\LoggerAwareRepositoryFactory
        arguments: ['@logger']

app/config/config.yml

doctrine:
    orm:
        entity_managers:
            default:
                repository_factory: "@logger_aware_repository_factory"

Lastly, for the actual implementation

src/AppBundle/Entity/SomeCustomRepository.php

<?php

namespace AppBundle\Entity;

use AppBundle\Doctrine\LoggerAwareEntityRepository;

class SomeCustomRepository extends LoggerAwareEntityRepository
{
    public function findSomethingCustom()
    {
        // Log something
        $this->logger->log('message');
    }
}

Full disclosure: this is untested code - there might be bugs!

score:0

Depending on what you want to log the most neat solution would be to create either a doctrine or doctrine entity listener, probably on post load. Inject the logger in the listener. Once you decide you don't need it, just remove the listener.


Related Query

More Query from same tag