我的Doctrine 2 Entity有一个抽象类。如何注入服务定位器以获取Translator或Zend \ Mvc \ Controller \ Plugin \ Url,或者如何将这些插件直接注入抽象实体类。
目标是从实体存储库中获取学说实体,并在抽象实体模型/服务中操纵实体的结果。
Doctrine 2实体简称:
namespace Rental\Entity;
use Doctrine\ORM\Mapping as ORM;
use Rental\Model\Rental as AbstractRental;
/**
* Rental
*
* @ORM\Entity(repositoryClass="Rental\Repository\Rental") *
* @ORM\Table(name="rental", options={"collate"="utf8_general_ci"})
*/
class Rental extends AbstractRental{
...
public function getType(){
...
}
... entity setter and getter
}
抽象实体模型:
namespace Rental\Model;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
/**
* Rental\Model\Rental
* @ORM\MappedSuperclass
* @ORM\HasLifecycleCallbacks
*/
abstract class Rental implements ServiceLocatorAwareInterface
{
protected $serviceLocator;
protected $translator;
abstract protected function getType();
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function getTranslator()
{
if (!$this->translator) {
$this->translator = $this->getServiceLocator()->get('translator');
// here is the problem, because getServiceLocator is NULL
}
return $this->translator;
}
public function getTranslatedType(){
return $this->translator->translate($this->getType())
}
这不起作用,因为抽象类没有实例化,因此不会注入ServiceLocatorInterface。
这是我的控制器:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Doctrine\ORM\EntityManager;
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Doctrine\ORM\EntityManager;
class IndexController extends AbstractActionController
{
/**
* @var \Doctrine\ORM\EntityManager
*/
protected $em;
/**
* @param \Doctrine\ORM\EntityManager $em
*/
public function setEntityManager(EntityManager $em)
{
$this->em = $em;
}
/**
* @return array|\Doctrine\ORM\EntityManager|object
*/
public function getEntityManager()
{
if (NULL === $this->em) {
$this->em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
}
return $this->em;
}
/**
* @return \Zend\View\Model\ViewModel
*/
public function indexAction()
{
...
/** @var $repository \Rental\Repository\Rental */
$repository = $this->getEntityManager()->getRepository('Rental\Entity\Rental');
/** @var $rentals array */
$rental= $repository->findBySlug($slug);
\ChromePhp::log($rental->getTranslatedType());
// is NULL
答案 0 :(得分:-1)
这是实现将ZF2服务定位器注入从抽象类继承的实体的目标的一种方法
请记住更改/修复任何名称空间
首先,您需要使用Doctrine注册事件监听器。您只需要监听 postLoad 。为此,实例化侦听器(我们接下来将定义)并将其传递给它唯一的依赖项,即服务定位器。
Module.php
// in your Module.php
use Rental\Model\Listeners\EntityInjectorListener;
public function onBootstrap(MvcEvent $e)
{
$serviceLocator = $e->getApplication()->getServiceManager();
$entityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
$entityManager->getEventManager()->addEventListener(array(\Doctrine\ORM\Events::postLoad), new EntityInjectorListener($serviceLocator));
}
现在为Doctrine定义一个侦听器。它应该检查它正在处理的实体,如果它继承自你的抽象类,那么它应该设置服务定位器。
// EntityInjectorListener.php
namespace \Rental\Model\Listeners;
class EntityInjectorListener
{
protected $serviceLocator;
public function __construct($serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function postLoad($eventArgs)
{
// check if entity is a child of abstract class
if ($eventArgs->getEntity() instanceof \Rental\Model\Rental) {
$eventArgs->getEntity()->setServiceLocator($this->serviceLocator);
}
}
}
现在你的实体内你应该可以打电话给
$this->getServiceLocator()->get('whatever-you-want-get');
要使用视图助手,您需要像这样调用它们:
$this->getServiceLocator()->get('ViewHelperManager')->get('url');