Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZF2 and EntityManager (Doctrine)

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?

like image 904
user1765334 Avatar asked Oct 25 '12 09:10

user1765334


2 Answers

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;
}
like image 165
Sam Avatar answered Nov 12 '22 11:11

Sam


Your real question is "How to get an Instance of ServiceManager in my own classes"

For this, take a look at the docu: (bottom of page http://zf2.readthedocs.org/en/latest/modules/zend.service-manager.quick-start.html)

By default, the Zend Framework MVC registers an initializer that will inject the ServiceManager instance, which is an implementation of Zend\ServiceManager\ServiceLocatorInterface, into any class implementing Zend\ServiceManager\ServiceLocatorAwareInterface. A simple implementation looks like the following.

so implent the ServiceLocatorInterface in your classes and then inside your class you can call:

$this->getServiceLocator()->get('doctrine.entitymanager.orm_default');

or any other service you have registered.

like image 4
Rufinus Avatar answered Nov 12 '22 12:11

Rufinus