handleDocumentFromRegistry()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 25
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 2
Metric Value
c 6
b 1
f 2
dl 0
loc 25
rs 8.439
cc 5
eloc 11
nc 4
nop 1
1
<?php
2
3
/*
4
 * This file is part of Sulu.
5
 *
6
 * (c) MASSIVE ART WebServices GmbH
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 Sulu\Component\DocumentManager\Subscriber\Core;
13
14
use Sulu\Component\DocumentManager\DocumentRegistry;
15
use Sulu\Component\DocumentManager\Event\AbstractMappingEvent;
16
use Sulu\Component\DocumentManager\Event\ClearEvent;
17
use Sulu\Component\DocumentManager\Event\ConfigureOptionsEvent;
18
use Sulu\Component\DocumentManager\Event\HydrateEvent;
19
use Sulu\Component\DocumentManager\Event\PersistEvent;
20
use Sulu\Component\DocumentManager\Event\RemoveEvent;
21
use Sulu\Component\DocumentManager\Event\ReorderEvent;
22
use Sulu\Component\DocumentManager\Events;
23
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
24
25
/**
26
 * Responsible for registering and deregistering documents and PHPCR nodes
27
 * with the Document Registry.
28
 */
29
class RegistratorSubscriber implements EventSubscriberInterface
30
{
31
    /**
32
     * @var DocumentRegistry
33
     */
34
    private $documentRegistry;
35
36
    /**
37
     * @param DocumentRegistry $documentRegistry
38
     */
39
    public function __construct(
40
        DocumentRegistry $documentRegistry
41
    ) {
42
        $this->documentRegistry = $documentRegistry;
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public static function getSubscribedEvents()
49
    {
50
        return [
51
            Events::HYDRATE => [
52
                ['handleDefaultLocale', 520],
53
                ['handleDocumentFromRegistry', 510],
54
                ['handleStopPropagationAndResetLocale', 509],
55
                ['handleHydrate', 490],
56
                ['handleEndHydrate', -500],
57
            ],
58
            Events::PERSIST => [
59
                ['handlePersist', 450],
60
                ['handleNodeFromRegistry', 510],
61
                ['handleEndPersist', -500],
62
            ],
63
            Events::REMOVE => ['handleRemove', 490],
64
            Events::CLEAR => ['handleClear', 500],
65
            Events::REORDER => ['handleNodeFromRegistry', 510],
66
            Events::CONFIGURE_OPTIONS => 'configureOptions',
67
        ];
68
    }
69
70
    /**
71
     * @param ConfigureOptionsEvent $event
72
     */
73
    public function configureOptions(ConfigureOptionsEvent $event)
74
    {
75
        $options = $event->getOptions();
76
        $options->setDefaults([
77
            'rehydrate' => true,
78
        ]);
79
    }
80
81
    /**
82
     * Set the default locale for the hydration request.
83
     *
84
     * @param HydrateEvent $event
85
     */
86
    public function handleDefaultLocale(HydrateEvent $event)
87
    {
88
        // set the default locale
89
        if (null === $event->getLocale()) {
90
            $event->setLocale($this->documentRegistry->getDefaultLocale());
91
        }
92
    }
93
94
    /**
95
     * If there is already a document for the node registered, use that.
96
     *
97
     * @param HydrateEvent $event
98
     */
99
    public function handleDocumentFromRegistry(HydrateEvent $event)
100
    {
101
        if ($event->hasDocument()) {
102
            return;
103
        }
104
105
        $node = $event->getNode();
106
107
        if (!$this->documentRegistry->hasNode($node)) {
108
            return;
109
        }
110
111
        $document = $this->documentRegistry->getDocumentForNode($node);
112
113
        $event->setDocument($document);
114
115
        $options = $event->getOptions();
116
117
        // if reydration is not required (f.e. we just want to retrieve the
118
        // current state of the document, no matter it's current state) stop
119
        // further event propagation - we have the document now.
120
        if (isset($options['rehydrate']) && false === $options['rehydrate']) {
121
            $event->stopPropagation();
122
        }
123
    }
124
125
    /**
126
     * Stop propagation if the document is already loaded in the requested locale,
127
     * otherwise reset the document locale to the new locale.
128
     *
129
     * @param HydrateEvent $event
130
     */
131
    public function handleStopPropagationAndResetLocale(HydrateEvent $event)
132
    {
133
        if (!$event->hasDocument()) {
134
            return;
135
        }
136
137
        $locale = $event->getLocale();
138
        $document = $event->getDocument();
139
        $options = $event->getOptions();
140
        $originalLocale = $this->documentRegistry->getOriginalLocaleForDocument($document);
141
142
        if (
143
            (!isset($options['rehydrate']) || false === $options['rehydrate']) &&
144
            (true === $this->documentRegistry->isHydrated($document) && $originalLocale === $locale)
145
        ) {
146
            $event->stopPropagation();
147
148
            return;
149
        }
150
151
        $this->documentRegistry->updateLocale($document, $locale, $locale);
152
    }
153
154
    /**
155
     * When the hydrate request has finished, mark the document has hydrated.
156
     * This should be the last event listener called.
157
     *
158
     * @param HydrateEvent $event
159
     */
160
    public function handleEndHydrate(HydrateEvent $event)
161
    {
162
        $this->documentRegistry->markDocumentAsHydrated($event->getDocument());
163
    }
164
165
    /**
166
     * After the persist event has ended, unmark the document from being hydrated so that
167
     * it will be re-hydrated on the next request.
168
     *
169
     * TODO: There might be better ways to ensure that the document state is updated.
170
     *
171
     * @param PersistEvent $event
172
     */
173
    public function handleEndPersist(PersistEvent $event)
174
    {
175
        $this->documentRegistry->unmarkDocumentAsHydrated($event->getDocument());
176
    }
177
178
    /**
179
     * If the node for the persisted document is in the registry.
180
     *
181
     * @param PersistEvent|ReorderEvent $event
182
     */
183
    public function handleNodeFromRegistry($event)
184
    {
185
        if ($event->hasNode()) {
186
            return;
187
        }
188
189
        $document = $event->getDocument();
190
191
        if (!$this->documentRegistry->hasDocument($document)) {
192
            return;
193
        }
194
195
        $node = $this->documentRegistry->getNodeForDocument($document);
196
        $event->setNode($node);
197
    }
198
199
    /**
200
     * Register any document that has been created in the hydrate event.
201
     *
202
     * @param HydrateEvent $event
203
     */
204
    public function handleHydrate(HydrateEvent $event)
205
    {
206
        $this->handleRegister($event);
207
    }
208
209
    /**
210
     * Register any document that has been created in the persist event.
211
     *
212
     * @param PersistEvent $event
213
     */
214
    public function handlePersist(PersistEvent $event)
215
    {
216
        $this->handleRegister($event);
217
    }
218
219
    /**
220
     * Deregister removed documents.
221
     *
222
     * @param RemoveEvent $event
223
     */
224
    public function handleRemove(RemoveEvent $event)
225
    {
226
        $document = $event->getDocument();
227
        $this->documentRegistry->deregisterDocument($document);
228
    }
229
230
    /**
231
     * Clear the register on the "clear" event.
232
     *
233
     * @param ClearEvent $event
234
     */
235
    public function handleClear(ClearEvent $event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
236
    {
237
        $this->documentRegistry->clear();
238
    }
239
240
    /**
241
     * Register the document and apparently update the locale.
242
     *
243
     * TODO: Is locale handling already done above?
244
     *
245
     * @param AbstractMappingEvent $event
246
     */
247
    private function handleRegister(AbstractMappingEvent $event)
248
    {
249
        $document = $event->getDocument();
250
        $node = $event->getNode();
251
        $locale = $event->getLocale();
252
253
        if ($this->documentRegistry->hasDocument($document)) {
254
            $this->documentRegistry->updateLocale($document, $locale);
255
256
            return;
257
        }
258
259
        $this->documentRegistry->registerDocument($document, $node, $locale);
260
    }
261
}
262