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

DoctrineORMManipulator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
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\Form\Manipulator;
15
16
use A2lix\AutoFormBundle\ObjectInfo\DoctrineORMInfo;
17
use Doctrine\Common\Util\ClassUtils;
18
use Symfony\Component\Form\FormInterface;
19
20
class DoctrineORMManipulator implements FormManipulatorInterface
21
{
22
    /** @var DoctrineORMInfo */
23
    private $doctrineORMInfo;
24
    /** @var array */
25
    private $globalExcludedFields;
26
27 3
    public function __construct(DoctrineORMInfo $doctrineORMInfo, array $globalExcludedFields = [])
28
    {
29 3
        $this->doctrineORMInfo = $doctrineORMInfo;
30 3
        $this->globalExcludedFields = $globalExcludedFields;
31 3
    }
32
33 3
    public function getFieldsConfig(FormInterface $form): array
34
    {
35 3
        $class = $this->getDataClass($form);
36 3
        $formOptions = $form->getConfig()->getOptions();
37
38
        // Filtering to remove excludedFields
39 3
        $objectFieldsConfig = $this->doctrineORMInfo->getFieldsConfig($class);
40 3
        $usuableObjectFieldsConfig = $this->filteringUsuableFields($objectFieldsConfig, $formOptions['excluded_fields']);
41
42 3
        if (empty($formOptions['fields'])) {
43 3
            return $usuableObjectFieldsConfig;
44
        }
45
46
        // Check unknows fields
47
        $unknowsFields = array_diff(array_keys($formOptions['fields']), array_keys($usuableObjectFieldsConfig));
48
        if (count($unknowsFields)) {
49
            throw new \RuntimeException(sprintf("Field(s) '%s' doesn't exist in %s", implode(', ', $unknowsFields), $class));
50
        }
51
52
        foreach ($formOptions['fields'] as $formFieldName => $formFieldConfig) {
53
            if (null === $formFieldConfig) {
54
                continue;
55
            }
56
57
            // If display undesired, remove
58
            if (isset($formFieldConfig['display']) && (false === $formFieldConfig['display'])) {
59
                unset($usuableObjectFieldsConfig[$formFieldName]);
60
                continue;
61
            }
62
63
            // Override with formFieldsConfig priority
64
            $usuableObjectFieldsConfig[$formFieldName] = $formFieldConfig + $usuableObjectFieldsConfig[$formFieldName];
65
        }
66
67
        return $usuableObjectFieldsConfig;
68
    }
69
70 3
    private function getDataClass(FormInterface $form): string
71
    {
72
        // Simple case, data_class from current form
73 3
        if ($dataClass = $form->getConfig()->getDataClass()) {
74 3
            return ClassUtils::getRealClass($dataClass);
75
        }
76
77
        // Advanced case, loop parent form to get closest fill data_class
78
        while ($formParent = $form->getParent()) {
79
            if (!$dataClass = $formParent->getConfig()->getDataClass()) {
80
                $form = $formParent;
81
                continue;
82
            }
83
84
            return $this->doctrineORMInfo->getAssociationTargetClass($dataClass, $form->getName());
85
        }
86
87
        throw new \RuntimeException('Unable to get dataClass');
88
    }
89
90 3
    private function filteringUsuableFields(array $objectFieldsConfig, array $formExcludedFields): array
91
    {
92 3
        $excludedFields = array_merge($this->globalExcludedFields, $formExcludedFields);
93
94 3
        $usualableFields = [];
95 3
        foreach ($objectFieldsConfig as $fieldName => $fieldConfig) {
96 3
            if (in_array($fieldName, $excludedFields, true)) {
97 3
                continue;
98
            }
99
100 3
            $usualableFields[$fieldName] = $fieldConfig;
101
        }
102
103 3
        return $usualableFields;
104
    }
105
}
106