Completed
Pull Request — master (#1331)
by Maciej
10:31
created

LifecycleEventManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4286
c 1
b 0
f 0
cc 1
eloc 4
nc 1
nop 3
crap 1
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ODM\MongoDB\Utility;
21
22
use Doctrine\Common\EventManager;
23
use Doctrine\ODM\MongoDB\DocumentManager;
24
use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
25
use Doctrine\ODM\MongoDB\Event\PreUpdateEventArgs;
26
use Doctrine\ODM\MongoDB\Events;
27
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
28
use Doctrine\ODM\MongoDB\UnitOfWork;
29
30
/**
31
 * @internal
32
 * @since 1.1
33
 */
34
class LifecycleEventManager
35
{
36
    /**
37
     * @var DocumentManager
38
     */
39
    private $dm;
40
    
41
    /**
42
     * @var EventManager
43
     */
44
    private $evm;
45
46
    /**
47
     * @var UnitOfWork
48
     */
49
    private $uow;
50
51
    /**
52
     * @param DocumentManager $dm
53
     * @param UnitOfWork $uow
54
     * @param EventManager $evm
55
     */
56 931
    public function __construct(DocumentManager $dm, UnitOfWork $uow, EventManager $evm)
57
    {
58 931
        $this->dm = $dm;
59 931
        $this->evm = $evm;
60 931
        $this->uow = $uow;
61 931
    }
62
63
    /**
64
     * Invokes postPersist callbacks and events for given document cascading them to embedded documents as well.
65
     *
66
     * @param ClassMetadata $class
67
     * @param object $document
68
     */
69 552
    public function postPersist(ClassMetadata $class, $document)
70
    {
71 552
        $class->invokeLifecycleCallbacks(Events::postPersist, $document, array(new LifecycleEventArgs($document, $this->dm)));
72 552
        $this->evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($document, $this->dm));
73 552
        $this->cascadePostPersist($class, $document);
74 552
    }
75
76
    /**
77
     * Invokes postRemove callbacks and events for given document.
78
     *
79
     * @param ClassMetadata $class
80
     * @param object $document
81
     */
82 10
    public function postRemove(ClassMetadata $class, $document)
83
    {
84 10
        $class->invokeLifecycleCallbacks(Events::postRemove, $document, array(new LifecycleEventArgs($document, $this->dm)));
85 10
        $this->evm->dispatchEvent(Events::postRemove, new LifecycleEventArgs($document, $this->dm));
86 10
    }
87
88
    /**
89
     * Invokes postUpdate callbacks and events for given document. The same will be done for embedded documents owned
90
     * by given document unless they were new in which case postPersist callbacks and events will be dispatched.
91
     *
92
     * @param ClassMetadata $class
93
     * @param object $document
94
     */
95
    public function postUpdate(ClassMetadata $class, $document)
96
    {
97
        $class->invokeLifecycleCallbacks(Events::postUpdate, $document, array(new LifecycleEventArgs($document, $this->dm)));
98
        $this->evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($document, $this->dm));
99
        $this->cascadePostUpdate($class, $document);
100
    }
101
102
    /**
103
     * Invokes prePersist callbacks and events for given document.
104
     *
105
     * @param ClassMetadata $class
106
     * @param object $document
107
     */
108 576
    public function prePersist(ClassMetadata $class, $document)
109
    {
110 576
        $class->invokeLifecycleCallbacks(Events::prePersist, $document, array(new LifecycleEventArgs($document, $this->dm)));
111 576
        $this->evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($document, $this->dm));
112 576
    }
113
114
    /**
115
     * Invokes prePersist callbacks and events for given document.
116
     *
117
     * @param ClassMetadata $class
118
     * @param object $document
119
     */
120 48
    public function preRemove(ClassMetadata $class, $document)
121
    {
122 48
        $class->invokeLifecycleCallbacks(Events::preRemove, $document, array(new LifecycleEventArgs($document, $this->dm)));
123 48
        $this->evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($document, $this->dm));
