Failed Conditions
Pull Request — master (#6392)
by Alessandro
11:37
created

EntityManager::copy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 2
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\ORM;
21
22
use Exception;
23
use Doctrine\Common\EventManager;
24
use Doctrine\DBAL\Connection;
25
use Doctrine\DBAL\DriverManager;
26
use Doctrine\DBAL\LockMode;
27
use Doctrine\ORM\Query\ResultSetMapping;
28
use Doctrine\ORM\Proxy\ProxyFactory;
29
use Doctrine\ORM\Query\FilterCollection;
30
use Doctrine\Common\Util\ClassUtils;
31
32
/**
33
 * The EntityManager is the central access point to ORM functionality.
34
 *
35
 * It is a facade to all different ORM subsystems such as UnitOfWork,
36
 * Query Language and Repository API. Instantiation is done through
37
 * the static create() method. The quickest way to obtain a fully
38
 * configured EntityManager is:
39
 *
40
 *     use Doctrine\ORM\Tools\Setup;
41
 *     use Doctrine\ORM\EntityManager;
42
 *
43
 *     $paths = array('/path/to/entity/mapping/files');
44
 *
45
 *     $config = Setup::createAnnotationMetadataConfiguration($paths);
46
 *     $dbParams = array('driver' => 'pdo_sqlite', 'memory' => true);
47
 *     $entityManager = EntityManager::create($dbParams, $config);
48
 *
49
 * For more information see
50
 * {@link http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/configuration.html}
51
 *
52
 * You should never attempt to inherit from the EntityManager: Inheritance
53
 * is not a valid extension point for the EntityManager. Instead you
54
 * should take a look at the {@see \Doctrine\ORM\Decorator\EntityManagerDecorator}
55
 * and wrap your entity manager in a decorator.
56
 *
57
 * @since   2.0
58
 * @author  Benjamin Eberlei <[email protected]>
59
 * @author  Guilherme Blanco <[email protected]>
60
 * @author  Jonathan Wage <[email protected]>
61
 * @author  Roman Borschel <[email protected]>
62
 */
63
/* final */class EntityManager implements EntityManagerInterface
64
{
65
    /**
66
     * The used Configuration.
67
     *
68
     * @var \Doctrine\ORM\Configuration
69
     */
70
    private $config;
71
72
    /**
73
     * The database connection used by the EntityManager.
74
     *
75
     * @var \Doctrine\DBAL\Connection
76
     */
77
    private $conn;
78
79
    /**
80
     * The metadata factory, used to retrieve the ORM metadata of entity classes.
81
     *
82
     * @var \Doctrine\ORM\Mapping\ClassMetadataFactory
83
     */
84
    private $metadataFactory;
85
86
    /**
87
     * The UnitOfWork used to coordinate object-level transactions.
88
     *
89
     * @var \Doctrine\ORM\UnitOfWork
90
     */
91
    private $unitOfWork;
92
93
    /**
94
     * The event manager that is the central point of the event system.
95
     *
96
     * @var \Doctrine\Common\EventManager
97
     */
98
    private $eventManager;
99
100
    /**
101
     * The proxy factory used to create dynamic proxies.
102
     *
103
     * @var \Doctrine\ORM\Proxy\ProxyFactory
104
     */
105
    private $proxyFactory;
106
107
    /**
108
     * The repository factory used to create dynamic repositories.
109
     *
110
     * @var \Doctrine\ORM\Repository\RepositoryFactory
111
     */
112
    private $repositoryFactory;
113
114
    /**
115
     * The expression builder instance used to generate query expressions.
116
     *
117
     * @var \Doctrine\ORM\Query\Expr
118
     */
119
    private $expressionBuilder;
120
121
    /**
122
     * Whether the EntityManager is closed or not.
123
     *
124
     * @var bool
125
     */
126
    private $closed = false;
127
128
    /**
129
     * Collection of query filters.
130
     *
131
     * @var \Doctrine\ORM\Query\FilterCollection
132
     */
133
    private $filterCollection;
134
135
    /**
136
     * @var \Doctrine\ORM\Cache The second level cache regions API.
137
     */
138
    private $cache;
139
140
    /**
141
     * Creates a new EntityManager that operates on the given database connection
142
     * and uses the given Configuration and EventManager implementations.
143
     *
144
     * @param \Doctrine\DBAL\Connection     $conn
145
     * @param \Doctrine\ORM\Configuration   $config
146
     * @param \Doctrine\Common\EventManager $eventManager
147
     */
148 2393
    protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager)
149
    {
150 2393
        $this->conn              = $conn;
151 2393
        $this->config            = $config;
152 2393
        $this->eventManager      = $eventManager;
153
154 2393
        $metadataFactoryClassName = $config->getClassMetadataFactoryName();
155
156 2393
        $this->metadataFactory = new $metadataFactoryClassName;
157 2393
        $this->metadataFactory->setEntityManager($this);
158 2393
        $this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl());
159
160 2393
        $this->repositoryFactory = $config->getRepositoryFactory();
161 2393
        $this->unitOfWork        = new UnitOfWork($this);
162 2393
        $this->proxyFactory      = new ProxyFactory(
163 2393
            $this,
164 2393
            $config->getProxyDir(),
165 2393
            $config->getProxyNamespace(),
166 2393
            $config->getAutoGenerateProxyClasses()
167
        );
168
169 2393
        if ($config->isSecondLevelCacheEnabled()) {
170 283
            $cacheConfig    = $config->getSecondLevelCacheConfiguration();
171 283
            $cacheFactory   = $cacheConfig->getCacheFactory();
172 283
            $this->cache    = $cacheFactory->createCache($this);
173
        }
174 2393
    }
