diff --git a/config/module.config.php b/config/module.config.php index 14419ef267ad94a699a62d6b01505ca5ec7c71bf..e031665b4a57ee2e64430bff0aad0f6bb931c541 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -9,6 +9,7 @@ use UnicaenAuth\Controller\UtilisateurControllerFactory; use UnicaenAuth\Form\Droits\RoleFormFactory; use UnicaenAuth\Guard\PrivilegeControllerFactory; use UnicaenAuth\Guard\PrivilegeRouteFactory; +use UnicaenAuth\ORM\Event\Listeners\HistoriqueListenerFactory; use UnicaenAuth\Provider\Rule\PrivilegeRuleProviderFactory; use UnicaenAuth\Service\ShibService; use UnicaenAuth\Service\ShibServiceFactory; @@ -490,6 +491,9 @@ return [ 'UnicaenAuth\Guard\PrivilegeController' => PrivilegeControllerFactory::class, 'UnicaenAuth\Guard\PrivilegeRoute' => PrivilegeRouteFactory::class, 'UnicaenAuth\Provider\Rule\PrivilegeRuleProvider' => PrivilegeRuleProviderFactory::class, + + 'UnicaenApp\HistoriqueListener' => HistoriqueListenerFactory::class, + 'UnicaenAuth\HistoriqueListener' => HistoriqueListenerFactory::class, ], 'lazy_services' => [ // Mapping services to their class names is required since the ServiceManager is not a declarative DIC. diff --git a/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListener.php b/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListener.php new file mode 100644 index 0000000000000000000000000000000000000000..36b3a979c47ee7da186044f3e82c12e15abdbdcc --- /dev/null +++ b/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListener.php @@ -0,0 +1,166 @@ + + * @see HistoriqueAwareInterface + */ +class HistoriqueListener implements EventSubscriber +{ + /** + * @var AuthenticationService + */ + private $authenticationService; + + /** + * @var mixed + */ + protected $identity; + + /** + * @param AuthenticationService $authenticationService + */ + public function setAuthenticationService(AuthenticationService $authenticationService) + { + $this->authenticationService = $authenticationService; + } + + /** + * @param LifecycleEventArgs $args + * @throws RuntimeException Aucun utilisateur disponible pour en faire l'auteur de la création/modification + */ + protected function updateHistorique(LifecycleEventArgs $args) + { + $entity = $args->getEntity(); + + // l'entité doit implémenter l'interface requise + if (! $entity instanceof HistoriqueAwareInterface) { + return; + } + + $now = new \DateTime(); + + if (null === $entity->getHistoCreation()) { + $entity->setHistoCreation($now); + } + + // on tente d'abord d'obtenir l'utilisateur connecté pour en faire l'auteur de la création/modification. + $user = $this->getAuthenticatedUser(); + // si aucun utilisateur connecté n'est disponible, on utilise l'éventuel auteur existant + if (null === $user) { + $user = $entity->getHistoCreateur(); + } + // si nous ne disposons d'aucun utilisateur, basta! + if (null === $user) { + throw new RuntimeException("Aucun utilisateur disponible pour en faire l'auteur de la création/modification."); + } + + if (null === $entity->getHistoCreateur()) { + $entity->setHistoCreateur($user); + } + + $entity->setHistoModificateur($user); + $entity->setHistoModification($now); + /* ce bloc a été mis en commentaire car il est inutile: cf. 2 lignes précédentes ! + if (null === $entity->getHistoDestruction() && null === $entity->getHistoDestructeur()) { + $entity + ->setHistoModification($now) + ->setHistoModificateur($user); + } + */ + + if (null !== $entity->getHistoDestruction() && null === $entity->getHistoDestructeur()) { + $entity->setHistoDestructeur($user); + } + } + + /** + * Recherche l'utilisateur connecté pour l'utiliser comme auteur de la création/modification. + * + * @return AbstractUser + */ + private function getAuthenticatedUser() + { + $user = null; + + if (($identity = $this->getIdentity())) { + if (isset($identity['db']) && $identity['db'] instanceof AbstractUser) { + /* @var $user AbstractUser */ + $user = $identity['db']; + } + } + + return $user; + } + + /** + * @param LifecycleEventArgs $args + */ + public function prePersist(LifecycleEventArgs $args) + { + $this->updateHistorique($args); + } + + /** + * @param PreUpdateEventArgs $args + */ + public function preUpdate(PreUpdateEventArgs $args) + { + $this->updateHistorique($args); + } + + /** + * Injecte l'identité authentifiée courante. + * + * @param mixed $identity + * @return self + */ + public function setIdentity($identity) + { + $this->identity = $identity; + + return $this; + } + + /** + * Retourne l'identité authentifiée courante. + * + * @return mixed + */ + public function getIdentity() + { + if (null === $this->identity) { + $authenticationService = $this->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 diff --git a/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListenerFactory.php b/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListenerFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..c35c5e5bbfba86bce8e9755e540de6e984abd832 --- /dev/null +++ b/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListenerFactory.php @@ -0,0 +1,32 @@ + + */ +class HistoriqueListenerFactory implements FactoryInterface +{ + public function createService(ServiceLocatorInterface $serviceLocator) + { + return $this->__invoke($serviceLocator, '?'); + } + + public function __invoke(ContainerInterface $container, $requestedName, array $options = null) + { + /** @var AuthenticationService $authenticationService */ + $authenticationService = $container->get('Zend\Authentication\AuthenticationService'); + + $listener = new HistoriqueListener(); + $listener->setAuthenticationService($authenticationService); + + return $listener; + } +}