EventResolverFactory::createEventObjectFromArray()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 14
c 0
b 0
f 0
rs 10
cc 3
nc 3
nop 1
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\Contracts\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\Model\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 $debug = false;
35
36
    /**
37
     * EventResolverFactory constructor.
38
     *
39
     * @param array $resolverEventMap
40
     * @param $userProperty
41
     * @param $entityClass
42
     */
43
    public function __construct(private array $resolverEventMap = array(), private $userProperty = 'userIdentifier', private $entityClass = BaseAuditLog::class)
44
    {
45
    }
46
47
    /**
48
     * @param Event  $event
49
     * @param string $eventName
50
     *
51
     * @return null|BaseAuditLog
52
     *
53
     * @throws UnrecognizedEventInfoException
54
     * @throws \Exception
55
     */
56
    public function getEventLog(Event $event, $eventName)
57
    {
58
        $eventLog = $this->getEventLogObject($this->getEventLogInfo($event, $eventName));
59
60
        if (null === $eventLog) {
61
            return null;
62
        }
63
64
        $eventLog->setTypeId($eventName);
65
        $eventLog->setIp($this->getClientIp());
66
        $eventLog->setEventTime(new \DateTime());
67
        $this->setUser($eventLog);
68
69
        return $eventLog;
70
    }
71
72
    /**
73
     * @param $eventInfo
74
     *
75
     * @return null|BaseAuditLog
76
     *
77
     * @throws UnrecognizedEventInfoException
78
     * @throws \Exception
79
     */
80
    protected function getEventLogObject($eventInfo)
81
    {
82
        if (empty($eventInfo)) {
83
            return null;
84
        }
85
86
        if ($eventInfo instanceof BaseAuditLog) {
87
            return $eventInfo;
88
        }
89
90
        return $this->createEventObjectFromArray($eventInfo);
91
    }
92
93
    /**
94
     * @param string $eventName
95
     *
96
     * @return EventResolverInterface
97
     */
98
    protected function getResolver($eventName)
99
    {
100
        if ($this->isEntityEvent($eventName)) {
101
            return $this->entityEventResolver;
102
        }
103
104
        if (isset($this->resolverEventMap[$eventName]) && isset($this->customResolvers[$this->resolverEventMap[$eventName]])) {
105
            return $this->customResolvers[$this->resolverEventMap[$eventName]];
106
        }
107
108
        return $this->commonResolver;
109
    }
110
111
    /**
112
     * @param string $eventName
113
     *
114
     * @return bool
115
     */
116
    protected function isEntityEvent($eventName)
117
    {
118
        return in_array($eventName, DoctrineEvents::getConstants());
119
    }
120
121
    /**
122
     * @param Event  $event
123
     * @param string $eventName
124
     *
125
     * @throws InvalidServiceException
126
     */
127
    protected function getEventLogInfo(Event $event, $eventName)
128
    {
129
        if ($event instanceof EmbeddedEventResolverInterface) {
130
            return $event->getEventLogInfo($eventName);
131
        }
132
133
        if (null === $eventResolver = $this->getResolver($eventName)) {
134
            return null;
135
        }
136
137
        return $eventResolver->getEventLogInfo($event, $eventName);
138
    }
139
140
    /**
141
     * @param BaseAuditLog $entity
142
     *
143
     * @throws \Exception
144
     */
145
    protected function setUser(BaseAuditLog $entity)
146
    {
147
        if (null === $user = $this->getUser()) {
148
            $entity->setUser($this->getAnonymousUserName());
149
            return;
150
        }
151
152
        $entity->setUser($this->getSettablePropertyValue($this->userProperty, $user));
153
154
        $this->setImpersonatingUser($entity, $this->userProperty);
155
    }
156
157
    /**
158
     * @return string
159
     */
160
    protected function getClientIp()
161
    {
162
        $request = $this->getRequest();
163
164
        if ($request) {
165
            return $request->getClientIp();
166
        }
167
168
        return '';
169
    }
170
171
    /**
172
     * @param $id
173
     * @param EventResolverInterface $resolver
174
     *
175
     * @throws \Exception|InvalidServiceException
176
     */
177
    public function addCustomResolver($id, $resolver)
178
    {
179
        if (!$resolver instanceof EventResolverInterface) {
0 ignored issues
show
introduced by
$resolver is always a sub-type of Xiidea\EasyAuditBundle\R...\EventResolverInterface.
Loading history...
180
            $this->handleException(new InvalidServiceException(
181
                'Resolver Service must implement'.EventResolverInterface::class
182
            ));
183
184
            return;
185
        }
186
187
        $this->customResolvers[$id] = $resolver;
188
    }
189
190
    /**
191
     * @throws \Exception
192
     */
193
    public function setCommonResolver(mixed $resolver)
194
    {
195
        if (!$resolver instanceof EventResolverInterface) {
196
            $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)) targeting 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...
197
                'Resolver Service must implement'.EventResolverInterface::class
198
            ));
199
200
            return;
201
        }
202
203
        $this->commonResolver = $resolver;
204
    }
205
206
    /**
207
     * @param \Exception $e
208
     *
209
     * @throws \Exception
210
     */
211
    protected function handleException(\Exception $e)
212
    {
213
        if ($this->isDebug()) {
214
            throw $e;
215
        }
216
217
        return null;
218
    }
219
220
    /**
221
     * @param $eventInfo
222
     *
223
     * @return null|BaseAuditLog
224
     *
225
     * @throws \Exception
226
     */
227
    protected function createEventObjectFromArray($eventInfo)
228
    {
229
        if (!is_array($eventInfo)) {
230
            return $this->handleException(new UnrecognizedEventInfoException());
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->handleException(n...edEventInfoException()) targeting 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 used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
231
        }
232
233
        $auditLogClass = $this->entityClass;
234
        $eventObject = new $auditLogClass();
235
236
        if (!$eventObject instanceof BaseAuditLog) {
237
            return $this->handleException(new UnrecognizedEntityException());
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->handleException(n...nizedEntityException()) targeting 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 used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
238
        }
239
240
        return $eventObject->fromArray($eventInfo);
241
    }
242
243
    /**
244
     * @param $userProperty
245
     * @param $user
246
     *
247
     * @return mixed
248
     */
249
    protected function getSettablePropertyValue($userProperty, $user)
250
    {
251
        if (empty($userProperty)) {
252
            return $user;
253
        }
254
255
        try {
256
            $propertyAccessor = PropertyAccess::createPropertyAccessor();
257
            return $propertyAccessor->getValue($user, $userProperty);
258
        } catch (NoSuchPropertyException $e) {
259
            return $this->handleException($e);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->handleException($e) targeting 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 used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
260
        }
261
    }
262
263
    /**
264
     * @param BaseAuditLog $entity
265
     * @param string $userProperty
266
     */
267
    protected function setImpersonatingUser(BaseAuditLog $entity, $userProperty)
268
    {
269
        if (null !== $user = $this->getImpersonatingUser()) {
270
            $entity->setImpersonatingUser($this->getSettablePropertyValue($userProperty, $user));
271
        }
272
    }
273
274
    public function setDebug(mixed $debug)
275
    {
276
        $this->debug = $debug;
277
    }
278
279
    /**
280
     * @param EventResolverInterface $entityEventResolver
281
     */
282
    public function setEntityEventResolver($entityEventResolver)
283
    {
284
        $this->entityEventResolver = $entityEventResolver;
285
    }
286
287
    private function isDebug()
288
    {
289
        return $this->debug;
290
    }
291
}
292