Completed
Push — master ( 3158b4...6fdefb )
by Vladimir
02:20
created

DoctrineInfo::getAssocsConfig()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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