michal
michal

Reputation: 428

Doctrine onFlush - catch entity changed fields

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

Answers (2)

michal
michal

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

Gaylord.P
Gaylord.P

Reputation: 1468

For PersistentCollection entities, use getSnapshot() for get originals data :)

http://www.doctrine-project.org/api/orm/2.3/class-Doctrine.ORM.PersistentCollection.html#_getSnapshot

Upvotes: 1

Related Questions