EasyAdminBundle
EasyAdminBundle copied to clipboard
How to get the original entity before updating using BeforeEntityUpdatedEvent ?
Hi,
I use the event BeforeEntityUpdatedEvent in order to detect changes with the entity before and after been updated.
However, using this code, I only be able to retrieve the entity updated even if the entity is not persist and flush yet...
public function onBeforeEntityUpdated(BeforeEntityUpdatedEvent $event): void
{
// EasyAdmin before EDIT action
$entity = $event->getEntityInstance();
\dump($entity);
die();
}
Can you help me ?
Thanks,
Hi,
If you use Doctrine with entities, these informations are easily to determined :
$uow = $this->em->getUnitOfWork(); $uow->computeChangeSets(); $changeset = $uow->getEntityChangeSet($entity);The changeset result is an array with all fields who have changed with old and new value.
If you use collections, you need to check the changeset for each row.
<?php
/**
* Permet différentes vérifications sur une entité
*
*/
namespace App\Services;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\UnitOfWork;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
class EntityCheckService
{
/**
* em
*
* @var EntityManagerInterface
*/
private $em;
/**
* Construct
*
* @param EntityManagerInterface $entityManagerInterface
*/
public function __construct(EntityManagerInterface $entityManagerInterface)
{
$this->em = $entityManagerInterface;
}
/**
* Retourne TRUE si l'entité a été modifiée, sinon FALSE
*
* @param Object $entity
* @return boolean
*/
public function hasBeenChanged(Object $entity): bool
{
$uow = $this->em->getUnitOfWork();
$uow->computeChangeSets();
// pour tester les collections
$doctrineExtractor = new DoctrineExtractor($this->em);
$propertyInfo = new PropertyInfoExtractor([$doctrineExtractor], [$doctrineExtractor]);
return $this->recursiveHasBeenChanged($uow, $propertyInfo, $entity);
}
/**
* Test recursif des collections
* Retourne TRUE si l'entité a été modifiée, sinon FALSE
*
* @param UnitOfWork $uow
* @param PropertyInfoExtractor $propertyInfo
* @param Object $entity
* @return boolean
*/
private function recursiveHasBeenChanged(UnitOfWork $uow, PropertyInfoExtractor $propertyInfo, Object $entity): bool
{
if ($uow->isScheduledForUpdate($entity)) {
$uow->commit();
return true;
}
// on test les collections
// on récupère la liste et les types des propriétés
$properties = $propertyInfo->getProperties($entity::class);
// on boucle les propriétés
foreach ($properties as $property) {
$propertyType = $propertyInfo->getTypes($entity::class, $property);
if (empty($propertyType))
continue;
$type = $propertyType[0];
// si ce n'est pas une collection on continue de boucler
if (!$type->isCollection())
continue;
// le champ est une collection
// si la méthode n'existe pas on continue de boucler
$method = 'get' . ucfirst($property);
if (!method_exists($entity, $method))
continue;
// on test si des lignes sont supprimées
$collection = $entity->$method();
if (!empty($collection->getDeleteDiff()))
return true;
// on test les lignes de la collection
foreach ($collection as $value) {
// on test la ligne
if ($uow->isScheduledForUpdate($value) || $uow->isScheduledForInsert($value)) {
$uow->commit();
return true;
}
// test récursif, si collections dans collections
if ($this->recursiveHasBeenChanged($uow, $propertyInfo, $value))
return true;
}
}
return false;
}
}