124 48
    }
125
126
    /**
127
     * Invokes preUpdate callbacks and events for given document cascading them to embedded documents as well.
128
     *
129
     * @param ClassMetadata $class
130
     * @param object $document
131
     */
132 218
    public function preUpdate(ClassMetadata $class, $document)
133
    {
134 218
        if ( ! empty($class->lifecycleCallbacks[Events::preUpdate])) {
135 12
            $class->invokeLifecycleCallbacks(Events::preUpdate, $document, array(
136 12
                new PreUpdateEventArgs($document, $this->dm, $this->uow->getDocumentChangeSet($document))
0 ignored issues
show
Bug introduced by
$this->uow->getDocumentChangeSet($document) cannot be passed to __construct() as the parameter $changeSet expects a reference.
Loading history...
137
            ));
138
            $this->uow->recomputeSingleDocumentChangeSet($class, $document);
139
        }
140 206
        $this->evm->dispatchEvent(Events::preUpdate, new PreUpdateEventArgs($document, $this->dm, $this->uow->getDocumentChangeSet($document)));
0 ignored issues
show
Bug introduced by
$this->uow->getDocumentChangeSet($document) cannot be passed to __construct() as the parameter $changeSet expects a reference.
Loading history...
141
        $this->cascadePreUpdate($class, $document);
142
    }
143
144
    /**
145
     * Cascades the preUpdate event to embedded documents.
146
     *
147
     * @param ClassMetadata $class
148
     * @param object $document
149
     */
150
    private function cascadePreUpdate(ClassMetadata $class, $document)
151
    {
152
        foreach ($class->getEmbeddedFieldsMappings() as $mapping) {
153
            $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
154
            if ($value === null) {
155
                continue;
156
            }
157
            $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value;
158
159
            foreach ($values as $entry) {
160
                if ($this->uow->isScheduledForInsert($entry) || empty($this->uow->getDocumentChangeSet($entry))) {
161
                    continue;
162
                }
163
                $this->preUpdate($this->dm->getClassMetadata(get_class($entry)), $entry);
164
            }
165
        }
166
    }
167
168
    /**
169
     * Cascades the postUpdate and postPersist events to embedded documents.
170
     *
171
     * @param ClassMetadata $class
172
     * @param object $document
173
     */
174
    private function cascadePostUpdate(ClassMetadata $class, $document)
175
    {
176
        foreach ($class->getEmbeddedFieldsMappings() as $mapping) {
177
            $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
178
            if ($value === null) {
179
                continue;
180
            }
181
            $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value;
182
183
            foreach ($values as $entry) {
184
                if (empty($this->uow->getDocumentChangeSet($entry)) && ! $this->uow->hasScheduledCollections($entry)) {
185
                    continue;
186
                }
187
                $entryClass = $this->dm->getClassMetadata(get_class($entry));
188
                $event = $this->uow->isScheduledForInsert($entry) ? Events::postPersist : Events::postUpdate;
189
                $entryClass->invokeLifecycleCallbacks($event, $entry, array(new LifecycleEventArgs($entry, $this->dm)));
190
                $this->evm->dispatchEvent($event, new LifecycleEventArgs($entry, $this->dm));
191
192
                $this->cascadePostUpdate($entryClass, $entry);
193
            }
194
        }
195
    }
196
197
    /**
198
     * Cascades the postPersist events to embedded documents.
199
     *
200
     * @param ClassMetadata $class
201
     * @param object $document
202
     */
203 552
    private function cascadePostPersist(ClassMetadata $class, $document)
204
    {
205 552
        foreach ($class->getEmbeddedFieldsMappings() as $mapping) {
206 336
            $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
207 336
            if ($value === null) {
208 215
                continue;
209
            }
210 316
            $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value;
211 316
            foreach ($values as $embeddedDocument) {
212 158
                $this->postPersist($this->dm->getClassMetadata(get_class($embeddedDocument)), $embeddedDocument);
213 316
            }
214 552
        }
215 552
    }
216
}
217