Reputation: 428
I need to store all changed field in logs when user change something in Product Entity.
I have event subscriber which works fine. I have two methods. Onflush and postFlush.
In onFlush method I have simply this:
public function onFlush(OnFlushEventArgs $args): void
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $key => $entity) {
if ($entity instanceof Product) {
$this->entitiesToProcess[] = $entity;
}
}
/**
* @var PersistentCollection $entity
*/
foreach ($uow->getScheduledCollectionUpdates() as $entity) {
foreach ($entity as $relationEntity) {
if ($relationEntity instanceof Product) {
$this->collectionToProcess[] = $entity;
}
}
}
}
in entitiesToProcess
I store simple field changes, and on collectionToProcess
I store my collection changes. But the weird thing is that my ManyToMany changes is in getScheduledEntityUpdates
where ManyToOne are stored in collectionToProcess
In postFlush method where I search my collectionToProcess request I have changed entities but I also have a problem.
In ManyToOne I have old and new values, but in ManyToMany I don't. I only have updated state. So I have those notices also when I don't update this field.
In another ManyToMany collection - my collection form of entity I have those values in getScheduledEntityUpdates
instead of getScheduledCollectionUpdates
which I don't understand why.
How can I catch ManyToMany relation changes ?
I tried to do this in simple way also in controller
$basedEntity = $product;
$command = new ProductEditCommand($product);
$form = $this->createForm(ProductEditType::class, $command)->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->commandBus->handle($command);
var_dump($basedEntity->getName());
var_dump(count($basedEntity->getTags()));
var_dump(count($basedEntity->getFilters()));
die("!");
}
and whats weird. Name of the product is the old one - so before any changes. But relations like Tags or Filters are updated. How can I fetch related association from before changes ? f
Upvotes: 0
Views: 1695
Reputation: 428
You give me correct direction. I use getDeletedDiff and getInsertedDiff on getScheduledCollectionUpdates event. But I have a problem when I have form with values and then I perform action and remove them (collection is empty). I don't have them in getScheduledCollectionUpdates or even getScheduledCollectionDeletions. I just can't fetch removed collection
This is my onFlush method for collection:
public function onFlush(OnFlushEventArgs $args): void
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledCollectionUpdates() as $key => $entity) {
if ($entity->getOwner() instanceof Product) {
if ($entity->getTypeClass()->getName() === 'App\Entity\Tag') {
if ($entity->isDirty()) {
$this->collectionToProcess[] = [
'type' => 'tags',
'old' => $this->fetchManyToManyRelation($entity->getInsertDiff()),
'new' => $this->fetchManyToManyRelation($entity->getDeleteDiff()),
];
}
}
}
}
}
And one more thing. One ManyToMany inversed side of relation Snapshot is always empty, the same as getDeleteDiff - only getInstertedDiff shown always actually data in form. So if I have one collection and add another I will have two collections in getInstertedDiff. If I had one relation and didn't add anyting - I still have one collection in getInsertedDiff instead of 0.
Upvotes: 0
Reputation: 1468
For PersistentCollection entities, use getSnapshot() for get originals data :)
Upvotes: 1