• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

xiidea / EasyAuditBundle / 19525679799

20 Nov 2025 04:30AM UTC coverage: 97.967% (-0.8%) from 98.79%
19525679799

Pull #63

github

web-flow
Merge 924195035 into 2a977f1ec
Pull Request #63: fix: fire created event though event configured for update

1 of 1 new or added line in 1 file covered. (100.0%)

4 existing lines in 1 file now uncovered.

482 of 492 relevant lines covered (97.97%)

23.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.78
/Subscriber/DoctrineSubscriber.php
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\Subscriber;
13

14
use Doctrine\Common\Util\ClassUtils;
15
use Doctrine\Persistence\Event\LifecycleEventArgs;
16
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17
use Xiidea\EasyAuditBundle\Attribute\SubscribeDoctrineEvents;
18
use Xiidea\EasyAuditBundle\Events\DoctrineEvents;
19
use Xiidea\EasyAuditBundle\Events\DoctrineObjectEvent;
20

21
class DoctrineSubscriber
22
{
23
    private array $toBeDeleted = [];
24
    private  $dispatcher = null;
25

26
    public function __construct(private array $entities = [])
27
    {
28
    }
12✔
29

30
    public function postPersist(LifecycleEventArgs $args)
31
    {
32
        $this->handleEvent(DoctrineEvents::ENTITY_CREATED, $args);
6✔
33
    }
34

35
    public function postUpdate(LifecycleEventArgs $args)
36
    {
37
        $this->handleEvent(DoctrineEvents::ENTITY_UPDATED, $args);
3✔
38
    }
39

40
    public function preRemove(LifecycleEventArgs $args)
41
    {
42
        if (false === $this->isConfiguredToTrack($args->getObject(), DoctrineEvents::ENTITY_DELETED)) {
9✔
43
            return;
×
44
        }
45

46
        $className = ClassUtils::getClass($args->getObject());
9✔
47

48
        if (!isset($this->toBeDeleted[$className])) {
9✔
49
            $this->toBeDeleted[$className] = [];
9✔
50
        }
51

52
        $this->toBeDeleted[$className][spl_object_hash($args->getObject())] = $this->getIdentity($args, $className);
9✔
53
    }
54

55
    public function postRemove(LifecycleEventArgs $args)
56
    {
57
        $identity = $this->getToBeDeletedId($args->getObject());
9✔
58

59
        if (null !== $identity) {
9✔
60
            $this->dispatcher->dispatch(new DoctrineObjectEvent($args, $identity), DoctrineEvents::ENTITY_DELETED);
9✔
61
        }
62
    }
63

64
    private function getToBeDeletedId($entity)
65
    {
66
        if ($this->isScheduledForDelete($entity)) {
9✔
67
            return $this->toBeDeleted[ClassUtils::getClass($entity)][spl_object_hash($entity)];
9✔
68
        }
69

UNCOV
70
        return null;
×
71
    }
72

73
    /**
74
     * @param  string  $eventName
75
     * @param  LifecycleEventArgs  $args
76
     */
77
    private function handleEvent($eventName, LifecycleEventArgs $args)
78
    {
79
        if (true === $this->isConfiguredToTrack($args->getObject(), $eventName)) {
6✔
80
            $this->dispatcher->dispatch(
6✔
81
                new DoctrineObjectEvent($args, $this->getIdentity($args, ClassUtils::getClass($args->getObject()))),
6✔
82
                $eventName
6✔
83
            );
6✔
84
        }
85
    }
86

87
    /**
88
     * @param $entity
89
     * @param  string  $eventName
90
     *
91
     * @return bool
92
     */
93
    private function isConfiguredToTrack($entity, $eventName = '')
94
    {
95
        $class = ClassUtils::getClass($entity);
12✔
96
        $eventType = DoctrineEvents::getShortEventType($eventName);
12✔
97

98
        if (null !== $track = $this->isAttributedEvent($entity, $eventType)) {
12✔
99
            return $track;
12✔
100
        }
101

UNCOV
102
        if (!isset($this->entities[$class])) {
×
UNCOV
103
            return false;
×
104
        }
105

106
        if ($this->shouldTrackAllEventType($class)) {
×
107
            return true;
×
108
        }
109

110
        return $this->shouldTrackEventType($eventType, $class);
×
111
    }
112

113
    /**
114
     * @param $entity
115
     * @param string $eventType
116
     * @return bool|null
117
     * @throws \ReflectionException
118
     */
119
    protected function isAttributedEvent($entity, $eventType)
120
    {
121
        $reflection = new \ReflectionClass($entity);
12✔
122
        $attribute = $reflection->getAttributes(SubscribeDoctrineEvents::class);
12✔
123
        if (empty($attribute)) {
12✔
UNCOV
124
            return null;
×
125
        }
126

127
        $instance = $attribute[0]->newInstance();
12✔
128

129
        return empty($instance->events) || in_array($eventType, $instance->events);
12✔
130
    }
131

132

133
    /**
134
     * @param  string  $eventType
135
     * @param  string  $class
136
     *
137
     * @return bool
138
     */
139
    private function shouldTrackEventType($eventType, $class)
140
    {
141
        return is_array($this->entities[$class]) && in_array($eventType, $this->entities[$class]);
×
142
    }
143

144
    /**
145
     * @param  string  $class
146
     *
147
     * @return bool
148
     */
149
    private function shouldTrackAllEventType($class)
150
    {
151
        return empty($this->entities[$class]);
×
152
    }
153

154
    /**
155
     * @param  LifecycleEventArgs  $args
156
     * @param $className
157
     *
158
     * @return array
159
     */
160
    protected function getIdentity(LifecycleEventArgs $args, $className)
161
    {
162
        return $args->getObjectManager()->getClassMetadata($className)->getIdentifierValues($args->getObject());
12✔
163
    }
164

165
    /**
166
     * @param $entity
167
     *
168
     * @return bool
169
     */
170
    private function isScheduledForDelete($entity)
171
    {
172
        $originalClassName = ClassUtils::getClass($entity);
9✔
173

174
        return isset($this->toBeDeleted[$originalClassName]) && isset(
9✔
175
                $this->toBeDeleted[$originalClassName][spl_object_hash(
9✔
176
                    $entity
9✔
177
                )]
9✔
178
            );
9✔
179
    }
180

181
    /**
182
     * @param  EventDispatcherInterface  $dispatcher
183
     */
184
    public function setDispatcher($dispatcher)
185
    {
186
        $this->dispatcher = $dispatcher;
12✔
187
    }
188
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc