Completed
Push — master ( e9e666...e79deb )
by Roni
01:22
created

EventResolverFactory::isDebug()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\Events\DoctrineEvents;
20
use Xiidea\EasyAuditBundle\Exception\InvalidServiceException;
21
use Xiidea\EasyAuditBundle\Exception\UnrecognizedEntityException;
22
use Xiidea\EasyAuditBundle\Exception\UnrecognizedEventInfoException;
23
24
class EventResolverFactory extends UserAwareComponent
25
{
26
    private $customResolvers = array();
27
    private $commonResolver;
28
29
    /**
30
     * @var EventResolverInterface
31
     */
32
    private $entityEventResolver;
33
34
    private $resolverEventMap = array();
35
36
    private $debug = false;
37
    private $userProperty;
38
    private $entityClass;
39
40
    /**
41
     * EventResolverFactory constructor.
42
     *
43
     * @param array $resolverEventMap
44
     * @param $userProperty
45
     * @param $entityClass
46
     */
47
    public function __construct(array $resolverEventMap = array(), $userProperty = 'username', $entityClass = BaseAuditLog::class)
48
    {
49
        $this->resolverEventMap = $resolverEventMap;
50
        $this->userProperty = $userProperty;
51
        $this->entityClass = $entityClass;
52
    }
53
54
    /**
55
     * @param Event $event
56
     * @param string $eventName
57
     * @return null|BaseAuditLog
58
     * @throws UnrecognizedEventInfoException
59
     * @throws \Exception
60
     */
61
    public function getEventLog(Event $event, $eventName)
62
    {
63
        $eventLog = $this->getEventLogObject($this->getEventLogInfo($event, $eventName));
64
65
        if ($eventLog === null) {
66
            return null;
67
        }
68
69
        $eventLog->setTypeId($eventName);
70
        $eventLog->setIp($this->getClientIp());
71
        $eventLog->setEventTime(new \DateTime());
72
        $this->setUser($eventLog);
73
74
        return $eventLog;
75
    }
76
77
    /**
78
     * @param $eventInfo
79
     *
80
     * @return null|BaseAuditLog
81
     * @throws UnrecognizedEventInfoException
82
     * @throws \Exception
83
     */
84
    protected function getEventLogObject($eventInfo)
85
    {
86
        if (empty($eventInfo)) {
87
            return null;
88
        }
89
90
        if ($eventInfo instanceof BaseAuditLog) {
91
            return $eventInfo;
92
        }
93
94
        return $this->createEventObjectFromArray($eventInfo);
95
    }
96
97
    /**
98
     * @param string $eventName
99
     *
100
     * @return EventResolverInterface
101
     */
102
    protected function getResolver($eventName)
103
    {
104
105
        if ($this->isEntityEvent($eventName)) {
106
            return $this->entityEventResolver;
107
        }
108
109
110
        if (isset($this->resolverEventMap[$eventName]) && isset($this->customResolvers[$this->resolverEventMap[$eventName]])) {
111
            return $this->customResolvers[$this->resolverEventMap[$eventName]];
112
        }
113
114
        return $this->commonResolver;
115
    }
116
117
    /**
118
     * @param string $eventName
119
     * @return bool
120
     */
121
    protected function isEntityEvent($eventName)
122
    {
123
        return in_array($eventName, DoctrineEvents::getConstants());
124
    }
125
126
    /**
127
     * @param Event $event
128
     * @param string $eventName
129
     * @return null
130
     * @throws InvalidServiceException
131
     */
132
    protected function getEventLogInfo(Event $event, $eventName)
133
    {
134
        if ($event instanceof EmbeddedEventResolverInterface) {
135
            return $event->getEventLogInfo($eventName);
136
        }
137
138
        if (null === $eventResolver = $this->getResolver($eventName)) {
139
            return null;
140
        }
141
142
        return $eventResolver->getEventLogInfo($event, $eventName);
143
    }
144
145
    /**
146
     * @param BaseAuditLog $entity
147
     * @throws \Exception
148
     */
149
    protected function setUser(BaseAuditLog $entity)
150
    {
151
        if (null === $user = $this->getUser()) {
152
            $entity->setUser($this->getAnonymousUserName());
153
            return;
154
        }
155
156
        $entity->setUser($this->getSettablePropertyValue($this->userProperty, $user));
157
158
        $this->setImpersonatingUser($entity, $this->userProperty);
159
    }
160
161
162
    /**
163
     * @return string
164
     */
165
    protected function getClientIp()
166
    {
167
        $request = $this->getRequest();
168
169
        if ($request) {
170
            return $request->getClientIp();
171
        }
172
173
        return "";
174
    }
175
176
    /**
177
     * @param $id
178
     * @param EventResolverInterface $resolver
179
     *
180
     * @throws \Exception|InvalidServiceException
181
     */
182 View Code Duplication
    public function addCustomResolver($id, $resolver)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
183
    {
184
        if (!$resolver instanceof EventResolverInterface) {
185
            $this->handleException(new InvalidServiceException(
186
                'Resolver Service must implement' . EventResolverInterface::class
187
            ));
188
189
            return;
190
        }
191
192
        $this->customResolvers[$id] = $resolver;
193
    }
194
195
    /**
196
     * @param mixed $resolver
197
     *
198
     * @throws \Exception
199
     */
200 View Code Duplication
    public function setCommonResolver($resolver)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
201
    {
202
        if (!$resolver instanceof EventResolverInterface) {
203
            $this->commonResolver = $this->handleException(new InvalidServiceException(
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $this->commonResolver is correct as $this->handleException(n...olverInterface::class)) (which targets Xiidea\EasyAuditBundle\R...tory::handleException()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
204
                'Resolver Service must implement' . EventResolverInterface::class
205
            ));
206
207
            return;
208
        }
209
210
        $this->commonResolver = $resolver;
211
    }
212
213
214
    /**
215
     * @param \Exception $e
216
     * @throws \Exception
217
     * @return null
218
     */
219
    protected function handleException(\Exception $e)
220
    {
221
        if ($this->isDebug()) {
222
            throw $e;
223
        }
224
225
        return null;
226
    }
227
228
    /**
229
     * @param $eventInfo
230
     * @return null|BaseAuditLog
231
     * @throws \Exception
232
     */
233
    protected function createEventObjectFromArray($eventInfo)
234
    {
235
        if (!is_array($eventInfo)) {
236
            return $this->handleException(new UnrecognizedEventInfoException());
237
        }
238
239
        $auditLogClass = $this->entityClass;
240
        $eventObject = new $auditLogClass();
241
242
        if (!$eventObject instanceof BaseAuditLog) {
243
            return $this->handleException(new UnrecognizedEntityException());
244
        }
245
246
        return $eventObject->fromArray($eventInfo);
247
    }
248
249
    /**
250
     * @param $userProperty
251
     * @param $user
252
     * @return mixed
253
     */
254
    protected function getSettablePropertyValue($userProperty, $user)
255
    {
256
        if (empty($userProperty)) {
257
            return $user;
258
        }
259
260
        try {
261
            $propertyAccessor = PropertyAccess::createPropertyAccessor();
262
            return $propertyAccessor->getValue($user, $userProperty);
263
        } catch (NoSuchPropertyException $e) {
264
            return $this->handleException($e);
265
        }
266
    }
267
268
    /**
269
     * @param BaseAuditLog $entity
270
     * @param $userProperty
271
     */
272
    protected function setImpersonatingUser(BaseAuditLog $entity, $userProperty)
273
    {
274
        if (null !== $user = $this->getImpersonatingUser()) {
275
            $entity->setImpersonatingUser($this->getSettablePropertyValue($userProperty, $user));
276
        }
277
    }
278
279
    /**
280
     * @param mixed $debug
281
     */
282
    public function setDebug($debug)
283
    {
284
        $this->debug = $debug;
285
    }
286
287
    /**
288
     * @param EventResolverInterface $entityEventResolver
289
     */
290
    public function setEntityEventResolver($entityEventResolver)
291
    {
292
        $this->entityEventResolver = $entityEventResolver;
293
    }
294
295
    private function isDebug()
296
    {
297
        return $this->debug;
298
    }
299
}
300