HistoriqueListener.php 4.56 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<?php

namespace UnicaenAuth\ORM\Event\Listeners;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;
use RuntimeException;
use UnicaenApp\Entity\HistoriqueAwareInterface;
use UnicaenAuth\Entity\Db\AbstractUser;
use Zend\Authentication\AuthenticationService;

/**
 * Listener Doctrine.
 *
 * Renseigne si besoin l'heure et l'auteur de la création/modification
 * de toute entité dont la classe implémente HistoriqueAwareInterface.
 *
 * Déclenchement : avant que l'enregistrement ne soit persisté (création) ou mis à jour (update).
 *
 * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
 * @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];
    }
}