I'm using Doctrine to save user data and I want to have a last modification
field.
Here is the pseudo-code for how I would like to save the form once the user presses Save
:
last updated
fieldThe problematic part is if anything will be changed by this transaction
. Can Doctrine give me such information?
How can I tell if entities have changed in the current transaction?
edit
Just to clear things up, I'm trying to modify a field called lastUpdated
in an entity called User
if any entity (including but not limited to User
) will be changed once the currect transaction is commited. In other words, if I start a transaction and modify the field called nbCars
of an entity called Garage
, I wish to update the lastUpdated
field of the User
entity even though that entity hasn't been modified.
It means the place where our data can be accessed from, a repository of data. This is to distinguish it from a database as a repository does not care how its data is stored.
Symfony provides all the tools you need to use databases in your applications thanks to Doctrine, the best set of PHP libraries to work with databases. These tools support relational databases like MySQL and PostgreSQL and also NoSQL databases like MongoDB.
The flush tag tells Twig to flush the output buffer: 1 {% flush %} Internally, Twig uses the PHP flush function. « filter | for » The Twig logo is © 2010-2022 Symfony.
This is a necessary reply that aims at correcting what @ColinMorelli posted (since flushing within an lifecycle event listener is disallowed - yes, there's one location in the docs that says otherwise, but we'll get rid of that, so please don't do it!).
You can simply listen to onFlush
with a listener like following:
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Events;
class UpdateUserEventSubscriber implements EventSubscriber
{
protected $user;
public function __construct(User $user)
{
// assuming the user is managed here
$this->user = $user;
}
public function onFlush(OnFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
// before you ask, `(bool) array()` with empty array is `false`
if (
$uow->getScheduledEntityInsertions()
|| $uow->getScheduledEntityUpdates()
|| $uow->getScheduledEntityDeletions()
|| $uow->getScheduledCollectionUpdates()
|| $uow->getScheduledCollectionDeletions()
) {
// update the user here
$this->user->setLastModifiedDate(new DateTime());
$uow->recomputeSingleEntityChangeSet(
$em->getClassMetadata(get_class($this->user)),
$this->user
);
}
}
public function getSubscribedEvents()
{
return array(Events::onFlush);
}
}
This will apply the change to the configured User
object only if the UnitOfWork
contains changes to be committed to the DB (an unit of work is actually what you could probably define as an application level state transaction).
You can register this subscriber with the ORM at any time by calling
$user = $entityManager->find('User', 123);
$eventManager = $entityManager->getEventManager();
$subscriber = new UpdateUserEventSubscriber($user);
$eventManager->addEventSubscriber($subscriber);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With