我有一个基本的Doctrine2实体,但其中一个字段需要应用一些格式才能将其从数据库主键转换为用户可见的“友好ID”。
我想将格式化逻辑放在一个地方,这样如果它改变了,它只需要更新一次。
部分格式化涉及从数据库中查找字符串并将其用作前缀,因为此值对于不同的安装将是不同的。我有点卡住了,因为在实体内我不能(也可能不应该)查找数据库来检索这个前缀。
但是我不知道怎么回事。
这是一些伪代码,说明了我要做的事情:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
// This is also an entity, annotations/getters/setters omitted for brevity.
class Lookup {
protected $key;
protected $value;
}
class Person {
/**
* Database primary key
*
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* Get the person's display ID.
*
* @Serializer\VirtualProperty
* @Serializer\SerializedName("friendlyId")
*/
protected function getFriendlyId()
{
if ($this->person === null) return null;
//$prefix = 'ABC';
// The prefix should be loaded from the DB, somehow
$lookup = $this->getDoctrine()->getRepository('AppBundle:Lookup')->find('USER_PREFIX');
$prefix = $lookup->getValue();
return $prefix . $this->person->getId();
}
}
答案 0 :(得分:2)
您可以使用event listeners使用symfony和doctrine并通过注册服务来收听postLoad
事件
services:
person.postload.listener:
class: AppBundle\EventListener\PersonPostLoadListener
tags:
- { name: doctrine.event_listener, event: postLoad }
现在,在您的监听器中,您将可以访问实体管理器
namespace AppBundle\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use AppBundle\Entity\Person;
class PersonPostLoadListener
{
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof Person) {
return;
}
$entityManager = $args->getEntityManager();
$lookup =$entityManager->getRepository('AppBundle\Entity\Lookup')->findOneBy(array(
'key'=> 'USER_PREFIX'
));
$entity->setFriendlyId($entity->getId().$lookup->getValue());
//echo "<pre>";dump($entity);echo "</pre>";die('Call')
}
}
在你的person实体中,你需要为你的id及其getter和setter方法定义一个未映射的属性,如
class Person
{
private $friendlyId;
public function getFriendlyId()
{
return $this->friendlyId;
}
public function setFriendlyId($friendlyId)
{
return $this->friendlyId = $friendlyId;
}
}