MetadataAdapterProvider::getClassNameForEntities()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 14
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 24
rs 9.2222
1
<?php
2
3
namespace Malef\Associate\DoctrineOrm\Metadata;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\ORM\EntityManagerInterface;
7
use Doctrine\ORM\EntityRepository;
8
use Doctrine\ORM\Mapping\ClassMetadata;
9
use Malef\Associate\AssociateException;
10
11
class MetadataAdapterProvider
12
{
13
    /**
14
     * @var EntityManagerInterface
15
     */
16
    protected $entityManager;
17
18
    /**
19
     * @var (ClassMetadataAdapter|null)[]
20
     */
21
    protected $classMetadataAdapters = [];
22
23
    public function __construct(EntityManagerInterface $entityManager)
24
    {
25
        $this->entityManager = $entityManager;
26
    }
27
28
    /**
29
     * @throws AssociateException
30
     */
31
    public function getClassNameForEntities(ArrayCollection $objects): string
32
    {
33
        if ($objects->isEmpty()) {
34
            throw new AssociateException();
35
        }
36
37
        $firstObject = $objects->first();
38
        $classMetadataAdapter = $this->getClassMetadataAdapterByClassName(get_class($firstObject));
39
        if (!$classMetadataAdapter instanceof ClassMetadataAdapter) {
40
            throw new AssociateException();
41
        }
42
        $commonClassName = $classMetadataAdapter->getClassName();
43
44
        foreach ($objects->slice(1) as $object) {
45
            if (is_a($object, $commonClassName, true)) {
46
                continue;
47
            }
48
            $commonClassName = $classMetadataAdapter->getRootClassName();
49
            if (!is_a($object, $commonClassName, true)) {
50
                throw new AssociateException();
51
            }
52
        }
53
54
        return $commonClassName;
55
    }
56
57
    /**
58
     * @throws \Exception
59
     */
60
    public function getClassMetadataAdapterByClassName(string $className): ?ClassMetadataAdapter
61
    {
62
        if (!array_key_exists($className, $this->classMetadataAdapters)) {
63
            $this->initializeClassMetadataAdapterByClassName($className);
64
        }
65
66
        return $this->classMetadataAdapters[$className];
67
    }
68
69
    /**
70
     * @throws AssociateException
71
     */
72
    protected function initializeClassMetadataAdapterByClassName(string $className): void
73
    {
74
        $classMetadata = $this->entityManager->getClassMetadata($className);
75
        if (!$classMetadata instanceof ClassMetadata) {
76
            $this->classMetadataAdapters[$className] = null;
77
78
            return;
79
        }
80
81
        $entityRepository = $this->entityManager->getRepository($className);
82
        if (!$entityRepository instanceof EntityRepository) {
83
            throw new AssociateException();
84
        }
85
        $this->classMetadataAdapters[$className] = new ClassMetadataAdapter($this, $entityRepository, $classMetadata);
86
    }
87
}
88