DoctrineEntityFieldsExtractor::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 1
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
    public function __construct(EntityManagerInterface $entityManager)
21
    {
22
        $this->entityManager = $entityManager;
23
    }
24
25
    /**
26
     * @param string $class
27
     */
28
    public function getFieldsConfig($class): array
29
    {
30
        $fieldsConfig = [];
31
32
        $metadata = $this->entityManager->getClassMetadata($class);
33
34
        if ($fields = $metadata->getFieldNames()) {
35
            $fieldsConfig = array_fill_keys($fields, []);
36
        }
37
38
        if ($assocNames = $metadata->getAssociationNames()) {
39
            $fieldsConfig += $this->getAssocsConfig($metadata, $assocNames);
40
        }
41
42
        return $fieldsConfig;
43
    }
44
45
    /**
46
     * @param array $assocNames
47
     */
48
    private function getAssocsConfig(ClassMetadata $metadata, $assocNames): array
49
    {
50
        $assocsConfigs = [];
51
52
        foreach ($assocNames as $assocName) {
53
            if ($metadata->isAssociationInverseSide($assocName)) {
54
                $class = $metadata->getAssociationTargetClass($assocName);
55
56
                $assocsConfigs[$assocName] = $this->generateConfig($class, $metadata, $assocName);
57
            }
58
        }
59
60
        return $assocsConfigs;
61
    }
62
63
    private function generateConfig(string $class, ClassMetadata $metadata, string $assocName): array
64
    {
65
        if ($metadata->isSingleValuedAssociation($assocName)) {
66
            return [
67
                'field_type' => AutoFormType::class,
68
                'data_class' => $class,
69
                'required' => !(\array_key_exists('nullable', $metadata->discriminatorColumn) && $metadata->discriminatorColumn['nullable']),
70
            ];
71
        }
72
73
        return [
74
            'field_type' => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
75
            'entry_type' => AutoFormType::class,
76
            'entry_options' => [
77
                'data_class' => $class,
78
            ],
79
            'allow_add' => true,
80
            'by_reference' => false,
81
        ];
82
    }
83
84
    public function getAssociationTargetClass(string $class, string $fieldName): string
85
    {
86
        $metadata = $this->entityManager->getClassMetadata($class);
87
88
        if (!$metadata->hasAssociation($fieldName)) {
89
            //TODO: Create Customized Exception
90
            throw new \Exception(sprintf('Unable to find the association target class of "%s" in %s.', $fieldName, $class));
91
        }
92
93
        return $metadata->getAssociationTargetClass($fieldName);
94
    }
95
}
96