Skip to content

Instantly share code, notes, and snippets.

@imiroslavov
Created July 30, 2019 08:32
Show Gist options
  • Save imiroslavov/75cd523f22b8d22ee3e397a094b881ed to your computer and use it in GitHub Desktop.
Save imiroslavov/75cd523f22b8d22ee3e397a094b881ed to your computer and use it in GitHub Desktop.
<?php
namespace App\Utils;
/**
* Class ClassAnalyzer.
*/
class ClassAnalyzer
{
/**
* @param \ReflectionClass $class
* @param string $traitName
*
* @return bool
*/
public static function hasTrait(\ReflectionClass $class, $traitName)
{
return \in_array($traitName, $class->getTraitNames(), true);
}
}
services:
App\Doctrine\EventSubscriber\TimestampableEntityEventSubscriber:
tags:
- { name: doctrine.event_subscriber }
<?php
namespace App\Doctrine\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Trait TimestampableEntity.
*/
trait TimestampableEntity
{
/**
* @var \DateTime
*
* @ORM\Column(name="created_at", type="datetime")
*/
protected $createdAt;
/**
* @var \DateTime
*
* @ORM\Column(name="updated_at", type="datetime")
*/
protected $updatedAt;
/**
* @param \DateTime $createdAt
*
* @return $this
*/
public function setCreatedAt(?\DateTime $createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return \DateTime
*/
public function getCreatedAt(): ?\DateTime
{
return $this->createdAt;
}
/**
* @param \DateTime $updatedAt
*
* @return $this
*/
public function setUpdatedAt(?\DateTime $updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return \DateTime
*/
public function getUpdatedAt(): ?\DateTime
{
return $this->updatedAt;
}
}
<?php
namespace App\Doctrine\EventSubscriber;
use App\Doctrine\Entity\TimestampableEntity;
use App\Utils\ClassAnalyzer;
use Doctrine\Common\Annotations\Reader;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadata;
/**
* Class TimestampableEntityEventSubscriber.
*/
class TimestampableEntityEventSubscriber implements EventSubscriber
{
/**
* @var Reader
*/
protected $annotationReader;
/**
* TimestampableEntityEventSubscriber constructor.
*
* @param Reader $annotationReader
*/
public function __construct(Reader $annotationReader)
{
$this->annotationReader = $annotationReader;
}
/**
* @return array
*/
public function getSubscribedEvents(): array
{
return [
Events::prePersist,
Events::preUpdate,
];
}
/**
* @param LifecycleEventArgs $args
*
* @throws \Exception
*/
public function prePersist(LifecycleEventArgs $args)
{
/** @var TimestampableEntity $entity */
$entity = $args->getEntity();
if (ClassAnalyzer::hasTrait($args->getEntityManager()->getClassMetadata(\get_class($entity))->reflClass, TimestampableEntity::class)) {
$date = new \DateTime();
$entity->setCreatedAt($date);
$entity->setUpdatedAt($date);
}
}
/**
* @param LifecycleEventArgs $args
*
* @throws \Exception
*/
public function preUpdate(LifecycleEventArgs $args)
{
/** @var TimestampableEntity $entity */
$entity = $args->getEntity();
/** @var EntityManagerInterface $entityManager */
$entityManager = $args->getEntityManager();
/** @var ClassMetadata $classMetadata */
$classMetadata = $entityManager->getClassMetadata(\get_class($entity));
if (ClassAnalyzer::hasTrait($classMetadata->reflClass, TimestampableEntity::class)) {
$entity->setUpdatedAt(new \DateTime());
$entityManager->getUnitOfWork()->recomputeSingleEntityChangeSet($classMetadata, $entity);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment