Completed
Pull Request — master (#828)
by
unknown
05:14
created

BusinessEntitySubscriber::preRemove()   C

Complexity

Conditions 9
Paths 16

Size

Total Lines 66
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 66
rs 6.4099
cc 9
eloc 41
nc 16
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Victoire\Bundle\BusinessEntityBundle\EventSubscriber;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\Common\EventSubscriber;
7
use Doctrine\ORM\EntityManager;
8
use Doctrine\ORM\Event\LifecycleEventArgs;
9
use Doctrine\ORM\Event\PostFlushEventArgs;
10
use Doctrine\ORM\UnitOfWork;
11
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12
use Victoire\Bundle\BusinessEntityBundle\Entity\BusinessEntity;
13
use Victoire\Bundle\BusinessEntityBundle\Helper\BusinessEntityHelper;
14
use Victoire\Bundle\BusinessPageBundle\Builder\BusinessPageBuilder;
15
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessPage;
16
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessTemplate;
17
use Victoire\Bundle\BusinessPageBundle\Helper\BusinessPageHelper;
18
use Victoire\Bundle\BusinessPageBundle\Repository\BusinessPageRepository;
19
use Victoire\Bundle\ViewReferenceBundle\Event\ViewReferenceEvent;
20
use Victoire\Bundle\ViewReferenceBundle\ViewReferenceEvents;
21
22
class BusinessEntitySubscriber implements EventSubscriber
23
{
24
    protected $businessPageBuilder;
25
    protected $dispatcher;
26
    protected $businessEntityHelper;
27
    protected $flushedBusinessEntities;
28
    protected $businessPageHelper;
29
    protected $flushedBusinessTemplates;
30
31
    /**
32
     * @param BusinessPageBuilder      $businessPageBuilder
33
     * @param BusinessEntityHelper     $businessEntityHelper
34
     * @param BusinessPageHelper       $businessPageHelper
35
     * @param EventDispatcherInterface $dispatcher
36
     */
37
    public function __construct(
38
        BusinessPageBuilder          $businessPageBuilder,
39
        BusinessEntityHelper         $businessEntityHelper,
40
        BusinessPageHelper           $businessPageHelper,
41
        EventDispatcherInterface     $dispatcher
42
    ) {
43
        $this->businessPageBuilder = $businessPageBuilder;
44
        $this->businessEntityHelper = $businessEntityHelper;
45
        $this->businessPageHelper = $businessPageHelper;
46
        $this->dispatcher = $dispatcher;
47
        $this->flushedBusinessEntities = new ArrayCollection();
48
        $this->flushedBusinessTemplates = new ArrayCollection();
49
    }
50
51
    /**
52
     * bind to LoadClassMetadata method.
53
     *
54
     * @return string[] The subscribed events
55
     */
56
    public function getSubscribedEvents()
57
    {
58
        return [
59
            'postUpdate',
60
            'postPersist',
61
            'preRemove',
62
            'postFlush',
63
        ];
64
    }
65
66
    /**
67
     * @param LifecycleEventArgs $eventArgs
68
     */
69
    public function postUpdate(LifecycleEventArgs $eventArgs)
70
    {
71
        /** @var EntityManager $entityManager */
72
        $entityManager = $eventArgs->getEntityManager();
73
        /** @var UnitOfWork $uow */
74
        $uow = $entityManager->getUnitOfWork();
75
76
        foreach ($uow->getScheduledEntityInsertions() as $entity) {
77
            $businessEntity = $this->businessEntityHelper->findByEntityInstance($entity);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $businessEntity is correct as $this->businessEntityHel...EntityInstance($entity) (which targets Victoire\Bundle\Business...:findByEntityInstance()) 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...
78
            if ($businessEntity) {
79
                $this->updateBusinessPages(
80
                    $entity,
81
                    $businessEntity,
82
                    $entityManager,
83
                    $uow->getScheduledEntityDeletions()
84
                );
85
            }
86
        }
87
        $this->updateViewReference($eventArgs);
88
    }
89
90
    /**
91
     * @param LifecycleEventArgs $eventArgs
92
     */
93
    public function postPersist(LifecycleEventArgs $eventArgs)
94
    {
95
        $this->updateViewReference($eventArgs);
96
    }
97
98
    /**
99
     * get BusinessTemplate concerned by this entity (if so)
100
     * then get BusinessPages
101
     * for each BusinessPage, update its slug according to the new slug (if so).
102
     *
103
     * @param $entity
104
     * @param BusinessEntity $businessEntity
105
     * @param EntityManager  $entityManager
106
     * @param array          $deletions
107
     *
108
     * @throws \Exception
109
     *
110
     * @internal param LifecycleEventArgs $eventArgs
111
     */
112
    public function updateBusinessPages($entity, BusinessEntity $businessEntity, EntityManager $entityManager, $deletions)
113
    {
114
        $businessTemplates = $entityManager->getRepository('VictoireBusinessPageBundle:BusinessTemplate')->findPagePatternByBusinessEntity($businessEntity);
115
        foreach ($businessTemplates as $businessTemplate) {
116
            // Generate viewRef for each BT translation
117
            /** @var ViewTra $translation */
118
            foreach ($businessTemplate->getTranslations() as $translation) {
119
                $businessTemplate->setCurrentLocale($translation->getLocale());
120
                if ($this->businessPageHelper->isEntityAllowed($businessTemplate, $entity, $entityManager)) {
121
                    /** @var BusinessPageRepository $bepRepo */
122
                    $bepRepo = $entityManager->getRepository('VictoireBusinessPageBundle:BusinessPage');
123
                    $virtualBusinessPage = $this->businessPageBuilder->generateEntityPageFromTemplate(
124
                        $businessTemplate,
125
                        $entity,
126
                        $entityManager
127
                    );
128
                    // Get the BusinessPage if exists for the given entity
129
                    /** @var BusinessPage $businessPage */
130
                    $businessPage = $bepRepo->findPageByBusinessEntityAndPattern(
131
                        $businessTemplate,
132
                        $entity,
133
                        $businessEntity
134
                    );
135
                    $businessPage->setCurrentLocale($translation->getLocale());
136
                    // If there is diff between persisted BEP and computed, persist the change
137
                    $scheduledForRemove = false;
138
                    foreach ($deletions as $deletion) {
139
                        if (get_class($deletion) == get_class($businessPage)
140
                            && $deletion->getId() === $businessPage->getId()
141
                        ) {
142
                            $scheduledForRemove = true;
143
                        }
144
                    }
145
146
                    if ($businessPage && !$scheduledForRemove) {
147
                        $oldSlug = $businessPage->getSlug();
0 ignored issues
show
Unused Code introduced by
$oldSlug is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
148
                        $newSlug = $entity->getSlug();
0 ignored issues
show
Unused Code introduced by
$newSlug is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
149
                        $businessPage->setName($virtualBusinessPage->getName());
150
                        $businessPage->setSlug($virtualBusinessPage->getSlug());
151
152
                        $entityManager->persist($businessPage);
153
                        $entityManager->flush();
154
                    }
155
                }
156
            }
157
        }
158
    }
159
160
    /**
161
     * Iterate over inserted BusinessEntities and BusinessTemplates catched by postPersist
162
     * and dispatch event to generate the needed ViewReferences.
163
     *
164
     * @param PostFlushEventArgs $eventArgs
165
     *
166
     * @throws \Exception
167
     */
168
    public function postFlush(PostFlushEventArgs $eventArgs)
169
    {
170
        $em = $eventArgs->getEntityManager();
171 View Code Duplication
        foreach ($this->flushedBusinessEntities as $entity) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
172
            $businessEntity = $this->businessEntityHelper->findByEntityInstance($entity);
173
            //find all BT that can represent the businessEntity
174
            $businessTemplates = $em->getRepository('VictoireBusinessPageBundle:BusinessTemplate')->findPagePatternByBusinessEntity($businessEntity);
175
            foreach ($businessTemplates as $businessTemplate) {
176
                //generate a viewReference for each BT translation
177
                foreach ($businessTemplate->getTranslations() as $translation) {
178
                    $businessTemplate->setCurrentLocale($translation->getLocale());
179
180
                    if ($page = $em->getRepository(
181
                        'Victoire\Bundle\BusinessPageBundle\Entity\BusinessPage'
182
                    )->findPageByBusinessEntityAndPattern($businessTemplate, $entity, $businessEntity)
183
                    ) {
184
                        //if it's a BP we update the BP
185
                        $this->businessPageBuilder->updatePageParametersByEntity($page, $entity);
186
                    } else {
187
                        $page = $this->businessPageBuilder->generateEntityPageFromTemplate(
188
                            $businessTemplate,
189
                            $entity,
190
                            $em
191
                        );
192
                    }
193
                    if ($this->businessPageHelper->isEntityAllowed($businessTemplate, $entity, $em)) {
194
                        //update the reference
195
                        $event = new ViewReferenceEvent($page);
196
                        $this->dispatcher->dispatch(ViewReferenceEvents::UPDATE_VIEW_REFERENCE, $event);
197
                    }
198
                }
199
            }
200
        }
201
202 View Code Duplication
        foreach ($this->flushedBusinessTemplates as $entity) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
203
            $businessEntityId = $entity->getBusinessEntityId();
204
            $businessEntity = $this->businessEntityHelper->findById($businessEntityId);
205
            //find all entities
206
            $entities = $this->businessPageHelper->getEntitiesAllowed($entity, $em);
207
            //generate a viewReference for each BT translation
208
            foreach ($entity->getTranslations() as $translation) {
209
                $entity->setCurrentLocale($translation->getLocale());
210
                foreach ($entities as $be) {
211
                    if ($this->businessPageHelper->isEntityAllowed($entity, $be, $em)) {
212
                        if ($page = $em->getRepository(
213
                            'Victoire\Bundle\BusinessPageBundle\Entity\BusinessPage'
214
                        )->findPageByBusinessEntityAndPattern($entity, $be, $businessEntity)
215
                        ) {
216
                            //rebuild page if its a BP
217
                            $this->businessPageBuilder->updatePageParametersByEntity($page, $be);
218
                        } else {
219
                            $page = $this->businessPageBuilder->generateEntityPageFromTemplate(
220
                                $entity,
221
                                $be,
222
                                $em
223
                            );
224
                        }
225
                        // update reference
226
                        $event = new ViewReferenceEvent($page);
227
                        $this->dispatcher->dispatch(ViewReferenceEvents::UPDATE_VIEW_REFERENCE, $event);
228
                    }
229
                }
230
            }
231
        }
232
        $this->flushedBusinessEntities->clear();
233
        $this->flushedBusinessTemplates->clear();
234
    }
