ZF2 and EntityManager (Doctrine)

user1765334 picture user1765334 · Oct 25, 2012 · Viewed 10.7k times · Source

I have a problem. I try to get the Entity-Manager without a Controller, but I found no way. At this time, I get the Entity-Manager like this:

(Controller)
public function getEntityManager()
{
    if (null === $this->_em) {
        $this->_em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
    }
    return $this->_em;
}

(Plugin)
public function getEntityManager()
{
    if($this->_em == null){
        $this->_em = $this->getController()->getServiceLocator()->get('doctrine.entitymanager.orm_default');
    }
    return $this->_em;
}

You see, I need allways a controller. But, if I need the EntityManager in a model, i have a problem. I can give the model the controller, but I think this is really a bad way.

Have you any idea to get the EntityManager without a controller?

Answer

Sam picture Sam · Oct 25, 2012

The way I handle Doctrine is through Services, i do it like the following:

//some Controller
public function someAction()
{
    $service = $this->getServiceLocator()->get('my_entity_service');
    return new ViewModel(array(
        'entities' => $service->findAll()
    ));
}

The Service->findAll() would look something like this:

public function findAll()
{
    return $this->getEntityRepository()->findAll();
}

Now we need to define the my_entity_service. I do this inside my Module.php

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'my_entity_service' => 'Namespace\Factory\MyServiceFactory'
        )
    );
}

Next I create the Factory (note: this could also be done via anonymous function inside the Module.php)

<?php
namespace Namespace\Factory;

use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
use Namespace\Model\MyModel;

class MyServiceFactory implements FactoryInterface
{
    /**
     * Create service
     *
     * @param ServiceLocatorInterface $serviceLocator
     * @return mixed
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $myModel= new MyModel();
        $myModel->setEntityManager($serviceLocator->get('Doctrine\ORM\EntityManager'));

        return $myModel;
    }    
}

Now this is a lot to chew :D I totally get that. What is happening here is actually very simple though. Instead of creating your model and somehow get to the EntityManager, you call ZF2's ServiceManager to create the Model for you and inject the EntityManager into it.

If this is still confusing to you, I'll gladly try to explain myself better. For further clarification however I'd like to know about your use case. I.e.: what for do you need the EntityManager or where exactly do u need it.

This code example is outside of the question scope

Just to give you a live example of something I do via ServiceFactories with forms:

public function createService(ServiceLocatorInterface $serviceLocator)
{
    $form = new ReferenzwertForm();
    $form->setHydrator(new DoctrineEntity($serviceLocator->get('Doctrine\ORM\EntityManager')))
         ->setObject(new Referenzwert())
         ->setInputFilter(new ReferenzwertFilter())
         ->setAttribute('method', 'post');

    return $form;
}