Completed
Push — 1.0.x ( 21c8a9...01b334 )
by Maciej
10:27
created

HydratorFactory   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 438
Duplicated Lines 13.01 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 83.72%

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 47
c 3
b 1
f 0
lcom 1
cbo 9
dl 57
loc 438
ccs 144
cts 172
cp 0.8372
rs 8.439

6 Methods

Rating   Name   Duplication   Size   Complexity  
A setUnitOfWork() 0 4 1
A __construct() 0 14 3
C getHydratorFor() 0 36 8
A generateHydratorClasses() 0 10 3
D generateHydratorClass() 47 228 20
C hydrate() 10 49 12

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like HydratorFactory often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use HydratorFactory, and based on these observations, apply Extract Interface, too.

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
 * @author      Jonathan H. Wage <[email protected]>
39
 */
40
class HydratorFactory
41
{
42
    /**
43
     * The DocumentManager this factory is bound to.
44
     *
45
     * @var \Doctrine\ODM\MongoDB\DocumentManager
46
     */
47
    private $dm;
48
49
    /**
50
     * The UnitOfWork used to coordinate object-level transactions.
51
     *
52
     * @var \Doctrine\ODM\MongoDB\UnitOfWork
53
     */
54
    private $unitOfWork;
55
56
    /**
57
     * The EventManager associated with this Hydrator
58
     *
59
     * @var \Doctrine\Common\EventManager
60
     */
61
    private $evm;
62
63
    /**
64
     * Which algorithm to use to automatically (re)generate hydrator classes.
65
     *
66
     * @var integer
67
     */
68
    private $autoGenerate;
69
70
    /**
71
     * The namespace that contains all hydrator classes.
72
     *
73
     * @var string
74
     */
75
    private $hydratorNamespace;
76
77
    /**
78
     * The directory that contains all hydrator classes.
79
     *
80
     * @var string
81
     */
82
    private $hydratorDir;
83
84
    /**
85
     * Array of instantiated document hydrators.
86
     *
87
     * @var array
88
     */
89
    private $hydrators = array();
90
91
    /**
92
     * @param DocumentManager $dm
93
     * @param EventManager $evm
94
     * @param string $hydratorDir
95
     * @param string $hydratorNs
96
     * @param integer $autoGenerate
97
     * @throws HydratorException
98
     */
99 920
    public function __construct(DocumentManager $dm, EventManager $evm, $hydratorDir, $hydratorNs, $autoGenerate)
100
    {
101 920
        if ( ! $hydratorDir) {
102
            throw HydratorException::hydratorDirectoryRequired();
103
        }
104 920
        if ( ! $hydratorNs) {
105
            throw HydratorException::hydratorNamespaceRequired();
106
        }
107 920
        $this->dm = $dm;
108 920
        $this->evm = $evm;
109 920
        $this->hydratorDir = $hydratorDir;
110 920
        $this->hydratorNamespace = $hydratorNs;
111 920
        $this->autoGenerate = $autoGenerate;
112 920
    }
113
114
    /**
115
     * Sets the UnitOfWork instance.
116
     *
117
     * @param UnitOfWork $uow
118
     */
119 920
    public function setUnitOfWork(UnitOfWork $uow)
120
    {
121 920
        $this->unitOfWork = $uow;
122 920
    }
123
124
    /**
125
     * Gets the hydrator object for the given document class.
126
     *
127
     * @param string $className
128
     * @return \Doctrine\ODM\MongoDB\Hydrator\HydratorInterface $hydrator
129
     */
130 371
    public function getHydratorFor($className)
131
    {
132 371
        if (isset($this->hydrators[$className])) {
133 196
            return $this->hydrators[$className];
134
        }
135 371
        $hydratorClassName = str_replace('\\', '', $className) . 'Hydrator';
136 371
        $fqn = $this->hydratorNamespace . '\\' . $hydratorClassName;
137 371
        $class = $this->dm->getClassMetadata($className);
138
139 371
        if ( ! class_exists($fqn, false)) {
140 170
            $fileName = $this->hydratorDir . DIRECTORY_SEPARATOR . $hydratorClassName . '.php';
141 170
            switch ($this->autoGenerate) {
142 170
                case Configuration::AUTOGENERATE_NEVER:
143
                    require $fileName;
144
                    break;
145
                    
146 170
                case Configuration::AUTOGENERATE_ALWAYS:
147 170
                    $this->generateHydratorClass($class, $hydratorClassName, $fileName);
148 170
                    require $fileName;
149 170
                    break;
150
                    
151
                case Configuration::AUTOGENERATE_FILE_NOT_EXISTS:
152
                    if (!file_exists($fileName)) {
153
                        $this->generateHydratorClass($class, $hydratorClassName, $fileName);
154
                    }
155
                    require $fileName;
156
                    break;
157
                    
158
                case Configuration::AUTOGENERATE_EVAL:
159
                    $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...
160
                    break;
161 170
            }
162 170
        }
163 371
        $this->hydrators[$className] = new $fqn($this->dm, $this->unitOfWork, $class);
164 371
        return $this->hydrators[$className];
165
    }
166
167
    /**
168
     * Generates hydrator classes for all given classes.
169
     *
170
     * @param array $classes The classes (ClassMetadata instances) for which to generate hydrators.
171
     * @param string $toDir The target directory of the hydrator classes. If not specified, the
172
     *                      directory configured on the Configuration of the DocumentManager used
173
     *                      by this factory is used.
174
     */
175
    public function generateHydratorClasses(array $classes, $toDir = null)
176
    {
177
        $hydratorDir = $toDir ?: $this->hydratorDir;
178
        $hydratorDir = rtrim($hydratorDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
179
        foreach ($classes as $class) {
180
            $hydratorClassName = str_replace('\\', '', $class->name) . 'Hydrator';
181
            $hydratorFileName = $hydratorDir . $hydratorClassName . '.php';
182
            $this->generateHydratorClass($class, $hydratorClassName, $hydratorFileName);
183
        }
184
    }
185
186
    /**
187
     * @param ClassMetadata $class
188
     * @param string $hydratorClassName
189
     * @param string $fileName
190
     */
191 170
    private function generateHydratorClass(ClassMetadata $class, $hydratorClassName, $fileName)
192
    {
193 170
        $code = '';
194
195 170
        foreach ($class->fieldMappings as $fieldName => $mapping) {
196 170
            if (isset($mapping['alsoLoadFields'])) {
197 4
                foreach ($mapping['alsoLoadFields'] as $name) {
198 4
                    $code .= sprintf(<<<EOF
199
200
        /** @AlsoLoad("$name") */
201 4
        if (!array_key_exists('%1\$s', \$data) && array_key_exists('$name', \$data)) {
202 4
            \$data['%1\$s'] = \$data['$name'];
203
        }
204
205
EOF
206 4
                        ,
207 4
                        $mapping['name']
208 4
                    );
209 4
                }
210 4
            }
211
212 170
            if ($mapping['type'] === 'date') {
213 9
                $code .= sprintf(<<<EOF
214
215
        /** @Field(type="date") */
216
        if (isset(\$data['%1\$s'])) {
217
            \$value = \$data['%1\$s'];
218
            %3\$s
219
            \$this->class->reflFields['%2\$s']->setValue(\$document, clone \$return);
220
            \$hydratedData['%2\$s'] = \$return;
221
        }
222
223
EOF
224 9
                    ,
225 9
                    $mapping['name'],
226 9
                    $mapping['fieldName'],
227 9
                    Type::getType($mapping['type'])->closureToPHP()
228 9
                );
229
230
231 170
            } elseif ( ! isset($mapping['association'])) {
232 170
                $code .= sprintf(<<<EOF
233
234 170
        /** @Field(type="{$mapping['type']}") */
235
        if (isset(\$data['%1\$s'])) {
236
            \$value = \$data['%1\$s'];
237
            %3\$s
238
            \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
239
            \$hydratedData['%2\$s'] = \$return;
240
        }
241
242
EOF
243 170
                    ,
244 170
                    $mapping['name'],
245 170
                    $mapping['fieldName'],
246 170
                    Type::getType($mapping['type'])->closureToPHP()
247 170
                );
248 170 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...
249 46
                $code .= sprintf(<<<EOF
250
251
        /** @ReferenceOne */
252
        if (isset(\$data['%1\$s'])) {
253
            \$reference = \$data['%1\$s'];
254
            if (isset(\$this->class->fieldMappings['%2\$s']['simple']) && \$this->class->fieldMappings['%2\$s']['simple']) {
255
                \$className = \$this->class->fieldMappings['%2\$s']['targetDocument'];
256
                \$mongoId = \$reference;
257
            } else {
258
                \$className = \$this->unitOfWork->getClassNameForAssociation(\$this->class->fieldMappings['%2\$s'], \$reference);
259
                \$mongoId = \$reference['\$id'];
260
            }
261
            \$targetMetadata = \$this->dm->getClassMetadata(\$className);
262
            \$id = \$targetMetadata->getPHPIdentifierValue(\$mongoId);
263
            \$return = \$this->dm->getReference(\$className, \$id);
264
            \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
265
            \$hydratedData['%2\$s'] = \$return;
266
        }
267
268
EOF
269 46
                    ,
270 46
                    $mapping['name'],
271 46
                    $mapping['fieldName']
272 46
                );
273 113
            } elseif ($mapping['association'] === ClassMetadata::REFERENCE_ONE && $mapping['isInverseSide']) {
274 6
                if (isset($mapping['repositoryMethod']) && $mapping['repositoryMethod']) {
275 1
                    $code .= sprintf(<<<EOF
276
277
        \$className = \$this->class->fieldMappings['%2\$s']['targetDocument'];
278
        \$return = \$this->dm->getRepository(\$className)->%3\$s(\$document);
279
        \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
280
        \$hydratedData['%2\$s'] = \$return;
281
282
EOF
283 1
                        ,
284 1
                        $mapping['name'],
285 1
                        $mapping['fieldName'],
286 1
                        $mapping['repositoryMethod']
287 1
                    );
288 1
                } else {
289 6
                    $code .= sprintf(<<<EOF
290
291
        \$mapping = \$this->class->fieldMappings['%2\$s'];
292
        \$className = \$mapping['targetDocument'];
293
        \$targetClass = \$this->dm->getClassMetadata(\$mapping['targetDocument']);
294
        \$mappedByMapping = \$targetClass->fieldMappings[\$mapping['mappedBy']];
295
        \$mappedByFieldName = isset(\$mappedByMapping['simple']) && \$mappedByMapping['simple'] ? \$mapping['mappedBy'] : \$mapping['mappedBy'].'.\$id';
296
        \$criteria = array_merge(
297
            array(\$mappedByFieldName => \$data['_id']),
298
            isset(\$this->class->fieldMappings['%2\$s']['criteria']) ? \$this->class->fieldMappings['%2\$s']['criteria'] : array()
299
        );
300
        \$sort = isset(\$this->class->fieldMappings['%2\$s']['sort']) ? \$this->class->fieldMappings['%2\$s']['sort'] : array();
301
        \$return = \$this->unitOfWork->getDocumentPersister(\$className)->load(\$criteria, null, array(), 0, \$sort);
302
        \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
303
        \$hydratedData['%2\$s'] = \$return;
304
305
EOF
306 6
                        ,
307 6
                        $mapping['name'],
308 6
                        $mapping['fieldName']
309 6
                    );
310
                }
311 94 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...
312 73
                $code .= sprintf(<<<EOF
313
314
        /** @Many */
315
        \$mongoData = isset(\$data['%1\$s']) ? \$data['%1\$s'] : null;
316
        \$return = new \Doctrine\ODM\MongoDB\PersistentCollection(new \Doctrine\Common\Collections\ArrayCollection(), \$this->dm, \$this->unitOfWork);
317
        \$return->setHints(\$hints);
318
        \$return->setOwner(\$document, \$this->class->fieldMappings['%2\$s']);
319
        \$return->setInitialized(false);
320
        if (\$mongoData) {
321
            \$return->setMongoData(\$mongoData);
322
        }
323
        \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
324
        \$hydratedData['%2\$s'] = \$return;
325
326
EOF
327 73
                    ,
328 73
                    $mapping['name'],
329 73
                    $mapping['fieldName']
330 73
                );
331 93
            } elseif ($mapping['association'] === ClassMetadata::EMBED_ONE) {
332 40
                $code .= sprintf(<<<EOF
333
334
        /** @EmbedOne */
335
        if (isset(\$data['%1\$s'])) {
336
            \$embeddedDocument = \$data['%1\$s'];
337
            \$className = \$this->unitOfWork->getClassNameForAssociation(\$this->class->fieldMappings['%2\$s'], \$embeddedDocument);
338
            \$embeddedMetadata = \$this->dm->getClassMetadata(\$className);
339
            \$return = \$embeddedMetadata->newInstance();
340
341
            \$this->unitOfWork->setParentAssociation(\$return, \$this->class->fieldMappings['%2\$s'], \$document, '%1\$s');
342
343
            \$embeddedData = \$this->dm->getHydratorFactory()->hydrate(\$return, \$embeddedDocument, \$hints);
344
            \$embeddedId = \$embeddedMetadata->identifier && isset(\$embeddedData[\$embeddedMetadata->identifier]) ? \$embeddedData[\$embeddedMetadata->identifier] : null;
345
346
            \$this->unitOfWork->registerManaged(\$return, \$embeddedId, \$embeddedData);
347
348
            \$this->class->reflFields['%2\$s']->setValue(\$document, \$return);
349
            \$hydratedData['%2\$s'] = \$return;
350
        }
351
352
EOF
353 40
                    ,
354 40
                    $mapping['name'],
355 40
                    $mapping['fieldName']
356 40
                );
357 40
            }
358 170
        }
359
360 170
        $namespace = $this->hydratorNamespace;
361 170
        $code = sprintf(<<<EOF
362
<?php
363
364
namespace $namespace;
365
366
use Doctrine\ODM\MongoDB\DocumentManager;
367
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
368
use Doctrine\ODM\MongoDB\Hydrator\HydratorInterface;
369
use Doctrine\ODM\MongoDB\UnitOfWork;
370
371
/**
372
 * THIS CLASS WAS GENERATED BY THE DOCTRINE ODM. DO NOT EDIT THIS FILE.
373
 */
374 170
class $hydratorClassName implements HydratorInterface
375
{
376
    private \$dm;
377
    private \$unitOfWork;
378
    private \$class;
379
380
    public function __construct(DocumentManager \$dm, UnitOfWork \$uow, ClassMetadata \$class)
381
    {
382
        \$this->dm = \$dm;
383
        \$this->unitOfWork = \$uow;
384
        \$this->class = \$class;
385
    }
386
387
    public function hydrate(\$document, \$data, array \$hints = array())
388
    {
389
        \$hydratedData = array();
390
%s        return \$hydratedData;
391
    }
392 170
}
393
EOF
394 170
            ,
395
            $code
396 170
        );
397
398 170
        if ($fileName === false) {
399
            if ( ! class_exists($namespace . '\\' . $hydratorClassName)) {
400
                eval(substr($code, 5));
401
            }
402
        } else {
403 170
            $parentDirectory = dirname($fileName);
404
405 170
            if ( ! is_dir($parentDirectory) && (false === @mkdir($parentDirectory, 0775, true))) {
406
                throw HydratorException::hydratorDirectoryNotWritable();
407
            }
408
409 170
            if ( ! is_writable($parentDirectory)) {
410
                throw HydratorException::hydratorDirectoryNotWritable();
411
            }
412
413 170
            $tmpFileName = $fileName . '.' . uniqid('', true);
414 170
            file_put_contents($tmpFileName, $code);
415 170
            rename($tmpFileName, $fileName);
416 170
            chmod($fileName, 0664);
417
        }
418 170
    }
419
420
    /**
421
     * Hydrate array of MongoDB document data into the given document object.
422
     *
423
     * @param object $document  The document object to hydrate the data into.
424
     * @param array $data The array of document data.
425
     * @param array $hints Any hints to account for during reconstitution/lookup of the document.
426
     * @return array $values The array of hydrated values.
427
     */
428 371
    public function hydrate($document, $data, array $hints = array())
429
    {
430 371
        $metadata = $this->dm->getClassMetadata(get_class($document));
431
        // Invoke preLoad lifecycle events and listeners
432 371 View Code Duplication
        if ( ! empty($metadata->lifecycleCallbacks[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...
433 14
            $args = array(&$data);
434 14
            $metadata->invokeLifecycleCallbacks(Events::preLoad, $document, $args);
435 14
        }
436 371 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...
437 3
            $this->evm->dispatchEvent(Events::preLoad, new PreLoadEventArgs($document, $this->dm, $data));
438 3
        }
439
440
        // alsoLoadMethods may transform the document before hydration
441 371
        if ( ! empty($metadata->alsoLoadMethods)) {
442 12
            foreach ($metadata->alsoLoadMethods as $method => $fieldNames) {
443 12
                foreach ($fieldNames as $fieldName) {
444
                    // Invoke the method only once for the first field we find
445 12
                    if (array_key_exists($fieldName, $data)) {
446 8
                        $document->$method($data[$fieldName]);
447 8
                        continue 2;
448
                    }
449 10
                }
450 12
            }
451 12
        }
452
453 371
        $data = $this->getHydratorFor($metadata->name)->hydrate($document, $data, $hints);
454 371
        if ($document instanceof Proxy) {
455 62
            $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...
456 62
            $document->__setInitializer(null);
457 62
            $document->__setCloner(null);
458
            // lazy properties may be left uninitialized
459 62
            $properties = $document->__getLazyProperties();
460 62
            foreach ($properties as $propertyName => $property) {
461 24
                if ( ! isset($document->$propertyName)) {
462 9
                    $document->$propertyName = $properties[$propertyName];
463 9
                }
464 62
            }
465 62
        }
466
467
        // Invoke the postLoad lifecycle callbacks and listeners
468 371
        if ( ! empty($metadata->lifecycleCallbacks[Events::postLoad])) {
469 13
            $metadata->invokeLifecycleCallbacks(Events::postLoad, $document);
470 13
        }
471 371 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...
472 4
            $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($document, $this->dm));
473 4
        }
474
475 371
        return $data;
476
    }
477
}
478