235
236
    /**
237
     * This method throw an event if needed for a view related to a businessEntity.
238
     *
239
     * @param LifecycleEventArgs $eventArgs
240
     *
241
     * @throws \Exception
242
     */
243
    private function updateViewReference(LifecycleEventArgs $eventArgs)
244
    {
245
        $entity = $eventArgs->getEntity();
246
247
        //if entity is a translation, get its translatable entity
248
        if(method_exists($entity, 'getTranslatable')) {
249
            $entity = $entity->getTranslatable();
250
        }
251
252
        //if it's a businessEntity we need to rebuild virtuals (BPs are rebuild in businessEntitySubscriber)
253
        if ($businessEntity = $this->businessEntityHelper->findByEntityInstance($entity)) {
0 ignored issues
show
Unused Code introduced by
$businessEntity is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
254
            $this->flushedBusinessEntities->add($entity);
255
        }
256
        //if it a businessTemplate we have to rebuild virtuals or update BP
257
        if ($entity instanceof BusinessTemplate) {
258
            $this->flushedBusinessTemplates->add($entity);
259
        }
260
    }
261
262
    /**
263
     * @param LifecycleEventArgs $eventArgs
264
     *
265
     * @throws \Exception
266
     */
267
    public function preRemove(LifecycleEventArgs $eventArgs)
