EntityResolver   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Importance

Changes 12
Bugs 0 Features 0
Metric Value
wmc 26
eloc 59
c 12
b 0
f 0
dl 0
loc 130
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getMappingFromMetadata() 0 8 3
A getClassesFromName() 0 25 5
A getMetadataFromProperty() 0 18 4
A asAccessForCase() 0 5 2
A getMappingFromMetadataPart() 0 14 5
A __construct() 0 4 1
A getMetadataFromObject() 0 5 1
A resolve() 0 16 4
A entityNameProposal() 0 7 1
1
<?php
2
3
namespace Knp\FriendlyContexts\Doctrine;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use Doctrine\Common\Persistence\ObjectManager;
7
use Doctrine\ORM\Mapping\ClassMetadata;
8
use Knp\FriendlyContexts\Reflection\ObjectReflector;
9
use Knp\FriendlyContexts\Utils\TextFormater;
10
11
class EntityResolver
12
{
13
    const CASE_CAMEL      = 'CamelCase';
14
    const CASE_UNDERSCORE = 'UnderscoreCase';
15
16
    protected $reflector;
17
    protected $formater;
18
19
    public function __construct(ObjectReflector $reflector, TextFormater $formater)
20
    {
21
        $this->reflector = $reflector;
22
        $this->formater  = $formater;
23
    }
24
25
    public function resolve(ObjectManager $entityManager, $name, $namespaces = '')
26
    {
27
        $results = [];
28
29
        $namespaces = is_array($namespaces) ? $namespaces : [ $namespaces ];
30
31
        foreach ($namespaces as $namespace) {
32
            $results = $this->getClassesFromName($entityManager, $name, $namespace, $results);
33
        }
34
35
        if (0 === count($results)) {
36
37
            return;
38
        }
39
40
        return $results;
41
    }
42
43
    protected function getClassesFromName(ObjectManager $entityManager, $name, $namespace, array $results = [])
44
    {
45
        if (!empty($results)) {
46
47
            return $results;
48
        }
49
50
        $allMetadata = $entityManager->getMetadataFactory()->getAllMetadata();
51
        $allClass = $this->reflector->getReflectionsFromMetadata($allMetadata);
52
        foreach ($this->entityNameProposal($name) as $name) {
0 ignored issues
show
introduced by
$name is overwriting one of the parameters of this function.
Loading history...
53
            $class = array_filter(
54
                $allClass,
55
                function ($e) use ($namespace, $name) {
56
                    $nameValid = strtolower($e->getShortName()) === strtolower($name);
57
58
                    return '' === $namespace
59
                        ? $nameValid
60
                        : $namespace === substr($e->getNamespaceName(), 0, strlen($namespace)) && $nameValid
61
                    ;
62
                }
63
            );
64
            $results = array_merge($results, $class);
65
        }
66
67
        return $results;
68
    }
69
70
    public function getMetadataFromProperty(ObjectManager $entityManager, $entity, $property)
71
    {
72
        $metadata = $this->getMetadataFromObject($entityManager, $entity);
73
74
        if (null !== $map = $this->getMappingFromMetadata($metadata, $property)) {
75
            return $map;
76
        }
77
78
        if ($this->asAccessForCase($entity, $property, self::CASE_CAMEL) || $this->asAccessForCase($entity, $property, self::CASE_UNDERSCORE)) {
79
            return false;
80
        }
81
82
        throw new \RuntimeException(
83
            sprintf(
84
                'Can\'t find property %s or %s in class %s',
85
                $this->formater->toCamelCase(strtolower($property)),
86
                $this->formater->toUnderscoreCase(strtolower($property)),
87
                get_class($entity)
88
            )
89
        );
90
    }
91
92
    public function getMetadataFromObject(ObjectManager $entityManager, $object)
93
    {
94
        return $entityManager
95
            ->getMetadataFactory()
96
            ->getMetadataFor(get_class($object)
97
        );
98
    }
99
100
    public function entityNameProposal($name)
101
    {
102
        $name = strtolower(str_replace(" ", "", $name));
103
104
        $results = [Inflector::singularize($name), Inflector::pluralize($name), $name];
105
106
        return array_unique($results);
107
    }
108
109
    public function asAccessForCase($entity, $property, $case)
110
    {
111
        $method = sprintf('to%s', $case);
112
113
        return property_exists($entity, $this->formater->{$method}($property)) || method_exists($entity, 'set' . $this->formater->{$method}($property));
114
    }
115
116
    protected function getMappingFromMetadata(ClassMetadata $metadata, $property)
117
    {
118
        if (null !== $map = $this->getMappingFromMetadataPart($metadata->fieldMappings, $property)) {
119
            return $map;
120
        }
121
122
        if (null !== $map = $this->getMappingFromMetadataPart($metadata->associationMappings, $property)) {
123
            return $map;
124
        }
125
    }
126
127
    protected function getMappingFromMetadataPart($metadata, $property)
128
    {
129
        $property = trim($property);
130
131
        foreach ($metadata as $id => $map) {
132
            switch (strtolower($id)) {
133
                case strtolower($property):
134
                case strtolower($this->formater->toCamelCase($property)):
135
                case strtolower($this->formater->toUnderscoreCase($property)):
136
                    return $map;
137
            }
138
        }
139
140
        return null;
141
    }
142
143
}
144