Passed
Push — master ( d3a6ec...c169ec )
by Vladimir
02:30 queued 15s
created

DoctrineEntityFieldsExtractor::getAssocsConfig()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 2
1
<?php
2
3
namespace Koff\Bundle\I18nFormBundle\Extractor;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Doctrine\ORM\Mapping\ClassMetadata;
7
use Koff\Bundle\I18nFormBundle\Form\Type\AutoFormType;
8
9
/**
10
 * Class DoctrineEntityFieldsExtractor.
11
 *
12
 * @author David ALLIX
13
 * @author Sadicov Vladimir <[email protected]>
14
 */
15
class DoctrineEntityFieldsExtractor implements FieldsExtractorInterface
16
{
17
    /** @var EntityManagerInterface */
18
    private $entityManager;
19
20
    /**
21
     * @param EntityManagerInterface $entityManager
22
     */
23
    public function __construct(EntityManagerInterface $entityManager)
24
    {
25
        $this->entityManager = $entityManager;
26
    }
27
28
    /**
29
     * @param string $class
30
     *
31
     * @return array
32
     */
33
    public function getFieldsConfig($class)
34
    {
35
        $fieldsConfig = [];
36
37
        $metadata = $this->entityManager->getClassMetadata($class);
38
39
        if ($fields = $metadata->getFieldNames()) {
40
            $fieldsConfig = array_fill_keys($fields, []);
41
        }
42
43
        if ($assocNames = $metadata->getAssociationNames()) {
44
            $fieldsConfig += $this->getAssocsConfig($metadata, $assocNames);
45
        }
46
47
        return $fieldsConfig;
48
    }
49
50
    /**
51
     * @param ClassMetadata $metadata
52
     * @param array         $assocNames
53
     *
54
     * @return array
55
     */
56
    private function getAssocsConfig(ClassMetadata $metadata, $assocNames)
57
    {
58
        $assocsConfigs = [];
59
60
        foreach ($assocNames as $assocName) {
61
            if ($metadata->isAssociationInverseSide($assocName)) {
62
                $class = $metadata->getAssociationTargetClass($assocName);
63
64
                $assocsConfigs[$assocName] = $this->generateConfig($class, $metadata, $assocName);
65
            }
66
        }
67
68
        return $assocsConfigs;
69
    }
70
71
    /**
72
     * @param string        $class
73
     * @param ClassMetadata $metadata
74
     * @param string        $assocName
75
     *
76
     * @return array
77
     */
78
    private function generateConfig($class, ClassMetadata $metadata, $assocName)
79
    {
80
        if ($metadata->isSingleValuedAssociation($assocName)) {
81
            return [
82
                'field_type' => AutoFormType::class,
83
                'data_class' => $class,
84
                'required' => !(array_key_exists('nullable', $metadata->discriminatorColumn) && $metadata->discriminatorColumn['nullable']),
85
            ];
86
        }
87
88
        return [
89
            'field_type' => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
90
            'entry_type' => AutoFormType::class,
91
            'entry_options' => [
92
                'data_class' => $class,
93
            ],
94
            'allow_add' => true,
95
            'by_reference' => false,
96
        ];
97
    }
98
99
    /**
100
     * @param string $class
101
     * @param string $fieldName
102
     *
103
     * @throws \Exception
104
     *
105
     * @return string
106
     */
107
    public function getAssociationTargetClass($class, $fieldName)
108
    {
109
        $metadata = $this->entityManager->getClassMetadata($class);
110
111
        if (!$metadata->hasAssociation($fieldName)) {
112
            throw new \Exception(
113
                sprintf('Unable to find the association target class of "%s" in %s.', $fieldName, $class)
114
            );
115
        }
116
117
        return $metadata->getAssociationTargetClass($fieldName);
118
    }
119
}
120