175
176
    /**
177
     * {@inheritDoc}
178
     */
179 1878
    public function getConnection()
180
    {
181 1878
        return $this->conn;
182
    }
183
184
    /**
185
     * Gets the metadata factory used to gather the metadata of classes.
186
     *
187
     * @return \Doctrine\ORM\Mapping\ClassMetadataFactory
188
     */
189 2393
    public function getMetadataFactory()
190
    {
191 2393
        return $this->metadataFactory;
192
    }
193
194
    /**
195
     * {@inheritDoc}
196
     */
197 17
    public function getExpressionBuilder()
198
    {
199 17
        if ($this->expressionBuilder === null) {
200 17
            $this->expressionBuilder = new Query\Expr;
201
        }
202
203 17
        return $this->expressionBuilder;
204
    }
205
206
    /**
207
     * {@inheritDoc}
208
     */
209 1
    public function beginTransaction()
210
    {
211 1
        $this->conn->beginTransaction();
212 1
    }
213
214
    /**
215
     * {@inheritDoc}
216
     */
217 216
    public function getCache()
218
    {
219 216
        return $this->cache;
220
    }
221
222
    /**
223
     * {@inheritDoc}
224
     */
225 4
    public function transactional($func)
226
    {
227 4
        if (!is_callable($func)) {
228 1
            throw new \InvalidArgumentException('Expected argument of type "callable", got "' . gettype($func) . '"');
229
        }
230
231 3
        $this->conn->beginTransaction();
232
233
        try {
234 3
            $return = call_user_func($func, $this);
235
236 3
            $this->flush();
237 3
            $this->conn->commit();
238
239 3
            return $return ?: true;
240
        } catch (Exception $e) {
241
            $this->close();
242
            $this->conn->rollBack();
243
244
            throw $e;
245
        }
246
    }
247
248
    /**
249
     * {@inheritDoc}
250
     */
251 1
    public function commit()
252
    {
253 1
        $this->conn->commit();
254 1
    }
255
256
    /**
257
     * {@inheritDoc}
258
     */
259
    public function rollback()
260
    {
261
        $this->conn->rollBack();
262
    }
263
264
    /**
265
     * Returns the ORM metadata descriptor for a class.
266
     *
267
     * The class name must be the fully-qualified class name without a leading backslash
268
     * (as it is returned by get_class($obj)) or an aliased class name.
269
     *
270
     * Examples:
271
     * MyProject\Domain\User
272
     * sales:PriceRequest
273
     *
274
     * Internal note: Performance-sensitive method.
275
     *
276
     * @param string $className
277
     *
278
     * @return \Doctrine\ORM\Mapping\ClassMetadata
279
     */
280 1938
    public function getClassMetadata($className)
281
    {
282 1938
        return $this->metadataFactory->getMetadataFor($className);
283
    }
284
285
    /**
286
     * {@inheritDoc}
287
     */
288 941
    public function createQuery($dql = '')