268
    {
269
        $entity = $eventArgs->getEntity();
270
271
        //if we remove a BP we need to replace by a VBP ref
272
        if ($entity instanceof BusinessPage) {
273
            //remove BP ref
274
            $event = new ViewReferenceEvent($entity);
275
            $this->dispatcher->dispatch(ViewReferenceEvents::REMOVE_VIEW_REFERENCE, $event);
276
            $em = $eventArgs->getEntityManager();
277
            $businessTemplate = $entity->getTemplate();
278
            $page = $this->businessPageBuilder->generateEntityPageFromTemplate(
279
                $businessTemplate,
0 ignored issues
show
Documentation introduced by
$businessTemplate is of type string, but the function expects a object<Victoire\Bundle\B...ntity\BusinessTemplate>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
280
                $entity->getBusinessEntity(),
281
                $em
282
            );
283
            //create VBP ref
284
            //TODO :: dont rebuild if businessEntity or businessTemplate doesn't exist
285
            $event = new ViewReferenceEvent($page);
286
            $this->dispatcher->dispatch(ViewReferenceEvents::UPDATE_VIEW_REFERENCE, $event);
287
        }
288
289
        //if it's a businessEntity, we need to remove all BP and VBP ref
290
        if ($businessEntity = $this->businessEntityHelper->findByEntityInstance($entity)) {
291
            $em = $eventArgs->getEntityManager();
292
            $businessTemplates = $em->getRepository('VictoireBusinessPageBundle:BusinessTemplate')->findPagePatternByBusinessEntity($businessEntity);
293
            foreach ($businessTemplates as $businessTemplate) {
294
295
                //generate a viewReference for each BT translation
296
                foreach ($businessTemplate->getTranslations() as $translation) {
297
                    $businessTemplate->setCurrentLocale($translation->getLocale());
298
                    if ($page = $em->getRepository('Victoire\Bundle\BusinessPageBundle\Entity\BusinessPage')->findPageByBusinessEntityAndPattern($businessTemplate, $entity, $businessEntity)) {
299
                        $event = new ViewReferenceEvent($page);
300
                        $this->dispatcher->dispatch(ViewReferenceEvents::REMOVE_VIEW_REFERENCE, $event);
301
                    } else {
302
                        $page = $this->businessPageBuilder->generateEntityPageFromTemplate(
303
                            $businessTemplate,
304
                            $entity,
305
                            $em
306
                        );
307
                        $event = new ViewReferenceEvent($page);
308
                        $this->dispatcher->dispatch(ViewReferenceEvents::REMOVE_VIEW_REFERENCE, $event);
309
                    }
310
                }
311
            }
312
        }
313
        //if we remove a businessTemplate remove all VBT ref (BP cascade remove)
314
        if ($entity instanceof BusinessTemplate) {
315
            $em = $eventArgs->getEntityManager();
316
            $entities = $this->businessPageHelper->getEntitiesAllowed($entity, $em);
317
318
            //generate a viewReference for each BT translation
319
            foreach ($entity->getTranslations() as $translation) {
320
                $entity->setCurrentLocale($translation->getLocale());
321
                foreach ($entities as $be) {
322
                    $page = $this->businessPageBuilder->generateEntityPageFromTemplate(
323
                        $entity,
324
                        $be,
325
                        $em
326
                    );
327
                    $event = new ViewReferenceEvent($page);
328
                    $this->dispatcher->dispatch(ViewReferenceEvents::REMOVE_VIEW_REFERENCE, $event);
329
                }
330
            }
331
        }
332
    }
333
}
334