Passed
Branch master (a38afe)
by David
02:46
created

DoctrineORMInfo::getFieldsConfig()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 4
nop 1
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
ccs 8
cts 8
cp 1
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the AutoFormBundle package.
7
 *
8
 * (c) David ALLIX <http://a2lix.fr>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace A2lix\AutoFormBundle\ObjectInfo;
15
16
use A2lix\AutoFormBundle\Form\Type\AutoFormType;
17
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
18
use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
19
use Doctrine\ORM\Mapping\ClassMetadataInfo;
20
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
21
22
class DoctrineORMInfo
23
{
24
    /** @var ClassMetadataFactory */
25
    private $classMetadataFactory;
26
27 3
    public function __construct(ClassMetadataFactory $classMetadataFactory)
28
    {
29 3
        $this->classMetadataFactory = $classMetadataFactory;
30 3
    }
31
32 3
    public function getFieldsConfig(string $class): array
33
    {
34 3
        $fieldsConfig = [];
35
36 3
        $metadata = $this->classMetadataFactory->getMetadataFor($class);
37
38 3
        if ($fields = $metadata->getFieldNames()) {
39 3
            $fieldsConfig = array_fill_keys($fields, []);
40
        }
41
42 3
        if ($assocNames = $metadata->getAssociationNames()) {
43 3
            $fieldsConfig += $this->getAssocsConfig($metadata, $assocNames);
44
        }
45
46 3
        return $fieldsConfig;
47
    }
48
49
    public function getAssociationTargetClass(string $class, string $fieldName): string
50
    {
51
        $metadata = $this->classMetadataFactory->getMetadataFor($class);
52
53
        if (!$metadata->hasAssociation($fieldName)) {
54
            throw new \RuntimeException(sprintf('Unable to find the association target class of "%s" in %s.', $fieldName, $class));
55
        }
56
57
        return $metadata->getAssociationTargetClass($fieldName);
58
    }
59
60 3
    private function getAssocsConfig(ClassMetadata $metadata, array $assocNames): array
61
    {
62 3
        $assocsConfigs = [];
63
64 3
        foreach ($assocNames as $assocName) {
65 3
            if (!$metadata->isAssociationInverseSide($assocName)) {
66 3
                continue;
67
            }
68
69 3
            $class = $metadata->getAssociationTargetClass($assocName);
70
71 3
            if ($metadata->isSingleValuedAssociation($assocName)) {
72
                $nullable = ($metadata instanceof ClassMetadataInfo) && isset($metadata->discriminatorColumn['nullable']) && $metadata->discriminatorColumn['nullable'];
73
74
                $assocsConfigs[$assocName] = [
75
                    'field_type' => AutoFormType::class,
76
                    'data_class' => $class,
77
                    'required' => !$nullable,
78
                ];
79
80
                continue;
81
            }
82
83 3
            $assocsConfigs[$assocName] = [
84 3
                'field_type' => CollectionType::class,
85
                'entry_type' => AutoFormType::class,
86
                'entry_options' => [
87 3
                    'data_class' => $class,
88
                ],
89
                'allow_add' => true,
90
                'by_reference' => false,
91
            ];
92
        }
93
94 3
        return $assocsConfigs;
95
    }
96
}
97