289
    {
290 941
        $query = new Query($this);
291
292 941
        if ( ! empty($dql)) {
293 936
            $query->setDQL($dql);
294
        }
295
296 941
        return $query;
297
    }
298
299
    /**
300
     * {@inheritDoc}
301
     */
302 1
    public function createNamedQuery($name)
303
    {
304 1
        return $this->createQuery($this->config->getNamedQuery($name));
305
    }
306
307
    /**
308
     * {@inheritDoc}
309
     */
310 21
    public function createNativeQuery($sql, ResultSetMapping $rsm)
311
    {
312 21
        $query = new NativeQuery($this);
313
314 21
        $query->setSQL($sql);
315 21
        $query->setResultSetMapping($rsm);
316
317 21
        return $query;
318
    }
319
320
    /**
321
     * {@inheritDoc}
322
     */
323 1
    public function createNamedNativeQuery($name)
324
    {
325 1
        list($sql, $rsm) = $this->config->getNamedNativeQuery($name);
326
327 1
        return $this->createNativeQuery($sql, $rsm);
328
    }
329
330
    /**
331
     * {@inheritDoc}
332
     */
333 117
    public function createQueryBuilder()
334
    {
335 117
        return new QueryBuilder($this);
336
    }
337
338
    /**
339
     * Flushes all changes to objects that have been queued up to now to the database.
340
     * This effectively synchronizes the in-memory state of managed objects with the
341
     * database.
342
     *
343
     * If an entity is explicitly passed to this method only this entity and
344
     * the cascade-persist semantics + scheduled inserts/removals are synchronized.
345
     *
346
     * @param null|object|array $entity
347
     *
348
     * @return void
349
     *
350
     * @throws \Doctrine\ORM\OptimisticLockException If a version check on an entity that
351
     *         makes use of optimistic locking fails.
352
     * @throws ORMException
353
     */
354 1036
    public function flush($entity = null)
355
    {
356 1036
        $this->errorIfClosed();
357
358 1035
        $this->unitOfWork->commit($entity);
359 1026
    }
360
361
    /**
362
     * Finds an Entity by its identifier.
363
     *
364
     * @param string       $entityName  The class name of the entity to find.
365
     * @param mixed        $id          The identity of the entity to find.
366
     * @param integer|null $lockMode    One of the \Doctrine\DBAL\LockMode::* constants
367
     *                                  or NULL if no specific lock mode should be used
368
     *                                  during the search.
369
     * @param integer|null $lockVersion The version of the entity to find when using
370
     *                                  optimistic locking.
371
     *
372
     * @return object|null The entity instance or NULL if the entity can not be found.
373
     *
374
     * @throws OptimisticLockException
375
     * @throws ORMInvalidArgumentException
376
     * @throws TransactionRequiredException
377
     * @throws ORMException
378
     */
379 429
    public function find($entityName, $id, $lockMode = null, $lockVersion = null)
380
    {
381 429
        $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
382
383 429
        if ( ! is_array($id)) {
384 383
            if ($class->isIdentifierComposite) {
0 ignored issues
show
Bug introduced by
Accessing isIdentifierComposite on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
385
                throw ORMInvalidArgumentException::invalidCompositeIdentifier();
386
            }
387
388 383
            $id = [$class->identifier[0] => $id];
0 ignored issues
show
Bug introduced by
Accessing identifier on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
389
        }
390
391 429
        foreach ($id as $i => $value) {
392 429 View Code Duplication
            if (is_object($value) && $this->metadataFactory->hasMetadataFor(ClassUtils::getClass($value))) {
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...
393 7
                $id[$i] = $this->unitOfWork->getSingleIdentifierValue($value);
394
395 7
                if ($id[$i] === null) {
396 1
                    throw ORMInvalidArgumentException::invalidIdentifierBindingEntity();
397
                }
398
            }
399
        }
400
401 428
        $sortedId = [];
402
403 428 View Code Duplication
        foreach ($class->identifier as $identifier) {
0 ignored issues
show
Bug introduced by
Accessing identifier on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
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...
404 428
            if ( ! isset($id[$identifier])) {
405 1
                throw ORMException::missingIdentifierField($class->name, $identifier);
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
406
            }
407
408 427
            $sortedId[$identifier] = $id[$identifier];
409 427
            unset($id[$identifier]);
410
        }
411
412 427
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
413 1
            throw ORMException::unrecognizedIdentifierFields($class->name, array_keys($id));
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
414
        }
