Completed
Push — cq ( c9c669...15d49d )
by Roni
03:04
created

EntityEventResolver::isIdProperty()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 2
eloc 2
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\DependencyInjection\ContainerAwareInterface;
15
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
16
use Symfony\Component\EventDispatcher\Event;
17
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
18
use Symfony\Component\PropertyAccess\PropertyAccess;
19
use Xiidea\EasyAuditBundle\Events\DoctrineEntityEvent;
20
use Xiidea\EasyAuditBundle\Events\DoctrineEvents;
21
22
/** Custom Event Resolver Example Class */
23
class EntityEventResolver implements ContainerAwareInterface, EventResolverInterface
24
{
25
    use ContainerAwareTrait;
26
27
    protected $candidateProperties = array('name', 'title');
28
29
    protected $propertiesFound = array();
30
31
    protected $eventShortName;
32
33
    /** @var  $event DoctrineEntityEvent */
34
    protected $event;
35
36
    protected $entity;
37
38
    protected $eventName;
39
40
41
    /**
42
     * @param Event|DoctrineEntityEvent $event
43
     * @param $eventName
44
     *
45
     * @return array
46
     */
47
    public function getEventLogInfo(Event $event, $eventName)
48
    {
49
        if (!$event instanceof DoctrineEntityEvent) {
50
            return null;
51
        }
52
53
        $this->initialize($event, $eventName);
54
55
        if ($this->isUpdateEvent() && null === $this->getChangeSets($this->entity)) {
56
            return null;
57
        }
58
59
        $entityClass = $this->getReflectionClassFromObject($this->entity);
60
61
        return array(
62
            'description' => $this->getDescription($entityClass),
63
            'type' => $this->getEventType($entityClass->getShortName()),
64
        );
65
66
    }
67
68
    /**
69
     * @param DoctrineEntityEvent $event
70
     * @param string $eventName
71
     */
72
    private function initialize(DoctrineEntityEvent $event, $eventName)
73
    {
74
        $this->eventShortName = null;
75
        $this->propertiesFound = array();
76
        $this->eventName = $eventName;
77
        $this->event = $event;
78
        $this->entity = $event->getLifecycleEventArgs()->getEntity();
79
    }
80
81
    protected function getChangeSets($entity)
82
    {
83
        return $this->isUpdateEvent() ? $this->getUnitOfWork()->getEntityChangeSet($entity) : null;
84
    }
85
86
    protected function isUpdateEvent()
87
    {
88
        return $this->getEventShortName() == 'updated';
89
    }
90
91
    /**
92
     * @param string $name
93
     * @return string|mixed
94
     */
95
    protected function getProperty($name)
96
    {
97
        $propertyAccessor = PropertyAccess::createPropertyAccessor();
98
99
        try {
100
            return $propertyAccessor->getValue($this->entity, $this->propertiesFound[$name]);
101
        } catch (NoSuchPropertyException $e) {
102
            return '{INACCESSIBLE} property! ' . $e->getMessage();
103
        }
104
    }
105
106
107
    /**
108
     * @param string $typeName
109
     * @return string
110
     */
111
    protected function getEventType($typeName)
112
    {
113
        return $typeName . " " . $this->getEventShortName();
114
    }
115
116
    /**
117
     * @param \ReflectionClass $reflectionClass
118
     * @return string
119
     */
120
    protected function getDescription(\ReflectionClass $reflectionClass)
121
    {
122
        $property = $this->getBestCandidatePropertyForIdentify($reflectionClass);
123
124
        $descriptionTemplate = '%s has been %s';
125
126
        if (!empty($property)) {
127
            $descriptionTemplate .= sprintf(' with %s = "%s"', $property, $this->getProperty($property));
128
        }
129
130
        return sprintf(
131
            $descriptionTemplate,
132
            $reflectionClass->getShortName(),
133
            $this->getEventShortName()
134
        );
135
    }
136
137
    /**
138
     * @return string
139
     */
140
    protected function getEventShortName()
141
    {
142
        if (null === $this->eventShortName) {
143
            $this->eventShortName = DoctrineEvents::getShortEventType($this->getName());
144
        }
145
146
        return $this->eventShortName;
147
    }
148
149
    /**
150
     * @param \ReflectionClass $reflectionClass
151
     * @return null|string
152
     */
153
    protected function getBestCandidatePropertyForIdentify(\ReflectionClass $reflectionClass)
154
    {
155
        $foundPropertyName = $this->getPropertyNameInCandidateList($reflectionClass);
156
157
        if ("" !== $foundPropertyName) {
158
            return $foundPropertyName;
159
        }
160
161
        return $this->getNameOrIdPropertyFromPropertyList($reflectionClass,
162
            strtolower($reflectionClass->getShortName()) . "id"
163
        );
164
    }
165
166
    /**
167
     * @param \ReflectionClass $reflectionClass
168
     * @return string
169
     */
170
    protected function getPropertyNameInCandidateList(\ReflectionClass $reflectionClass)
171
    {
172
        foreach ($this->candidateProperties as $property) {
173
            if($reflectionClass->hasProperty($property)) {
174
                return $this->propertiesFound[$property] = $property;
175
            }
176
        }
177
178
        return "";
179
    }
180
181
    /**
182
     * @return string
183
     */
184
    protected function getName()
185
    {
186
        return $this->eventName;
187
    }
188
189
    /**
190
     * @param $object
191
     * @return \ReflectionClass
192
     */
193
    protected function getReflectionClassFromObject($object)
194
    {
195
        return new \ReflectionClass(get_class($object));
196
    }
197
198
    /**
199
     * @return \Doctrine\ORM\UnitOfWork
200
     */
201
    protected function getUnitOfWork()
202
    {
203
        return $this->container->get('doctrine')->getManager()->getUnitOfWork();
204
    }
205
206
    /**
207
     * @param \ReflectionClass $reflectionClass
208
     * @param $entityIdStr
209
     * @return null|string
210
     */
211
    private function getNameOrIdPropertyFromPropertyList(\ReflectionClass $reflectionClass, $entityIdStr)
212
    {
213
        foreach (array('id', $entityIdStr) as $field) {
214
            if($reflectionClass->hasProperty($field)) {
215
                return $this->propertiesFound['id'] = $field;
216
            }
217
        }
218
219
        return "";
220
    }
221
}
222