Completed
Pull Request — 5.2 (#2395)
by
unknown
11:37
created

NodeIndexUpdateEventListener::preUpdate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Kunstmaan\NodeSearchBundle\EventListener;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Doctrine\ORM\Event\LifecycleEventArgs;
7
use Kunstmaan\NodeBundle\Entity\Node;
8
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
9
use Kunstmaan\NodeBundle\Entity\StructureNode;
10
use Kunstmaan\NodeBundle\Event\NodeEvent;
11
use Kunstmaan\NodeSearchBundle\Configuration\NodePagesConfiguration;
12
use Symfony\Component\DependencyInjection\ContainerInterface;
13
14
/**
15
 * EventListener which will be triggered when a Node has been updated in order to update its related documents
16
 * in the index
17
 */
18
class NodeIndexUpdateEventListener implements NodeIndexUpdateEventListenerInterface
19
{
20
    /** @var ContainerInterface */
21
    private $container;
22
23
    /** @var EntityManagerInterface */
24
    private $em;
25
26
    /** @var NodePagesConfiguration */
27
    private $nodePagesConfiguration;
28
29
    /** @var array */
30
    private $entityChangeSet;
31
32
    public function __construct(/* NodePagesConfiguration */
33
        $nodePagesConfiguration, /* EntityManagerInterface */
34
        $em = null)
35
    {
36
        if ($nodePagesConfiguration instanceof ContainerInterface) {
37
            @trigger_error(sprintf('Passing the container as the first argument of "%s" is deprecated in KunstmaanNodeSearchBundle 5.2 and will be removed in KunstmaanNodeSearchBundle 6.0. Inject the "%s" service instead.', __CLASS__, 'kunstmaan_node_search.search_configuration.node'), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
38
39
            $this->container = $nodePagesConfiguration;
40
            $this->nodePagesConfiguration = $this->container->get('kunstmaan_node_search.search_configuration.node');
41
42
            return;
43
        }
44
45
        if ($em === null || !($em instanceof EntityManagerInterface)) {
46
            @trigger_error(sprintf('Passing null or something other than an entitymanagerinterface as the second argument of "%s" is deprecated in KunstmaanNodeSearchBundle 5.2 and will be removed in KunstmaanNodeSearchBundle 6.0. Inject the "%s" service instead.', __CLASS__, 'doctrine.orm.default_entity_manager'), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
47
        }
48
49
        $this->nodePagesConfiguration = $nodePagesConfiguration;
50
        $this->em = $em;
51
    }
52
53
    /**
54
     * @param LifecycleEventArgs $args
55
     */
56
    public function preUpdate(LifecycleEventArgs $args)
57
    {
58
        if ($args->getObject() instanceof NodeTranslation) {
59
            // unfortunately we have to keep a state to see what has changed
60
            $this->entityChangeSet = [
61
                'nodeTranslationId' => $args->getObject()->getId(),
62
                'changeSet' => $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($args->getObject()),
63
            ];
64
        }
65
    }
66
67
    /**
68
     * @param NodeEvent $event
69
     */
70
    public function onPostPublish(NodeEvent $event)
71
    {
72
        $this->index($event);
73
    }
74
75
    /**
76
     * @param NodeEvent $event
77
     */
78
    public function onPostPersist(NodeEvent $event)
79
    {
80
        $reIndexChildren = (
81
            !is_null($this->entityChangeSet)
82
            && $this->entityChangeSet['nodeTranslationId'] == $event->getNodeTranslation()->getId()
83
            && isset($this->entityChangeSet['changeSet']['url'])
84
        );
85
        $this->index($event, $reIndexChildren);
86
    }
87
88
    /**
89
     * @param NodeEvent $event
90
     * @param bool      $reIndexChildren
91
     */
92
    private function index(NodeEvent $event, $reIndexChildren = false)
93
    {
94
        $nodeTranslation = $event->getNodeTranslation();
95
96
        if ($this->hasOfflineParents($nodeTranslation)) {
97
            return;
98
        }
99
100
        $this->nodePagesConfiguration->indexNodeTranslation($nodeTranslation, true);
101
102
        if ($reIndexChildren) {
103
            $this->nodePagesConfiguration->indexChildren($event->getNode(), $nodeTranslation->getLang());
104
        }
105
    }
106
107
    /**
108
     * @param NodeEvent $event
109
     */
110
    public function onPostDelete(NodeEvent $event)
111
    {
112
        $this->delete($event);
113
    }
114
115
    /**
116
     * @param NodeEvent $event
117
     */
118
    public function onPostUnPublish(NodeEvent $event)
119
    {
120
        $this->delete($event);
121
    }
122
123
    /**
124
     * @param NodeEvent $event
125
     */
126
    public function delete(NodeEvent $event)
127
    {
128
        $this->nodePagesConfiguration->deleteNodeTranslation($event->getNodeTranslation());
129
    }
130
131
    /**
132
     * @param $nodeTranslation
133
     *
134
     * @return bool
135
     */
136
    private function hasOfflineParents(NodeTranslation $nodeTranslation)
137
    {
138
        $lang = $nodeTranslation->getLang();
139
        $node = $nodeTranslation->getNode();
140
        if (null !== $this->em) {
141
            $em = $this->em;
142
        } elseif (null !== $this->container) {
143
            $em = $this->container->get('doctrine.orm.entity_manager.abstract');
144
        } else {
145
            /* Revert to bugged behaviour to avoid BC breaking */
146
            return true;
147
        }
148
149
        foreach ($node->getParents() as $parent) {
150
            $parentNodeTranslation = $parent->getNodeTranslation($lang, true);
151
            if (null === $parentNodeTranslation) {
152
                continue;
153
            }
154
            $parentRef = $parentNodeTranslation->getRef($em);
155
            // Continue looping unless we find an offline page that is not a StructureNode
156
            if ($parentRef instanceof StructureNode || $parentNodeTranslation->isOnline()) {
157
                continue;
158
            }
159
160
            return true;
161
        }
162
163
        return false;
164
    }
165
}
166