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

HydratorFactory::generateHydratorClasses()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 8
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 4
nop 2
crap 12
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\Hydrator;
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\PreLoadEventArgs;
26
use Doctrine\ODM\MongoDB\Events;
27
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
28
use Doctrine\ODM\MongoDB\Proxy\Proxy;
29
use Doctrine\ODM\MongoDB\Types\Type;
30
use Doctrine\ODM\MongoDB\UnitOfWork;
31
use Doctrine\ODM\MongoDB\Configuration;
32
33
/**
34
 * The HydratorFactory class is responsible for instantiating a correct hydrator
35
 * type based on document's ClassMetadata
36
 *
37
 * @since       1.0
38
 */
39
class HydratorFactory
40
{
41
    /**
42
     * The DocumentManager this factory is bound to.
43
     *
44
     * @var \Doctrine\ODM\MongoDB\DocumentManager
45
     */
46
    private $dm;
47
48
    /**
49
     * The UnitOfWork used to coordinate object-level transactions.
50
     *
51
     * @var \Doctrine\ODM\MongoDB\UnitOfWork
52
     */
53
    private $unitOfWork;
54
55
    /**
56
     * The EventManager associated with this Hydrator
57
     *
58
     * @var \Doctrine\Common\EventManager
59
     */
60
    private $evm;
61
62
    /**
63
     * Which algorithm to use to automatically (re)generate hydrator classes.
64
     *
65
     * @var integer
66
     */
67
    private $autoGenerate;
68
69
    /**
70
     * The namespace that contains all hydrator classes.
71
     *
72
     * @var string
73
     */
74
    private $hydratorNamespace;
75
76
    /**
77
     * The directory that contains all hydrator classes.
78
     *
79
     * @var string
80
     */
81
    private $hydratorDir;
82
83
    /**
84
     * Array of instantiated document hydrators.
85
     *
86
     * @var array
87
     */
88
    private $hydrators = array();
89
90
    /**
91
     * @param DocumentManager $dm
92
     * @param EventManager $evm
93
     * @param string $hydratorDir
94
     * @param string $hydratorNs
95
     * @param integer $autoGenerate
96
     * @throws HydratorException
97
     */
98 1114
    public function __construct(DocumentManager $dm, EventManager $evm, $hydratorDir, $hydratorNs, $autoGenerate)
99
    {
100 1114
        if ( ! $hydratorDir) {
101
            throw HydratorException::hydratorDirectoryRequired();
102
        }
103 1114
        if ( ! $hydratorNs) {
104
            throw HydratorException::hydratorNamespaceRequired();
105
        }
106 1114
        $this->dm = $dm;
107 1114
        $this->evm = $evm;
108 1114
        $this->hydratorDir = $hydratorDir;
109 1114
        $this->hydratorNamespace = $hydratorNs;
110 1114
        $this->autoGenerate = $autoGenerate;
111 1114
    }
112
113
    /**
114
     * Sets the UnitOfWork instance.
115
     *
116
     * @param UnitOfWork $uow
117
     */
118 1114
    public function setUnitOfWork(UnitOfWork $uow)
119
    {
120 1114
        $this->unitOfWork = $uow;
121 1114
    }
122
123
    /**
124
     * Gets the hydrator object for the given document class.
125
     *
126
     * @param string $className
127
     * @return \Doctrine\ODM\MongoDB\Hydrator\HydratorInterface $hydrator
128
     */
129 412
    public function getHydratorFor($className)
130
    {
131 412
        if (isset($this->hydrators[$className])) {
132 211
            return $this->hydrators[$className];
133
        }
134 412
        $hydratorClassName = str_replace('\\', '', $className) . 'Hydrator';
135 412
        $fqn = $this->hydratorNamespace . '\\' . $hydratorClassName;
136 412
        $class = $this->dm->getClassMetadata($className);
137
138 412 View Code Duplication
        if ( ! class_exists($fqn, false)) {
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...
139 182
            $fileName = $this->hydratorDir . DIRECTORY_SEPARATOR . $hydratorClassName . '.php';
140 182
            switch ($this->autoGenerate) {
141
                case Configuration::AUTOGENERATE_NEVER:
142
                    require $fileName;
143
                    break;
144
                    
145
                case Configuration::AUTOGENERATE_ALWAYS:
146 182
                    $this->generateHydratorClass($class, $hydratorClassName, $fileName);
147 182
                    require $fileName;
148 182
                    break;
149
                    
150
                case Configuration::AUTOGENERATE_FILE_NOT_EXISTS:
151
                    if (!file_exists($fileName)) {
152
                        $this->generateHydratorClass($class, $hydratorClassName, $fileName);
153
                    }
154
                    require $fileName;
155
                    break;
156
                    
157
                case Configuration::AUTOGENERATE_EVAL:
158
                    $this->generateHydratorClass($class, $hydratorClassName, false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
159
                    break;
160
            }
161
        }
162 412
        $this->hydrators[$className] = new $fqn($this->dm, $this->unitOfWork, $class);
163 412
        return $this->hydrators[$className];
164
    }
165
166
    /**
167
     * Generates hydrator classes for all given classes.
168
     *
169
     * @param array $classes The classes (ClassMetadata instances) for which to generate hydrators.
170
     * @param string $toDir The target directory of the hydrator classes. If not specified, the
171
     *                      directory configured on the Configuration of the DocumentManager used
172
     *                      by this factory is used.
173
     */
174
    public function generateHydratorClasses(array $classes, $toDir = null)
175
    {
176
        $hydratorDir = $toDir ?: $this->hydratorDir;
177
        $hydratorDir = rtrim($hydratorDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
178
        foreach ($classes as $class) {
179
            $hydratorClassName = str_replace('\\', '', $class->name) . 'Hydrator';
180
            $hydratorFileName = $hydratorDir . $hydratorClassName . '.php';
181
            $this->generateHydratorClass($class, $hydratorClassName, $hydratorFileName);
182
        }
183
    }
184
185
    /**
186
     * @param ClassMetadata $class
187
     * @param string $hydratorClassName
188
     * @param string $fileName
189
     */
190 182
    private function generateHydratorClass(ClassMetadata $class, $hydratorClassName, $fileName)
191
    {
192 182
        $code = '';
193
194 182
        foreach ($class->fieldMappings as $fieldName => $mapping) {
195 182
            if (isset($mapping['alsoLoadFields'])) {
196 5
                foreach ($mapping['alsoLoadFields'] as $name) {
197 5
                    $code .= sprintf(<<<EOF
198
199 5
        /** @AlsoLoad("$name") */
200 5
        if (!array_key_exists('%1\$s', \$data) && array_key_exists('$name', \$data)) {
201 5
            \$data['%1\$s'] = \$data['$name'];
202
        }
203
204
EOF
205
                        ,
206 5
                        $mapping['name']
207
                    );
208
                }
209
            }
210
211 182
            if ($mapping['type'] === 'date') {
212 9
                $code .= sprintf(<<<EOF
213
214
        /** @Field(type="date") */
215
        if (isset(\$data['%1\$s'])) {
216
            \$value = \$data['%1\$s'];
217
            %3\$s
218
            \$this->class->reflFields['%2\$s']->setValue(\$document, clone \$return);
219
            \$hydratedData['%2\$s'] = \$return;
220
        }
221
222
EOF
223
                    ,
224 9
                    $mapping['name'],
225 9
                    $mapping['fieldName'],
226 9
                    Type::getType($mapping['type'])->closureToPHP()
227
                );
228
229
230 182
            } elseif ( ! isset($mapping['association'])) {
231 182
                $code .= sprintf(<<<EOF
232
233 182
        /** @Field(type="{$mapping['type']}") */
234
        if (isset(\$data['%1\$s']) || (! empty(\$this->class->fieldMappings['%2\$s']['nullable']) && array_key_exists('%1\$s', \$data))) {
235
            \$value = \$data['%1\$s'];
236
            if (\$value !== null) {
237
                \$typeIdentifier = \$this->class->fieldMappings['%2\$s']['type'];
238
                %3\$s
239
            } else {
240
                \$return = null;
241
            }
242
            \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
243
            \$hydratedData['%2\$s'] = \$return;
244
        }
245
246
EOF
247
                    ,
248 182
                    $mapping['name'],
249 182
                    $mapping['fieldName'],
250 182
                    Type::getType($mapping['type'])->closureToPHP()
251
                );
252 122 View Code Duplication
            } elseif ($mapping['association'] === ClassMetadata::REFERENCE_ONE && $mapping['isOwningSide']) {
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...
253 50
                $code .= sprintf(<<<EOF
254
255
        /** @ReferenceOne */
256
        if (isset(\$data['%1\$s'])) {
257
            \$reference = \$data['%1\$s'];
258
            if (isset(\$this->class->fieldMappings['%2\$s']['storeAs']) && \$this->class->fieldMappings['%2\$s']['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
259
                \$className = \$this->class->fieldMappings['%2\$s']['targetDocument'];
260
                \$mongoId = \$reference;
261
            } else {
262
                \$className = \$this->unitOfWork->getClassNameForAssociation(\$this->class->fieldMappings['%2\$s'], \$reference);
263
                \$mongoId = \$reference['\$id'];
264
            }
265
            \$targetMetadata = \$this->dm->getClassMetadata(\$className);
266
            \$id = \$targetMetadata->getPHPIdentifierValue(\$mongoId);
267
            \$return = \$this->dm->getReference(\$className, \$id);
268
            \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
269
            \$hydratedData['%2\$s'] = \$return;
270
        }
271
272
EOF
273
                    ,
274 50
                    $mapping['name'],
275 50
                    $mapping['fieldName']
276
                );
277 104
            } elseif ($mapping['association'] === ClassMetadata::REFERENCE_ONE && $mapping['isInverseSide']) {
278 6
                if (isset($mapping['repositoryMethod']) && $mapping['repositoryMethod']) {
279 1
                    $code .= sprintf(<<<EOF
280
281
        \$className = \$this->class->fieldMappings['%2\$s']['targetDocument'];
282
        \$return = \$this->dm->getRepository(\$className)->%3\$s(\$document);
283
        \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
284
        \$hydratedData['%2\$s'] = \$return;
285
286
EOF
287
                        ,
288 1
                        $mapping['name'],
289 1
                        $mapping['fieldName'],
290 1
                        $mapping['repositoryMethod']
291
                    );
292
                } else {
293 6
                    $code .= sprintf(<<<EOF
294
295
        \$mapping = \$this->class->fieldMappings['%2\$s'];
296
        \$className = \$mapping['targetDocument'];
297
        \$targetClass = \$this->dm->getClassMetadata(\$mapping['targetDocument']);
298
        \$mappedByMapping = \$targetClass->fieldMappings[\$mapping['mappedBy']];
299
        \$mappedByFieldName = isset(\$mappedByMapping['storeAs']) && \$mappedByMapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID ? \$mapping['mappedBy'] : \$mapping['mappedBy'].'.\$id';
300
        \$criteria = array_merge(
301
            array(\$mappedByFieldName => \$data['_id']),
302
            isset(\$this->class->fieldMappings['%2\$s']['criteria']) ? \$this->class->fieldMappings['%2\$s']['criteria'] : array()
303
        );
304
        \$sort = isset(\$this->class->fieldMappings['%2\$s']['sort']) ? \$this->class->fieldMappings['%2\$s']['sort'] : array();
305
        \$return = \$this->unitOfWork->getDocumentPersister(\$className)->load(\$criteria, null, array(), 0, \$sort);
306
        \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
307
        \$hydratedData['%2\$s'] = \$return;
308
309
EOF
310
                        ,
311 6
                        $mapping['name'],
312 6
                        $mapping['fieldName']
313
                    );
314
                }
315 103 View Code Duplication
            } elseif ($mapping['association'] === ClassMetadata::REFERENCE_MANY || $mapping['association'] === ClassMetadata::EMBED_MANY) {
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...
316 82
                $code .= sprintf(<<<EOF
317
318
        /** @Many */
319
        \$mongoData = isset(\$data['%1\$s']) ? \$data['%1\$s'] : null;
320
        \$return = \$this->dm->getConfiguration()->getPersistentCollectionFactory()->create(\$this->dm, \$this->class->fieldMappings['%2\$s']);
321
        \$return->setHints(\$hints);
322
        \$return->setOwner(\$document, \$this->class->fieldMappings['%2\$s']);
323
        \$return->setInitialized(false);
324
        if (\$mongoData) {
325
            \$return->setMongoData(\$mongoData);
326
        }
327
        \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
328
        \$hydratedData['%2\$s'] = \$return;
329
330
EOF
331
                    ,
332 82
                    $mapping['name'],
333 82
                    $mapping['fieldName']
334
                );
335 45
            } elseif ($mapping['association'] === ClassMetadata::EMBED_ONE) {
336 45
                $code .= sprintf(<<<EOF
337
338
        /** @EmbedOne */
339
        if (isset(\$data['%1\$s'])) {
340
            \$embeddedDocument = \$data['%1\$s'];
341
            \$className = \$this->unitOfWork->getClassNameForAssociation(\$this->class->fieldMappings['%2\$s'], \$embeddedDocument);
342
            \$embeddedMetadata = \$this->dm->getClassMetadata(\$className);
343
            \$return = \$embeddedMetadata->newInstance();
344
345
            \$this->unitOfWork->setParentAssociation(\$return, \$this->class->fieldMappings['%2\$s'], \$document, '%1\$s');
346
347
            \$embeddedData = \$this->dm->getHydratorFactory()->hydrate(\$return, \$embeddedDocument, \$hints);
348
            \$embeddedId = \$embeddedMetadata->identifier && isset(\$embeddedData[\$embeddedMetadata->identifier]) ? \$embeddedData[\$embeddedMetadata->identifier] : null;
349
350
            if (empty(\$hints[Query::HINT_READ_ONLY])) {
351
                \$this->unitOfWork->registerManaged(\$return, \$embeddedId, \$embeddedData);
352
            }
353
354
            \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
355
            \$hydratedData['%2\$s'] = \$return;
356
        }
357
358
EOF
359
                    ,
360 45
                    $mapping['name'],
361 182
                    $mapping['fieldName']
362
                );
363
            }
364
        }
365
366 182
        $namespace = $this->hydratorNamespace;
367 182
        $code = sprintf(<<<EOF
368
<?php
369
370 182
namespace $namespace;
371
372
use Doctrine\ODM\MongoDB\DocumentManager;
373
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
374
use Doctrine\ODM\MongoDB\Hydrator\HydratorInterface;
375
use Doctrine\ODM\MongoDB\Query\Query;
376
use Doctrine\ODM\MongoDB\UnitOfWork;
377
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
378
379
/**
380
 * THIS CLASS WAS GENERATED BY THE DOCTRINE ODM. DO NOT EDIT THIS FILE.
381
 */
382 182
class $hydratorClassName implements HydratorInterface
383
{
384
    private \$dm;
385
    private \$unitOfWork;
386
    private \$class;
387
388
    public function __construct(DocumentManager \$dm, UnitOfWork \$uow, ClassMetadata \$class)
389
    {
390
        \$this->dm = \$dm;
391
        \$this->unitOfWork = \$uow;
392
        \$this->class = \$class;
393
    }
394
395
    public function hydrate(\$document, \$data, array \$hints = array())
396
    {
397
        \$hydratedData = array();
398
%s        return \$hydratedData;
399
    }
400
}
401
EOF
402
            ,
403 182
            $code
404
        );
405
406 182
        if ($fileName === false) {
407
            if ( ! class_exists($namespace . '\\' . $hydratorClassName)) {
408
                eval(substr($code, 5));
409
            }
410 View Code Duplication
        } else {
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...
411 182
            $parentDirectory = dirname($fileName);
412
413 182
            if ( ! is_dir($parentDirectory) && (false === @mkdir($parentDirectory, 0775, true))) {
414
                throw HydratorException::hydratorDirectoryNotWritable();
415
            }
416
417 182
            if ( ! is_writable($parentDirectory)) {
418
                throw HydratorException::hydratorDirectoryNotWritable();
419
            }
420
421 182
            $tmpFileName = $fileName . '.' . uniqid('', true);
422 182
            file_put_contents($tmpFileName, $code);
423 182
            rename($tmpFileName, $fileName);
424 182
            chmod($fileName, 0664);
425
        }
426 182
    }
427
428
    /**
429
     * Hydrate array of MongoDB document data into the given document object.
430
     *
431
     * @param object $document  The document object to hydrate the data into.
432
     * @param array $data The array of document data.
433
     * @param array $hints Any hints to account for during reconstitution/lookup of the document.
434
     * @return array $values The array of hydrated values.
435
     */
436 412
    public function hydrate($document, $data, array $hints = array())
437
    {
438 412
        $metadata = $this->dm->getClassMetadata(get_class($document));
439
        // Invoke preLoad lifecycle events and listeners
440 412
        if ( ! empty($metadata->lifecycleCallbacks[Events::preLoad])) {
441 14
            $args = array(new PreLoadEventArgs($document, $this->dm, $data));
442 14
            $metadata->invokeLifecycleCallbacks(Events::preLoad, $document, $args);
443
        }
444 412 View Code Duplication
        if ($this->evm->hasListeners(Events::preLoad)) {
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...
445 3
            $this->evm->dispatchEvent(Events::preLoad, new PreLoadEventArgs($document, $this->dm, $data));
446
        }
447
448
        // alsoLoadMethods may transform the document before hydration
449 412
        if ( ! empty($metadata->alsoLoadMethods)) {
450 12
            foreach ($metadata->alsoLoadMethods as $method => $fieldNames) {
451 12
                foreach ($fieldNames as $fieldName) {
452
                    // Invoke the method only once for the first field we find
453 12
                    if (array_key_exists($fieldName, $data)) {
454 8
                        $document->$method($data[$fieldName]);
455 12
                        continue 2;
456
                    }
457
                }
458
            }
459
        }
460
461 412
        $data = $this->getHydratorFor($metadata->name)->hydrate($document, $data, $hints);
462 412
        if ($document instanceof Proxy) {
463 69
            $document->__isInitialized__ = true;
0 ignored issues
show
Bug introduced by
Accessing __isInitialized__ on the interface Doctrine\ODM\MongoDB\Proxy\Proxy suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
464 69
            $document->__setInitializer(null);
465 69
            $document->__setCloner(null);
466
            // lazy properties may be left uninitialized
467 69
            $properties = $document->__getLazyProperties();
468 69
            foreach ($properties as $propertyName => $property) {
469 27
                if ( ! isset($document->$propertyName)) {
470 27
                    $document->$propertyName = $properties[$propertyName];
471
                }
472
            }
473
        }
474
475
        // Invoke the postLoad lifecycle callbacks and listeners
476 412 View Code Duplication
        if ( ! empty($metadata->lifecycleCallbacks[Events::postLoad])) {
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...
477 13
            $metadata->invokeLifecycleCallbacks(Events::postLoad, $document, array(new LifecycleEventArgs($document, $this->dm)));
478
        }
479 412 View Code Duplication
        if ($this->evm->hasListeners(Events::postLoad)) {
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...
480 4
            $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($document, $this->dm));
481
        }
482
483 412
        return $data;
484
    }
485
}
486