学说跟踪多个实体关系的变化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学说跟踪多个实体关系的变化相关的知识,希望对你有一定的参考价值。
我有这个实体
class nmEntidad
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
**/
private $id;
/**
* @var boolean
*
* @ORM\Column(name="eliminado", type="boolean")
**/
private $eliminado;
/**
* @var boolean
*
* @ORM\Column(name="tiene_area", type="boolean")
**/
private $tieneArea;
/**
* @var integer
*
* @ORM\Column(name="tiene_entidad", type="integer")
**/
private $tieneEntidad;
/**
* @var string
* @Assert\NotBlank(message="error.nmEntidad.nombre.blank")
* @ORM\Column(name="nombre", type="string")
**/
private $nombre;
/**
* @var string
* @Assert\NotBlank(message="error.nmEntidad.acronimo.blank")
* @ORM\Column(name="acronimo", type="string")
**/
private $acronimo;
/**
* @var string
*
* @ORM\Column(name="logo", type="string", nullable=true)
**/
private $logo;
/**
* @var string
*
* @ORM\Column(name="direccion", type="string", nullable=true)
**/
private $direccion;
/**
* @var string
*
* @ORM\Column(name="telefono", type="string", length=100, nullable=true)
**/
private $telefono;
/**
* @var string
* @Assert\NotBlank(message="error.nmEntidad.email.blank")
* @Assert\Email(message="email:error.nmEntidad.email.notvalid")
* @ORM\Column(name="email", type="string", length=50)
**/
private $email;
/**
* @var boolean
*
* @ORM\Column(name="primaria", type="boolean")
**/
private $primaria;
/**
* @var string
* @Assert\NotBlank(message="error.nmEntidad.respinf.blank")
* @Assert\Email(message="informatic_email:error.nmEntidad.respinf.notvalid")
* @ORM\Column(name="email_responsable_informatica", type="string", length=50)
**/
private $RespInform;
/**
* @ORM\ManyToOne(targetEntity="nmEntidad")
* @ORM\JoinColumn(name="id_padre", referencedColumnName="id")
*/
private $padre;
/**
* @ORM\ManyToOne(targetEntity="nmEmpresa")
* @ORM\JoinColumn(name="id_empresa", referencedColumnName="id")
*/
private $empresa;
/**
* @ORM\ManyToOne(targetEntity="nmUsuario")
* @ORM\JoinColumn(name="id_representante", referencedColumnName="id", nullable=false)
*/
private $representante;
}
然后我有一个doctrine lifecyclecallback事件的监听器,所以每当这些事件中的一个触发时,我都会为asociated事件创建一个登录数据库。
public function onSucessLogin(AuthenticationEvent $event)
{
if (!$event->getAuthenticationToken()->getUser() instanceof UserInterface)
return;
if(!$this->request)
return;
if ($this->request->getMethod() == 'GET')
return;
$user = $event->getAuthenticationToken()->getUser();
$this->container->get('monolog.logger.db')->info('request', ['user' => $user->getUsername(), 'empresa' => $user->getEmpresa()->getEmpresa()]);
}
//establecemos el codigo de response para ver si fallo la operacion o no
public function onKernelResponse(FilterResponseEvent $event)
{
if (!$this->checkIfUserRequest())
return;
if (!$this->isLog())
return;
if (!$event->isMasterRequest())
return;
$responseCode = $event->getResponse()->getStatusCode();
if (!$this->request->attributes->has('logEntry'))
return;
$logEntry = $this->request->attributes->get('logEntry');
if ($responseCode == Response::HTTP_BAD_REQUEST) {
$logEntry['status'] = Response::HTTP_BAD_REQUEST;
} else if ($responseCode == Response::HTTP_FORBIDDEN) {
$logEntry['status'] = Response::HTTP_FORBIDDEN;
} else if ($responseCode == Response::HTTP_UNAUTHORIZED) {
$logEntry['status'] = Response::HTTP_UNAUTHORIZED;
}
$this->request->attributes->set('logEntry', $logEntry);
}
//terminamos de construir el log y lo procesamos a la base de datos
/* public function onKernelFinishRequest(FinishRequestEvent $event)
{
$this->log($event);
}*/
private function log()
{
/* if (!$event->isMasterRequest())
return;
if (!$this->checkIfUserRequest())
return;*/
$log = $this->request->attributes->get('logEntry');
if (!$log)
return;
$logEntity = $this->buildLog($log);
if ($logEntity->getMessage() == '')
return;
$this->container->get('doctrine')->getEntityManager()->persist($logEntity);
$this->container->get('doctrine')->getEntityManager()->flush();
}
public function preUpdate(LifecycleEventArgs $args)
{
if (!$this->isLog())
return;
$entity = $args->getObject();
$em = $this->getEm();
$uow = $em->getUnitOfWork();
$changeSet = $uow->getEntityChangeSet($entity);
if ($entity instanceof UserInterface) {
if (sizeof($changeSet) == 1 && array_key_exists("lastLogin", $changeSet)) {
return;
}
}
if (!$changeSet)
return;
$value = $this->generateObjectChangeSet($entity, $changeSet, 'preUpdate');
$this->addEntityChangeSet($value);
//generando el id
}
public function postUpdate(LifecycleEventArgs $args)
{
if (!$this->isLog())
return;
$method = $this->request->getMethod();
$body = array();
$entity = $args->getObject();
$changeSet = $this->getEntityChangeSet($entity, 'preUpdate');
if (!$changeSet && $method != 'DELETE')
return;
if ($method == 'DELETE') {
$message = array('action.delete', 'target:%s', 'id:%s');
$params = array($this->getEntityName(get_class($entity)), $entity->getName());
$body['message'] = $message;
$body['params'] = $params;
} else {
if ($this->request->request->get('deleted') === 'false' && $entity->getEliminado()) {
//dump($changeSet);die;
$message = array('action.restore', 'target:%s', 'id:%s', 'values:%s');
$params = array($this->getEntityName(get_class($entity)), $entity->getName(), $changeSet);
$body['message'] = $message;
$body['params'] = $params;
} else {
//dump($changeSet);die;
$message = array('action.update', 'target:%s', 'id:%s', 'values:%s');
$params = array($this->getEntityName(get_class($entity)), $entity->getName(), $changeSet);
$body['message'] = $message;
$body['params'] = $params;
}
}
$this->addEntryLog($body);
$this->log();
}
public function postPersist(LifecycleEventArgs $args)
{
if (!$this->isLog())
return;
$body = array();
$entity = $args->getObject();
$name = $this->getEntityName(get_class($entity));
if ($name == 'Log')
return;
$method = $this->request->getMethod();
if ($method == 'DELETE')
return;
$message = array('action.insert', 'target:%s', 'id:%s');
$params = array($this->getEntityName(get_class($entity)), $entity->getName());
$body['message'] = $message;
$body['params'] = $params;
$this->addEntryLog($body);
$this->log();
}
public function preRemove(LifecycleEventArgs $args)
{
if (!$this->isLog())
return;
$entity = $args->getObject();
$value = $this->generateObjectChangeSet($entity, $entity->getname(), 'preRemove');
$this->addEntityChangeSet($value);
}
public function postRemove(LifecycleEventArgs $args)
{
if (!$this->isLog())
return;
$body = array();
$entity = $args->getObject();
$changeSet = $this->getEntityChangeSet($entity, 'preRemove');
/*if (!$changeSet)
return;*/
$message = array('action.deletefromsystem', 'target:%s', 'id:%s');
$params = array($this->getEntityName(get_class($entity)), $entity->getname());
$body['message'] = $message;
$body['params'] = $params;
$this->addEntryLog($body);
$this->log();
}
/**
* @param mixed $request
*/
public function setRequest($request)
{
$this->request = $request->getCurrentRequest();
}
private function addEntryLog($entry)
{
$logEntry = $this->request->attributes->get('logEntry');
$logEntry['body'][] = $entry;
$this->request->attributes->set('logEntry', $logEntry);
$this->request->attributes->remove('entityChangeSet');
}
private function addEntityChangeSet($object)
{
$this->request->attributes->set('entityChangeSet', $object);
}
private function getEntityChangeSet($entity, $method)
{
$className = $this->getEntityName(get_class($entity));
$hashId = $this->hashId($className, $entity->getId(), $method);
$changeSetObj = $this->request->attributes->get('entityChangeSet');
if (!$changeSetObj)
return false;
$changeSetObjId = $changeSetObj['id'];
if ($changeSetObjId == $hashId)
return $changeSetObj;
return false;
}
private function checkIfUserRequest()
{
$token = $this->container->get('security.token_storage')->getToken();
if (!$token)
return false;
$user = $token->getUser();
if ($user instanceof UserInterface)
return true;
return false;
}
private function isLog()
{
try {
return $this->request->attributes->has('logEntry');
} catch (\ErrorException $e) {
return false;
}
}
private function getEm()
{
return $this->container->get('doctrine')->getEntityManager();
}
private function generateObjectChangeSet($entity, $changeSet, $method)
{
$className = get_class($entity);
$className = $this->getEntityName($className);
$id = $entity->getId();
$hash = $this->hashId($className, $id, $method);
$resp = array('id' => $hash, 'value' => $changeSet);
return $resp;
}
private function hashId($className, $id, $method)
{
$hash = $className . $id . $method;
return $hash;
}
private function getLogEntry()
{
if ($this->isLog())
$this->request->attributes->get('logEntry');
return false;
}
这适用于实体的简单值,例如名称地址等,但是当@manytoone或@manytomany带注释的属性发生更改时,例如,侦听器的preupdate方法不会触发。是否有这种属性的额外配置或我遗漏了什么?
答案
对于Collection,您可以使用:
$uow->getScheduledCollectionUpdates();
$uow->getScheduledCollectionDeletions();
如果它是PersistentCollection
,您可以检索原始数据:
$entity->getSnapshot()
以上是关于学说跟踪多个实体关系的变化的主要内容,如果未能解决你的问题,请参考以下文章