415
416 426
        $unitOfWork = $this->getUnitOfWork();
417
418
        // Check identity map first
419 426
        if (($entity = $unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
0 ignored issues
show
Bug introduced by
Accessing rootEntityName on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
420 46
            if ( ! ($entity instanceof $class->name)) {
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
421 1
                return null;
422
            }
423
424
            switch (true) {
425 45
                case LockMode::OPTIMISTIC === $lockMode:
426 1
                    $this->lock($entity, $lockMode, $lockVersion);
427
                    break;
428
429 45
                case LockMode::NONE === $lockMode:
430 45
                case LockMode::PESSIMISTIC_READ === $lockMode:
431 45
                case LockMode::PESSIMISTIC_WRITE === $lockMode:
432
                    $persister = $unitOfWork->getEntityPersister($class->name);
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
433
                    $persister->refresh($sortedId, $entity, $lockMode);
434
                    break;
435
            }
436
437 45
            return $entity; // Hit!
438
        }
439
440 407
        $persister = $unitOfWork->getEntityPersister($class->name);
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
441
442
        switch (true) {
443 407
            case LockMode::OPTIMISTIC === $lockMode:
444 1
                if ( ! $class->isVersioned) {
0 ignored issues
show
Bug introduced by
Accessing isVersioned on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
445 1
                    throw OptimisticLockException::notVersioned($class->name);
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
446
                }
447
448
                $entity = $persister->load($sortedId);
449
450
                $unitOfWork->lock($entity, $lockMode, $lockVersion);
0 ignored issues
show
Bug introduced by
It seems like $entity defined by $persister->load($sortedId) on line 448 can also be of type null; however, Doctrine\ORM\UnitOfWork::lock() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
451
452
                return $entity;
453
454 406
            case LockMode::PESSIMISTIC_READ === $lockMode:
455 405
            case LockMode::PESSIMISTIC_WRITE === $lockMode:
456 2
                if ( ! $this->getConnection()->isTransactionActive()) {
457 2
                    throw TransactionRequiredException::transactionRequired();
458
                }
459
460
                return $persister->load($sortedId, null, null, [], $lockMode);
461
462
            default:
463 404
                return $persister->loadById($sortedId);
464
        }
465
    }
466
467
    /**
468
     * {@inheritDoc}
469
     */
470 92
    public function getReference($entityName, $id)
471
    {
472 92
        $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
473
474 92
        if ( ! is_array($id)) {
475 49
            $id = [$class->identifier[0] => $id];
0 ignored issues
show
Bug introduced by
Accessing identifier on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
476
        }
477
478 92
        $sortedId = [];
479
480 92 View Code Duplication
        foreach ($class->identifier as $identifier) {
0 ignored issues
show
Bug introduced by
Accessing identifier on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
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...
481 92
            if ( ! isset($id[$identifier])) {
482
                throw ORMException::missingIdentifierField($class->name, $identifier);
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
483
            }
484
485 92
            $sortedId[$identifier] = $id[$identifier];
486 92
            unset($id[$identifier]);
487
        }
488
489 92
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
490 1
            throw ORMException::unrecognizedIdentifierFields($class->name, array_keys($id));
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
491
        }
492
493
        // Check identity map first, if its already in there just return it.
494 91 View Code Duplication
        if (($entity = $this->unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
0 ignored issues
show
Bug introduced by
Accessing rootEntityName on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
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...
495 27
            return ($entity instanceof $class->name) ? $entity : null;
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
496
        }
497
498 87
        if ($class->subClasses) {
0 ignored issues
show
Bug introduced by
Accessing subClasses on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
499 2
            return $this->find($entityName, $sortedId);
500
        }
501
502 87
        $entity = $this->proxyFactory->getProxy($class->name, $sortedId);
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
503
504 87
        $this->unitOfWork->registerManaged($entity, $sortedId, []);
505
506 87
        return $entity;
507
    }
508
509
    /**
510
     * {@inheritDoc}
511
     */
512 4
    public function getPartialReference($entityName, $identifier)
