Completed
Push — master ( f47ecb...1c0a88 )
by Roni
14:50
created

EventResolverFactory::setImpersonatingUser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 2
1
<?php
2
3
/*
4
 * This file is part of the XiideaEasyAuditBundle package.
5
 *
6
 * (c) Xiidea <http://www.xiidea.net>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Xiidea\EasyAuditBundle\Resolver;
13
14
use Symfony\Component\EventDispatcher\Event;
15
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
16
use Symfony\Component\PropertyAccess\PropertyAccess;
17
use Xiidea\EasyAuditBundle\Common\UserAwareComponent;
18
use Xiidea\EasyAuditBundle\Entity\BaseAuditLog;
19
use Xiidea\EasyAuditBundle\Exception\InvalidServiceException;
20
use Xiidea\EasyAuditBundle\Exception\UnrecognizedEntityException;
21
use Xiidea\EasyAuditBundle\Exception\UnrecognizedEventInfoException;
22
23
class EventResolverFactory extends UserAwareComponent
24
{
25
    /**
26
     * @param Event $event
27
     * @param string $eventName
28
     * @return null|BaseAuditLog
29
     * @throws UnrecognizedEventInfoException
30
     * @throws \Exception
31
     */
32
    public function getEventLog(Event $event, $eventName)
33
    {
34
        $eventLog = $this->getEventLogObject($this->getEventLogInfo($event, $eventName));
35
36
        if ($eventLog === null) {
37
            return null;
38
        }
39
40
        $eventLog->setTypeId($eventName);
41
        $eventLog->setIp($this->getClientIp());
42
        $eventLog->setEventTime(new \DateTime());
43
        $this->setUser($eventLog);
44
45
        return $eventLog;
46
    }
47
48
    /**
49
     * @param $eventInfo
50
     *
51
     * @return null|BaseAuditLog
52
     * @throws UnrecognizedEventInfoException
53
     */
54
    protected function getEventLogObject($eventInfo)
55
    {
56
        if (empty($eventInfo)) {
57
            return null;
58
        }
59
60
        if ($eventInfo instanceof BaseAuditLog) {
61
            return $eventInfo;
62
        }
63
64
        return $this->createEventObjectFromArray($eventInfo);
65
    }
66
67
    /**
68
     * @param string $eventName
69
     *
70
     * @throws \Exception
71
     * @return EventResolverInterface
72
     */
73
    protected function getResolver($eventName)
74
    {
75
76
        if ($this->isEntityEvent($eventName)) {
77
            return $this->getEntityEventResolver();
78
        }
79
80
        $customResolvers = $this->getParameter('custom_resolvers');
81
82
        if (isset($customResolvers[$eventName])) {
83
            return $this->getCustomResolver($customResolvers[$eventName]);
84
        }
85
86
        return $this->getCommonResolver();
87
    }
88
89
    /**
90
     * @param string $eventName
91
     * @return bool
92
     */
93
    protected function isEntityEvent($eventName)
94
    {
95
        return in_array($eventName, $this->getDoctrineEventsList());
96
    }
97
98
    /**
99
     * @param Event $event
100
     * @param string $eventName
101
     * @return null
102
     * @throws InvalidServiceException
103
     */
104
    protected function getEventLogInfo(Event $event, $eventName)
105
    {
106
        if ($event instanceof EmbeddedEventResolverInterface) {
107
            return $event->getEventLogInfo($eventName);
108
        }
109
110
        if (null === $eventResolver = $this->getResolver($eventName)) {
111
            return null;
112
        }
113
114
        return $eventResolver->getEventLogInfo($event, $eventName);
115
    }
116
117
    /**
118
     * @param BaseAuditLog $entity
119
     * @throws \Exception
120
     */
121
    protected function setUser(BaseAuditLog $entity)
122
    {
123
        $userProperty = $this->container->getParameter('xiidea.easy_audit.user_property');
124
125
        if (null === $user = $this->getUser()) {
126
            $entity->setUser($this->getAnonymousUserName());
127
            return;
128
        }
129
130
        $entity->setUser($this->getSettablePropertyValue($userProperty, $user));
131
132
        $this->setImpersonatingUser($entity, $userProperty);
133
    }
134
135
136
    /**
137
     * @return string
138
     */
139
    protected function getClientIp()
140
    {
141
        $request = $this->getRequest();
142
        
143
        if ($request) {
144
            return $request->getClientIp();
145
        }
146
147
        return "";
148
    }
149
150
    /**
151
     * @return \Symfony\Component\DependencyInjection\ContainerInterface
152
     */
153
    protected function getContainer()
154
    {
155
        return $this->container;
156
    }
157
158
    /**
159
     * @return null
160
     * @throws InvalidServiceException
161
     */
162
    protected function handleInvalidResolverConfiguration()
163
    {
164
        if ($this->isDebug()) {
165
            throw new InvalidServiceException(
166
                'Resolver Service must implement' . __NAMESPACE__ . "EventResolverInterface"
167
            );
168
        }
169
170
        return null;
171
    }
172
173
    /**
174
     * @param $serviceName
175
     * @return null|EventResolverInterface
176
     * @throws InvalidServiceException
177
     */
178
    protected function getCustomResolver($serviceName)
179
    {
180
        $resolver = $this->getService($serviceName);
181
182
        if (!$resolver instanceof EventResolverInterface) {
183
            return $this->handleInvalidResolverConfiguration();
184
        }
185
186
        return $resolver;
187
    }
188
189
    /**
190
     * @param \Exception $e
191
     * @throws \Exception
192
     * @return null
193
     */
194
    protected function handleException(\Exception $e)
195
    {
196
        if ($this->isDebug()) {
197
            throw $e;
198
        }
199
200
        return null;
201
    }
202
203
    /**
204
     * @param $eventInfo
205
     * @return null|BaseAuditLog
206
     * @throws \Exception
207
     */
208
    protected function createEventObjectFromArray($eventInfo)
209
    {
210
        if (!is_array($eventInfo)) {
211
            return $this->handleException(new UnrecognizedEventInfoException());
212
        }
213
214
        $auditLogClass = $this->getParameter('entity_class');
215
        $eventObject = new $auditLogClass();
216
217
        if (!$eventObject instanceof BaseAuditLog) {
218
            return $this->handleException(new UnrecognizedEntityException());
219
        }
220
221
        return $eventObject->fromArray($eventInfo);
222
    }
223
224
    /**
225
     * @param $userProperty
226
     * @param $user
227
     * @return mixed
228
     */
229
    protected function getSettablePropertyValue($userProperty, $user)
230
    {
231
        if (empty($userProperty)) {
232
            return $user;
233
        }
234
235
        try {
236
            $propertyAccessor = PropertyAccess::createPropertyAccessor();
237
            return $propertyAccessor->getValue($user, $userProperty);
238
        } catch (NoSuchPropertyException $e) {
239
            return $this->handleException($e);
240
        }
241
    }
242
243
    /**
244
     * @param BaseAuditLog $entity
245
     * @param $userProperty
246
     */
247
    protected function setImpersonatingUser(BaseAuditLog $entity, $userProperty)
248
    {
249
        if (null !== $user = $this->getImpersonatingUser()) {
250
            $entity->setImpersonatingUser($this->getSettablePropertyValue($userProperty, $user));
251
        }
252
    }
253
}
254