Completed
Pull Request — master (#1336)
by Andreas
11:45
created

LifecycleEventManager::documentNotFound()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4286
cc 1
eloc 4
nc 1
nop 2
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\DocumentNotFoundEventArgs;
25
use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
26
use Doctrine\ODM\MongoDB\Event\PreUpdateEventArgs;
27
use Doctrine\ODM\MongoDB\Events;
28
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
29
use Doctrine\ODM\MongoDB\UnitOfWork;
30
31
/**
32
 * @internal
33
 * @since 1.1
34
 */
35
class LifecycleEventManager
36
{
37
    /**
38
     * @var DocumentManager
39
     */
40
    private $dm;
41
    
42
    /**
43
     * @var EventManager
44
     */
45
    private $evm;
46
47
    /**
48
     * @var UnitOfWork
49
     */
50
    private $uow;
51
52
    /**
53
     * @param DocumentManager $dm
54
     * @param UnitOfWork $uow
55
     * @param EventManager $evm
56
     */
57 939
    public function __construct(DocumentManager $dm, UnitOfWork $uow, EventManager $evm)
58
    {
59 939
        $this->dm = $dm;
60 939
        $this->evm = $evm;
61 939
        $this->uow = $uow;
62 939
    }
63
64
    /**
65
     * @param object $proxy
66
     * @param mixed $id
67
     * @return bool Returns whether the exceptionDisabled flag was set
68
     */
69 9
    public function documentNotFound($proxy, $id)
70
    {
71 9
        $eventArgs = new DocumentNotFoundEventArgs($proxy, $id);
72 9
        $this->evm->dispatchEvent(Events::documentNotFound, $eventArgs);
73
74 9
        return $eventArgs->isExceptionDisabled();
75
    }
76
77
    /**
78
     * Invokes postPersist callbacks and events for given document cascading them to embedded documents as well.
79
     *
80
     * @param ClassMetadata $class
81
     * @param object $document
82
     */
83 554
    public function postPersist(ClassMetadata $class, $document)
84
    {
85 554
        $class->invokeLifecycleCallbacks(Events::postPersist, $document, array(new LifecycleEventArgs($document, $this->dm)));
86 554
        $this->evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($document, $this->dm));
87 554
        $this->cascadePostPersist($class, $document);
88 554
    }
89
90
    /**
91
     * Invokes postRemove callbacks and events for given document.
92
     *
93
     * @param ClassMetadata $class
94
     * @param object $document
95
     */
96 61
    public function postRemove(ClassMetadata $class, $document)
97
    {
98 61
        $class->invokeLifecycleCallbacks(Events::postRemove, $document, array(new LifecycleEventArgs($document, $this->dm)));
99 61
        $this->evm->dispatchEvent(Events::postRemove, new LifecycleEventArgs($document, $this->dm));
100 61
    }
101
102
    /**
103
     * Invokes postUpdate callbacks and events for given document. The same will be done for embedded documents owned
104
     * by given document unless they were new in which case postPersist callbacks and events will be dispatched.
105
     *
106
     * @param ClassMetadata $class
107
     * @param object $document
108
     */
109 215
    public function postUpdate(ClassMetadata $class, $document)
110
    {
111 215
        $class->invokeLifecycleCallbacks(Events::postUpdate, $document, array(new LifecycleEventArgs($document, $this->dm)));
112 215
        $this->evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($document, $this->dm));
113 215
        $this->cascadePostUpdate($class, $document);
114 215
    }
115
116
    /**
117
     * Invokes prePersist callbacks and events for given document.
118
     *
119
     * @param ClassMetadata $class
120
     * @param object $document
121
     */
122 584
    public function prePersist(ClassMetadata $class, $document)
123
    {
124 584
        $class->invokeLifecycleCallbacks(Events::prePersist, $document, array(new LifecycleEventArgs($document, $this->dm)));
125 584
        $this->evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($document, $this->dm));
126 584
    }
127
128
    /**
129
     * Invokes prePersist callbacks and events for given document.
130
     *
131
     * @param ClassMetadata $class
132
     * @param object $document
133
     */