513
    {
514 4
        $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
515
516
        // Check identity map first, if its already in there just return it.
517 4 View Code Duplication
        if (($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) !== false) {
0 ignored issues
show
Bug introduced by
Accessing rootEntityName on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
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...
518 1
            return ($entity instanceof $class->name) ? $entity : null;
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
519
        }
520
521 3
        if ( ! is_array($identifier)) {
522 3
            $identifier = [$class->identifier[0] => $identifier];
0 ignored issues
show
Bug introduced by
Accessing identifier on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata 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...
523
        }
524
525 3
        $entity = $class->newInstance();
526
527 3
        $class->setIdentifierValues($entity, $identifier);
528
529 3
        $this->unitOfWork->registerManaged($entity, $identifier, []);
530 3
        $this->unitOfWork->markReadOnly($entity);
531
532 3
        return $entity;
533
    }
534
535
    /**
536
     * Clears the EntityManager. All entities that are currently managed
537
     * by this EntityManager become detached.
538
     *
539
     * @param string|null $entityName if given, only entities of this type will get detached
540
     *
541
     * @return void
542
     *
543
     * @throws ORMInvalidArgumentException                           if a non-null non-string value is given
544
     * @throws \Doctrine\Common\Persistence\Mapping\MappingException if a $entityName is given, but that entity is not
545
     *                                                               found in the mappings
546
     */
547 1255
    public function clear($entityName = null)
548
    {
549 1255
        if (null !== $entityName && ! is_string($entityName)) {
550 1
            throw ORMInvalidArgumentException::invalidEntityName($entityName);
551
        }
552
553 1254
        $this->unitOfWork->clear(
554 1254
            null === $entityName
555 1252
                ? null
556 1254
                : $this->metadataFactory->getMetadataFor($entityName)->getName()
557
        );
558 1253
    }
559
560
    /**
561
     * {@inheritDoc}
562
     */
563 19
    public function close()
564
    {
565 19
        $this->clear();
566
567 19
        $this->closed = true;
568 19
    }
569
570
    /**
571
     * Tells the EntityManager to make an instance managed and persistent.
572
     *
573
     * The entity will be entered into the database at or before transaction
574
     * commit or as a result of the flush operation.
575
     *
576
     * NOTE: The persist operation always considers entities that are not yet known to
577
     * this EntityManager as NEW. Do not pass detached entities to the persist operation.
578
     *
579
     * @param object $entity The instance to make managed and persistent.
580
     *
581
     * @return void
582
     *
583
     * @throws ORMInvalidArgumentException
584
     * @throws ORMException
585
     */
586 1032 View Code Duplication
    public function persist($entity)
587
    {
588 1032
        if ( ! is_object($entity)) {
589 1
            throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()', $entity);
590
        }
591
592 1031
        $this->errorIfClosed();
593
594 1030
        $this->unitOfWork->persist($entity);
595 1029
    }
596
597
    /**
598
     * Removes an entity instance.
599
     *
600
     * A removed entity will be removed from the database at or before transaction commit
601
     * or as a result of the flush operation.
602
     *
603
     * @param object $entity The entity instance to remove.
604
     *
605
     * @return void
606
     *
607
     * @throws ORMInvalidArgumentException
608
     * @throws ORMException
609
     */
610 51 View Code Duplication
    public function remove($entity)
611
    {
612 51
        if ( ! is_object($entity)) {
613 1
            throw ORMInvalidArgumentException::invalidObject('EntityManager#remove()', $entity);
614
        }
615
616 50
        $this->errorIfClosed();
617
618 49
        $this->unitOfWork->remove($entity);
619 49
    }
620
621
    /**
622
     * Refreshes the persistent state of an entity from the database,
623
     * overriding any local changes that have not yet been persisted.
624
     *
625
     * @param object $entity The entity to refresh.
626
     *
627
     * @return void
628
     *
629
     * @throws ORMInvalidArgumentException
630
     * @throws ORMException
631
     */
632 19 View Code Duplication
    public function refresh($entity)
633
    {
634 19
        if ( ! is_object($entity)) {
635 1
            throw ORMInvalidArgumentException::invalidObject('EntityManager#refresh()', $entity);
636
        }
637
638 18
        $this->errorIfClosed();
639
640 17
        $this->unitOfWork->refresh($entity);
641 17
    }
