Completed
Push — master ( c83ddd...a45884 )
by David
05:47
created

DoctrineInfo   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 12
c 2
b 0
f 0
lcom 1
cbo 3
dl 0
loc 97
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getFieldsConfig() 0 16 3
B getAssocsConfig() 0 36 6
A getAssociationTargetClass() 0 10 2
1
<?php
2
3
namespace A2lix\AutoFormBundle\ObjectInfo;
4
5
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
6
use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
7
use Doctrine\ORM\Mapping\ClassMetadataInfo;
8
9
/**
10
 * @author David ALLIX
11
 */
12
class DoctrineInfo implements ObjectInfoInterface
13
{
14
    /** @var ClassMetadataFactory */
15
    private $classMetadataFactory;
16
17
    /**
18
     * @param ClassMetadataFactory $classMetadataFactory
19
     */
20
    public function __construct(ClassMetadataFactory $classMetadataFactory)
21
    {
22
        $this->classMetadataFactory = $classMetadataFactory;
23
    }
24
25
    /**
26
     * @param string $class
27
     *
28
     * @return array
29
     */
30
    public function getFieldsConfig($class)
31
    {
32
        $fieldsConfig = [];
33
34
        $metadata = $this->classMetadataFactory->getMetadataFor($class);
35
36
        if ($fields = $metadata->getFieldNames()) {
37
            $fieldsConfig = array_fill_keys($fields, []);
38
        }
39
40
        if ($assocNames = $metadata->getAssociationNames()) {
41
            $fieldsConfig += $this->getAssocsConfig($metadata, $assocNames);
42
        }
43
44
        return $fieldsConfig;
45
    }
46
47
    /**
48
     * @param ClassMetadata $metadata
49
     * @param array         $assocNames
50
     *
51
     * @return array
52
     */
53
    private function getAssocsConfig(ClassMetadata $metadata, $assocNames)
54
    {
55
        $assocsConfigs = [];
56
57
        foreach ($assocNames as $assocName) {
58
            if (!$metadata->isAssociationInverseSide($assocName)) {
59
                continue;
60
            }
61
62
            $class = $metadata->getAssociationTargetClass($assocName);
63
64
            if ($metadata->isSingleValuedAssociation($assocName)) {
65
                $nullable = ($metadata instanceof ClassMetadataInfo) && isset($metadata->discriminatorColumn['nullable']) && $metadata->discriminatorColumn['nullable'];
66
67
                $assocsConfigs[$assocName] = [
68
                    'field_type' => 'A2lix\AutoFormBundle\Form\Type\AutoFormType',
69
                    'data_class' => $class,
70
                    'required' => !$nullable,
71
                ];
72
73
                continue;
74
            }
75
76
            $assocsConfigs[$assocName] = [
77
                'field_type' => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
78
                'entry_type' => 'A2lix\AutoFormBundle\Form\Type\AutoFormType',
79
                'entry_options' => [
80
                    'data_class' => $class,
81
                ],
82
                'allow_add' => true,
83
                'by_reference' => false,
84
            ];
85
        }
86
87
        return $assocsConfigs;
88
    }
89
90
    /**
91
     * @param string $class
92
     * @param string $fieldName
93
     *
94
     * @throws \Exception
95
     *
96
     * @return string
97
     */
98
    public function getAssociationTargetClass($class, $fieldName)
99
    {
100
        $metadata = $this->classMetadataFactory->getMetadataFor($class);
101
102
        if ($metadata->hasAssociation($fieldName)) {
103
            return $metadata->getAssociationTargetClass($fieldName);
104
        }
105
106
        throw new \Exception(sprintf('Unable to find the association target class of "%s" in %s.', $fieldName, $class));
107
    }
108
}
109