Doctrine2 entity changeset for relations

Doctrine2 offers very powerful API for getting entity properties that have changed. This can be achieved using Doctrine\ORM\UnitOfWork. We can call:

  • Doctrine\ORM\UnitOfWork::computeChangeSets() to compute all the changes that have been done to entities and collections and store these changes;
  • Doctrine\ORM\UnitOfWork::getEntityChangeSet($entity) to retrieve all changes to our entity object;
  • Doctrine\ORM\UnitOfWork::getOriginalEntityData($entity) to retrieve the original data of an entity before introduced changes.

This simple example will explain it:

But what about relations? While working with Doctrine2 relations we are dealing with Doctrine\ORM\PersistentCollection which also has some useful public methods:

  • Doctrine\ORM\PersistentCollection::getSnapshot to return the last snapshot of the elements in the collection;
  • Doctrine\ORM\PersistentCollection::getDeleteDiff to return removed entities from the collection;
  • Doctrine\ORM\PersistentCollection::getInsertDiff to return new entities thast have been added to the collection;
  • Doctrine\ORM\PersistentCollection::isDirty to check whether this collection is dirty which means its state needs to be synchronized with the database.

Those methods are marked in doc as INTERNAL but have public access.

Usage:

This is very useful when you are auditing your entities and you want to know how your entities relations are changing, for example while adding / removing Post->tags or User->roles. We don’t need to store whole entities state because this should be audited separately but we can store its ids. In my case solution that I needed was:

To store something like:

I hope this will be useful as lately I was looking for similar solution for Doctrine2 relations.