642
643
    /**
644
     * Detaches an entity from the EntityManager, causing a managed entity to
645
     * become detached.  Unflushed changes made to the entity if any
646
     * (including removal of the entity), will not be synchronized to the database.
647
     * Entities which previously referenced the detached entity will continue to
648
     * reference it.
649
     *
650
     * @param object $entity The entity to detach.
651
     *
652
     * @return void
653
     *
654
     * @throws ORMInvalidArgumentException
655
     */
656 13
    public function detach($entity)
657
    {
658 13
        if ( ! is_object($entity)) {
659 1
            throw ORMInvalidArgumentException::invalidObject('EntityManager#detach()', $entity);
660
        }
661
662 12
        $this->unitOfWork->detach($entity);
663 12
    }
664
665
    /**
666
     * Merges the state of a detached entity into the persistence context
667
     * of this EntityManager and returns the managed copy of the entity.
668
     * The entity passed to merge will not become associated/managed with this EntityManager.
669
     *
670
     * @param object $entity The detached entity to merge into the persistence context.
671
     *
672
     * @return object The managed copy of the entity.
673
     *
674
     * @throws ORMInvalidArgumentException
675
     * @throws ORMException
676
     */
677 42 View Code Duplication
    public function merge($entity)
678
    {
679 42
        if ( ! is_object($entity)) {
680 1
            throw ORMInvalidArgumentException::invalidObject('EntityManager#merge()', $entity);
681
        }
682
683 41
        $this->errorIfClosed();
684
685 40
        return $this->unitOfWork->merge($entity);
686
    }
687
688
    /**
689
     * {@inheritDoc}
690
     *
691
     * @todo Implementation need. This is necessary since $e2 = clone $e1; throws an E_FATAL when access anything on $e:
692
     * Fatal error: Maximum function nesting level of '100' reached, aborting!
693
     */
694
    public function copy($entity, $deep = false)
695
    {
696
        throw new \BadMethodCallException("Not implemented.");
697
    }
698
699
    /**
700
     * {@inheritDoc}
701
     */
702 9
    public function lock($entity, $lockMode, $lockVersion = null)
703
    {
704 9
        $this->unitOfWork->lock($entity, $lockMode, $lockVersion);
705 2
    }
706
707
    /**
708
     * Gets the repository for an entity class.
709
     *
710
     * @param string $entityName The name of the entity.
711
     *
712
     * @return \Doctrine\ORM\EntityRepository The repository class.
713
     */
714 155
    public function getRepository($entityName)
715
    {
716 155
        return $this->repositoryFactory->getRepository($this, $entityName);
717
    }
718
719
    /**
720
     * Determines whether an entity instance is managed in this EntityManager.
721
     *
722
     * @param object $entity
723
     *
724
     * @return boolean TRUE if this EntityManager currently manages the given entity, FALSE otherwise.
725
     */
726 24
    public function contains($entity)
727
    {
728 24
        return $this->unitOfWork->isScheduledForInsert($entity)
729 22
            || $this->unitOfWork->isInIdentityMap($entity)
730 24
            && ! $this->unitOfWork->isScheduledForDelete($entity);
731
    }
732
733
    /**
734
     * {@inheritDoc}
735
     */
736 2393
    public function getEventManager()
737
    {
738 2393
        return $this->eventManager;
739
    }
740
741
    /**
742
     * {@inheritDoc}
743
     */
744 2393
    public function getConfiguration()
745
    {
746 2393
        return $this->config;
747
    }
748
749
    /**
750
     * Throws an exception if the EntityManager is closed or currently not active.
751
     *
752
     * @return void
753
     *
754
     * @throws ORMException If the EntityManager is closed.
755
     */
756 1051
    private function errorIfClosed()
757
    {
758 1051
        if ($this->closed) {
759 5
            throw ORMException::entityManagerClosed();
760
        }
761 1046
    }
762
763
    /**
764
     * {@inheritDoc}
765
     */
766 1
    public function isOpen()
767
    {
768 1
        return (!$this->closed);
769
    }
770
771
    /**
772
     * {@inheritDoc}
773
     */
774 2393
    public function getUnitOfWork()
775
    {
776 2393
        return $this->unitOfWork;
777
    }
778
779
    /**
780
     * {@inheritDoc}
781
     */
782
    public function getHydrator($hydrationMode)
783
    {
784
        return $this->newHydrator($hydrationMode);
785
    }
786
787
    /**
788
     * {@inheritDoc}
789
     */
