diff --git a/config/module.config.php b/config/module.config.php index 52bb5adb7911c2fb75e58d05d7a48498a20c4e43..b9d90a906da48a026e2eeb41b41a3907d7b67a84 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -158,6 +158,9 @@ return array( 'MessageCollector' => 'UnicaenApp\Service\MessageCollectorFactory', ), + 'invokables' => [ + 'UnicaenApp\HistoriqueListener' => 'UnicaenApp\ORM\Event\Listeners\HistoriqueListener' + ], 'abstract_factories' => array( 'UnicaenApp\Service\Doctrine\MultipleDbAbstractFactory', ), diff --git a/src/UnicaenApp/Entity/HistoriqueAwareInterface.php b/src/UnicaenApp/Entity/HistoriqueAwareInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..b727903fcf9d64194a46075b598555fa967575bb --- /dev/null +++ b/src/UnicaenApp/Entity/HistoriqueAwareInterface.php @@ -0,0 +1,102 @@ +<?php + +namespace UnicaenApp\Entity; +use UnicaenAuth\Entity\Db\AbstractUser; + +/** + * Interface des entités possédant une gestion d'historique. + * + * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr> + */ +interface HistoriqueAwareInterface +{ + /** + * Set histoCreation + * + * @param \DateTime $histoCreation + * @return self + */ + public function setHistoCreation($histoCreation); + + /** + * Get histoCreation + * + * @return \DateTime + */ + public function getHistoCreation(); + + /** + * Set histoDestruction + * + * @param \DateTime $histoDestruction + * @return self + */ + public function setHistoDestruction($histoDestruction); + + /** + * Get histoDestruction + * + * @return \DateTime + */ + public function getHistoDestruction(); + + /** + * Set histoModification + * + * @param \DateTime $histoModification + * @return self + */ + public function setHistoModification($histoModification); + + /** + * Get histoModification + * + * @return \DateTime + */ + public function getHistoModification(); + + /** + * Set histoModificateur + * + * @param AbstractUser $histoModificateur + * @return self + */ + public function setHistoModificateur(AbstractUser $histoModificateur = null); + + /** + * Get histoModificateur + * + * @return AbstractUser + */ + public function getHistoModificateur(); + + /** + * Set histoDestructeur + * + * @param AbstractUser $histoDestructeur + * @return self + */ + public function setHistoDestructeur(AbstractUser $histoDestructeur = null); + + /** + * Get histoDestructeur + * + * @return AbstractUser + */ + public function getHistoDestructeur(); + + /** + * Set histoCreateur + * + * @param AbstractUser $histoCreateur + * @return self + */ + public function setHistoCreateur(AbstractUser $histoCreateur = null); + + /** + * Get histoCreateur + * + * @return AbstractUser + */ + public function getHistoCreateur(); +} \ No newline at end of file diff --git a/src/UnicaenApp/Entity/HistoriqueAwareTrait.php b/src/UnicaenApp/Entity/HistoriqueAwareTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..404a39fdb99760239441411016605408bb7a9ac8 --- /dev/null +++ b/src/UnicaenApp/Entity/HistoriqueAwareTrait.php @@ -0,0 +1,249 @@ +<?php + +namespace UnicaenApp\Entity; + +use Common\Constants; +use UnicaenAuth\Entity\Db\AbstractUser; + +/** + * Code commun aux entités possédant une gestion d'historique. + * + * @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr> + */ +trait HistoriqueAwareTrait +{ + /** + * @var \DateTime + */ + protected $histoCreation; + + /** + * @var \DateTime + */ + protected $histoModification; + + /** + * @var \DateTime + */ + protected $histoDestruction; + + /** + * @var AbstractUser + */ + protected $histoCreateur; + + /** + * @var AbstractUser + */ + protected $histoModificateur; + + /** + * @var AbstractUser + */ + protected $histoDestructeur; + + + + /** + * Set histoCreation + * + * @param \DateTime $histoCreation + * + * @return self + */ + public function setHistoCreation($histoCreation) + { + $this->histoCreation = $histoCreation; + + return $this; + } + + + + /** + * Get histoCreation + * + * @return \DateTime + */ + public function getHistoCreation() + { + return $this->histoCreation; + } + + + + /** + * Set histoDestruction + * + * @param \DateTime $histoDestruction + * + * @return self + */ + public function setHistoDestruction($histoDestruction) + { + $this->histoDestruction = $histoDestruction; + + return $this; + } + + + + /** + * Get histoDestruction + * + * @return \DateTime + */ + public function getHistoDestruction() + { + return $this->histoDestruction; + } + + + + /** + * Set histoModification + * + * @param \DateTime $histoModification + * + * @return self + */ + public function setHistoModification($histoModification) + { + $this->histoModification = $histoModification; + + return $this; + } + + + + /** + * Get histoModification + * + * @return \DateTime + */ + public function getHistoModification() + { + return $this->histoModification; + } + + + + /** + * Retourne la date et l'auteur de la dernière modification au format "Le dd/mm/yyyy à hh:mm par Tartanpion". + * + * @return string + */ + public function getHistoModificationEtModificateurToString() + { + $dateModif = $this->getHistoModification() ? $this->getHistoModification()->format(Constants::DATETIME_FORMAT) : null; + return sprintf("Le %s par %s", $dateModif, $this->getHistoModificateur()); + } + + + + /** + * Set histoModificateur + * + * @param AbstractUser $histoModificateur + * + * @return self + */ + public function setHistoModificateur(AbstractUser $histoModificateur = null) + { + $this->histoModificateur = $histoModificateur; + + return $this; + } + + + + /** + * Get histoModificateur + * + * @return AbstractUser + */ + public function getHistoModificateur() + { + return $this->histoModificateur; + } + + + + /** + * Set histoDestructeur + * + * @param AbstractUser $histoDestructeur + * + * @return self + */ + public function setHistoDestructeur(AbstractUser $histoDestructeur = null) + { + $this->histoDestructeur = $histoDestructeur; + + return $this; + } + + + + /** + * Get histoDestructeur + * + * @return AbstractUser + */ + public function getHistoDestructeur() + { + return $this->histoDestructeur; + } + + + + /** + * Set histoCreateur + * + * @param AbstractUser $histoCreateur + * + * @return self + */ + public function setHistoCreateur(AbstractUser $histoCreateur = null) + { + $this->histoCreateur = $histoCreateur; + + return $this; + } + + + + /** + * Get histoCreateur + * + * @return AbstractUser + */ + public function getHistoCreateur() + { + return $this->histoCreateur; + } + + + + /** + * Détermine si l'entité est historisée ou non + * + * @param \DateTime|null $dateObs + * + * @return bool + */ + public function estNonHistorise(\DateTime $dateObs = null) + { + if (empty($dateObs)) $dateObs = new \DateTime(); + + + $dObs = $dateObs->format('Y-m-d'); + $dDeb = $this->getHistoCreation() ? $this->getHistoCreation()->format('Y-m-d') : null; + $dFin = $this->getHistoDestruction() ? $this->getHistoDestruction()->format('Y-m-d') : null; + + if ($dDeb && !($dDeb <= $dObs)) return false; + if ($dFin && !($dObs < $dFin)) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/UnicaenApp/ORM/Event/Listeners/HistoriqueListener.php b/src/UnicaenApp/ORM/Event/Listeners/HistoriqueListener.php new file mode 100644 index 0000000000000000000000000000000000000000..4df96d9d835362c7adaffaac164acac60f84b46c --- /dev/null +++ b/src/UnicaenApp/ORM/Event/Listeners/HistoriqueListener.php @@ -0,0 +1,151 @@ +<?php +namespace UnicaenApp\ORM\Event\Listeners; + +use UnicaenAuth\Entity\Db\AbstractUser; +use Zend\ServiceManager\ServiceLocatorAwareInterface; +use Zend\ServiceManager\ServiceLocatorAwareTrait; +use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\Event\PreUpdateEventArgs; +use Doctrine\ORM\Events; +use Doctrine\Common\EventSubscriber; +use Common\Exception\RuntimeException; +use UnicaenApp\Entity\HistoriqueAwareInterface; + +/** + * Listener Doctrine permettant l'ajout automatique de l'heure de création/modification + * et de l'auteur de création/modification de toute entité avant qu'elle soit persistée. + * + * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr> + */ +class HistoriqueListener implements EventSubscriber, ServiceLocatorAwareInterface +{ + use ServiceLocatorAwareTrait; + + /** + * @var mixed + */ + protected $identity; + + + + /** + * + * @param LifecycleEventArgs $args + * + * @return type + * @throws RuntimeException + */ + protected function updateHistorique(LifecycleEventArgs $args) + { + $em = $args->getEntityManager(); + $entity = $args->getEntity(); + $user = null; + + // l'entité doit implémenter l'interface requise + if (!$entity instanceof HistoriqueAwareInterface) { + return; + } + /* @var $entity \UnicaenApp\Entity\HistoriqueAwareInterface */ + + // l'utilisateur connecté sera l'auteur de la création/modification + if (($identity = $this->getIdentity())) { + if (isset($identity['db']) && $identity['db'] instanceof AbstractUser) { + $user = $identity['db']; + /* @var $user AbstractUser */ + } + } + + if (null === $user) { + throw new RuntimeException("Aucun utilisateur connecté disponible pour la gestion de l'historique."); + } + + $now = new \DateTime(); + + /** + * Historique + */ + + if (null === $entity->getHistoCreation()) { + $entity->setHistoCreation($now); + } + + if (null === $entity->getHistoCreateur()) { + $entity->setHistoCreateur($user); + } + + $entity->setHistoModificateur($user); + $entity->setHistoModification($now); + + if (null === $entity->getHistoDestruction() && null === $entity->getHistoDestructeur()) { + $entity->setHistoModification($now) + ->setHistoModificateur($user); + } + + if (null !== $entity->getHistoDestruction() && null === $entity->getHistoDestructeur()) { + $entity->setHistoDestructeur($user); + } + } + + + + /** + * @param LifecycleEventArgs $args + */ + public function prePersist(LifecycleEventArgs $args) + { + $this->updateHistorique($args); + } + + + + /** + * @param PreUpdateEventArgs $args + */ + public function preUpdate(PreUpdateEventArgs $args) + { + $this->updateHistorique($args); + } + + + + /** + * + * @param mixed $identity + * + * @return \Common\ORM\Event\Listeners\Histo + */ + public function setIdentity($identity) + { + $this->identity = $identity; + + return $this; + } + + + + /** + * + * @return mixed + */ + public function getIdentity() + { + if (null === $this->identity) { + $authenticationService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService'); + if ($authenticationService->hasIdentity()) { + $this->identity = $authenticationService->getIdentity(); + } + } + + return $this->identity; + } + + + + /** + * {@inheritdoc} + */ + public function getSubscribedEvents() + { + return [Events::prePersist, Events::preUpdate]; + } +} \ No newline at end of file