134 67
    public function preRemove(ClassMetadata $class, $document)
135
    {
136 67
        $class->invokeLifecycleCallbacks(Events::preRemove, $document, array(new LifecycleEventArgs($document, $this->dm)));
137 67
        $this->evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($document, $this->dm));
138 67
    }
139
140
    /**
141
     * Invokes preUpdate callbacks and events for given document cascading them to embedded documents as well.
142
     *
143
     * @param ClassMetadata $class
144
     * @param object $document
145
     */
146 219
    public function preUpdate(ClassMetadata $class, $document)
147
    {
148 219
        if ( ! empty($class->lifecycleCallbacks[Events::preUpdate])) {
149 12
            $class->invokeLifecycleCallbacks(Events::preUpdate, $document, array(
150 12
                new PreUpdateEventArgs($document, $this->dm, $this->uow->getDocumentChangeSet($document))
151 12
            ));
152 12
            $this->uow->recomputeSingleDocumentChangeSet($class, $document);
153 12
        }
154 219
        $this->evm->dispatchEvent(Events::preUpdate, new PreUpdateEventArgs($document, $this->dm, $this->uow->getDocumentChangeSet($document)));
155 219
        $this->cascadePreUpdate($class, $document);
156 219
    }
157
158
    /**
159
     * Cascades the preUpdate event to embedded documents.
160
     *
161
     * @param ClassMetadata $class
162
     * @param object $document
163
     */
164 219
    private function cascadePreUpdate(ClassMetadata $class, $document)
165
    {
166 219
        foreach ($class->getEmbeddedFieldsMappings() as $mapping) {
167 134
            $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
168 134
            if ($value === null) {
169 49
                continue;
170
            }
171 132
            $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value;
172
173 132
            foreach ($values as $entry) {
174 85
                if ($this->uow->isScheduledForInsert($entry) || empty($this->uow->getDocumentChangeSet($entry))) {
175 71
                    continue;
176
                }
177 45
                $this->preUpdate($this->dm->getClassMetadata(get_class($entry)), $entry);
178 132
            }
179 219
        }
180 219
    }
181
182
    /**
183
     * Cascades the postUpdate and postPersist events to embedded documents.
184
     *
185
     * @param ClassMetadata $class
186
     * @param object $document
187
     */
188 215
    private function cascadePostUpdate(ClassMetadata $class, $document)
189
    {
190 215
        foreach ($class->getEmbeddedFieldsMappings() as $mapping) {
191 130
            $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
192 130
            if ($value === null) {
193 52
                continue;
194
            }
195 128
            $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value;
196
197 128
            foreach ($values as $entry) {
198 85
                if (empty($this->uow->getDocumentChangeSet($entry)) && ! $this->uow->hasScheduledCollections($entry)) {
199 48
                    continue;
200
                }
201 67
                $entryClass = $this->dm->getClassMetadata(get_class($entry));
202 67
                $event = $this->uow->isScheduledForInsert($entry) ? Events::postPersist : Events::postUpdate;
203 67
                $entryClass->invokeLifecycleCallbacks($event, $entry, array(new LifecycleEventArgs($entry, $this->dm)));
204 67
                $this->evm->dispatchEvent($event, new LifecycleEventArgs($entry, $this->dm));
205
206 67
                $this->cascadePostUpdate($entryClass, $entry);
207 128
            }
208 215
        }
209 215
    }
210
211
    /**
212
     * Cascades the postPersist events to embedded documents.
213
     *
214
     * @param ClassMetadata $class
215
     * @param object $document
216
     */
217 554
    private function cascadePostPersist(ClassMetadata $class, $document)
218
    {
219 554
        foreach ($class->getEmbeddedFieldsMappings() as $mapping) {
220 337
            $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
221 337
            if ($value === null) {
222 216
                continue;
223
            }
224 318
            $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value;
225 318
            foreach ($values as $embeddedDocument) {
226 159
                $this->postPersist($this->dm->getClassMetadata(get_class($embeddedDocument)), $embeddedDocument);
227 318
            }
228 554
        }
229 554
    }
230
}
231