0
votes

I've got a need to set a parameter into some queries that comes from the symfony2 configuration.

Normally you would pass that parameter from outside the repository class, but in this case I don't want to do that.

I've looked at a custom function (as that is already in play as well), but I can't use a service as custom function for Doctrine. So I would need to do some nasty things to get the parameter from the ServiceContainer. Something similar is the case for SqlWalkers.

I think the best might even be to push the parameter into the Doctrine Configuration object or EntityManager. This would allow me to fetch the parameter from the Query object in the CustomFunction and add it to the query when needed.

If that is not possible a good alternative would be to have the parameter available in the Repository class. That way it would not need to be passed manually to the Repository class.

Is there a way to inject some custom parameter in the Doctrine Configuration? Or the Repository class? Does anyone has a better solution?

2
Could you explain what prevents you from injecting the parameter into the repository (service)? - Nicolai Fröhlich
Just the sake of simplicity, can you tell us what you want instead of writing a long-winded case please? Thanks - BentCoder
You wanted something nasty so there it is (well based on what I understood after trying to understand): stackoverflow.com/questions/12971552/… - BentCoder
@nifr: the question is how to do that. - DoppyNL
@BentCoder: explaining what parameters are needed in the Repository would make it even less understandable on stackoverflow. Question in short: How do I get a application-wide configured parameter into multiple Repositories automatically. (see answer below). - DoppyNL

2 Answers

0
votes

What is a repository ? It is no more than the result of a factory pattern in the Doctrine Manager class.

So you can define your repository as a service in the container. This service being the result of a factory call :

http://php-and-symfony.matthiasnoback.nl/2014/05/inject-a-repository-instead-of-an-entity-manager/

http://symfony.com/doc/current/components/dependency_injection/factories.html

You can then inject parameters using calls configuration.

0
votes

I hate answering my own questions, but the solution I found is different from what was suggested and works like a charm.

Short version: Decorate the entity manager and adjust the Repository class before returning it.

Long version: Create a Decorator:

class EntityManagerDecorator extends \Doctrine\ORM\Decorator\EntityManagerDecorator
{
    protected $myProperty;

    public function __construct(EntityManagerInterface $wrapped, ....) {
        parent::__construct($wrapped);
        $this->myProperty = $myProperty;
    }

    // overridden method so we can add some additional logic.
    public function getRepository($className)
    {
        $repository = parent::getRepository($className);

        if ($repository instanceof ExpandedEntityRepository) {
            $repository->setMyProperty($this->myProperty);
        }
        return $repository;
    }
}

Create a new Base repository class, make sure you extend your repository classes that need this from this one.

class ExpandedEntityRepository extends EntityRepository {
    protected $myProperty;
    public function getMyProperty()
    {
        return $this->myProperty;
    }
    public function setMyProperty($myProperty)
    {
        $this->myProperty = $myProperty;
    }
}

I recommend you actually replace this with an Interface (which you check for in the Decorator) and a trait (wich you add to your repository class to add the needed methods) to make it more elegant. I used a base class as this still needs to work in PHP5.3

Finally configure your sevices to decorate the original entity manager:

services:
    my_cool_bundle_entitymanager_decorator:
        public: false
        class: MyCoolBundle\ORM\EntityManagerDecorator
        decorates: doctrine.orm.default_entity_manager
        arguments:
          - @my_cool_bundle_entitymanager_decorator.inner
          - %my_cool_bundle.property%

Keep in mind you might need to do this multiple times if you got additional entity-managers.