Completed
Push — master ( c83ddd...a45884 )
by David
05:47
created

DefaultManipulator::getDataClass()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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