Completed
Push — master ( 743030...781f26 )
by Vladimir
02:28
created

DoctrineInfo::__construct()   A

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