790 917
    public function newHydrator($hydrationMode)
791
    {
792
        switch ($hydrationMode) {
793 917
            case Query::HYDRATE_OBJECT:
794 634
                return new Internal\Hydration\ObjectHydrator($this);
795
796 562
            case Query::HYDRATE_ARRAY:
797 36
                return new Internal\Hydration\ArrayHydrator($this);
798
799 531
            case Query::HYDRATE_SCALAR:
800 85
                return new Internal\Hydration\ScalarHydrator($this);
801
802 448
            case Query::HYDRATE_SINGLE_SCALAR:
803 13
                return new Internal\Hydration\SingleScalarHydrator($this);
804
805 439
            case Query::HYDRATE_SIMPLEOBJECT:
806 438
                return new Internal\Hydration\SimpleObjectHydrator($this);
807
808
            default:
809 1
                if (($class = $this->config->getCustomHydrationMode($hydrationMode)) !== null) {
810 1
                    return new $class($this);
811
                }
812
        }
813
814
        throw ORMException::invalidHydrationMode($hydrationMode);
815
    }
816
817
    /**
818
     * {@inheritDoc}
819
     */
820 174
    public function getProxyFactory()
821
    {
822 174
        return $this->proxyFactory;
823
    }
824
825
    /**
826
     * {@inheritDoc}
827
     */
828
    public function initializeObject($obj)
829
    {
830
        $this->unitOfWork->initializeObject($obj);
831
    }
832
833
    /**
834
     * Factory method to create EntityManager instances.
835
     *
836
     * @param array|Connection $connection   An array with the connection parameters or an existing Connection instance.
837
     * @param Configuration    $config       The Configuration instance to use.
838
     * @param EventManager     $eventManager The EventManager instance to use.
839
     *
840
     * @return EntityManager The created EntityManager.
841
     *
842
     * @throws \InvalidArgumentException
843
     * @throws ORMException
844
     */
845 1258
    public static function create($connection, Configuration $config, EventManager $eventManager = null)
846
    {
847 1258
        if ( ! $config->getMetadataDriverImpl()) {
848
            throw ORMException::missingMappingDriverImpl();
849
        }
850
851 1258
        $connection = static::createConnection($connection, $config, $eventManager);
852
853 1257
        return new EntityManager($connection, $config, $connection->getEventManager());
854
    }
855
856
    /**
857
     * Factory method to create Connection instances.
858
     *
859
     * @param array|Connection $connection   An array with the connection parameters or an existing Connection instance.
860
     * @param Configuration    $config       The Configuration instance to use.
861
     * @param EventManager     $eventManager The EventManager instance to use.
862
     *
863
     * @return Connection
864
     *
865
     * @throws \InvalidArgumentException
866
     * @throws ORMException
867
     */
868 1258
    protected static function createConnection($connection, Configuration $config, EventManager $eventManager = null)
869
    {
870 1258
        if (is_array($connection)) {
871
            return DriverManager::getConnection($connection, $config, $eventManager ?: new EventManager());
872
        }
873
874 1258
        if ( ! $connection instanceof Connection) {
875 1
            throw new \InvalidArgumentException(
876 1
                sprintf(
877 1
                    'Invalid $connection argument of type %s given%s.',
878 1
                    is_object($connection) ? get_class($connection) : gettype($connection),
879 1
                    is_object($connection) ? '' : ': "' . $connection . '"'
880
                )
881
            );
882
        }
883
884 1257
        if ($eventManager !== null && $connection->getEventManager() !== $eventManager) {
885
            throw ORMException::mismatchedEventManager();
886
        }
887
888 1257
        return $connection;
889
    }
890
891
    /**
892
     * {@inheritDoc}
893
     */
894 631
    public function getFilters()
895
    {
896 631
        if (null === $this->filterCollection) {
897 631
            $this->filterCollection = new FilterCollection($this);
898
        }
899
900 631
        return $this->filterCollection;
901
    }
902
903
    /**
904
     * {@inheritDoc}
905
     */
906 40
    public function isFiltersStateClean()
907
    {
908 40
        return null === $this->filterCollection || $this->filterCollection->isClean();
909
    }
910
911
    /**
912
     * {@inheritDoc}
913
     */
914 752
    public function hasFilters()
915
    {
916 752
        return null !== $this->filterCollection;
917
    }
918
}
919