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

DefaultManipulator   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 15
dl 0
loc 105
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getDataClass() 0 15 4
C getFieldsConfig() 0 40 7
A __construct() 0 4 1
A filteringUsuableFields() 0 14 3
1
<?php
2
3
namespace Koff\Bundle\I18nFormBundle\Form\Manipulator;
4
5
use Koff\Bundle\I18nFormBundle\ObjectInfo\ObjectInfoInterface;
6
use Doctrine\Common\Util\ClassUtils;
7
use Symfony\Component\Form\FormInterface;
8
9
class DefaultManipulator implements FormManipulatorInterface
10
{
11
    /** @var ObjectInfoInterface */
12
    private $objectInfo;
13
    /** @var array */
14
    private $globalExcludedFields;
15
16
    /**
17
     * @param ObjectInfoInterface $objectInfo
18
     * @param array               $globalExcludedFields
19
     */
20
    public function __construct(ObjectInfoInterface $objectInfo, array $globalExcludedFields = [])
21
    {
22
        $this->objectInfo = $objectInfo;
23
        $this->globalExcludedFields = $globalExcludedFields;
24
    }
25
26
    /**
27
     * {@inheritdoc}
28
     */
29
    public function getFieldsConfig(FormInterface $form)
30
    {
31
        $class = $this->getDataClass($form);
32
        $formOptions = $form->getConfig()->getOptions();
33
34
        // Filtering to remove excludedFields
35
        $objectFieldsConfig = $this->objectInfo->getFieldsConfig($class);
0 ignored issues
show
Bug introduced by
The method getFieldsConfig() does not exist on Koff\Bundle\I18nFormBund...nfo\ObjectInfoInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Koff\Bundle\I18nFormBund...nfo\ObjectInfoInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

35
        /** @scrutinizer ignore-call */ 
36
        $objectFieldsConfig = $this->objectInfo->getFieldsConfig($class);
Loading history...
36
        $usuableObjectFieldsConfig = $this->filteringUsuableFields(
37
            $objectFieldsConfig,
38
            $formOptions['excluded_fields']
39
        );
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(
49
                sprintf("Field(s) '%s' doesn't exist in %s", implode(', ', $unknowsFields), $class)
50
            );
51
        }
52
53
        foreach ($formOptions['fields'] as $formFieldName => $formFieldConfig) {
54
            if (null === $formFieldConfig) {
55
                continue;
56
            }
57
58
            // If display undesired, remove
59
            if (isset($formFieldConfig['display']) && (false === $formFieldConfig['display'])) {
60
                unset($usuableObjectFieldsConfig[$formFieldName]);
61
                continue;
62
            }
63
64
            // Override with formFieldsConfig priority
65
            $usuableObjectFieldsConfig[$formFieldName] = $formFieldConfig + $usuableObjectFieldsConfig[$formFieldName];
66
        }
67
68
        return $usuableObjectFieldsConfig;
69
    }
70
71
    /**
72
     * @param FormInterface $form
73
     *
74
     * @return string
75
     */
76
    private function getDataClass(FormInterface $form)
77
    {
78
        // Simple case, data_class from current form
79
        if ($dataClass = $form->getConfig()->getDataClass()) {
80
            return ClassUtils::getRealClass($dataClass);
81
        }
82
83
        // Advanced case, loop parent form to get closest fill data_class
84
        while ($formParent = $form->getParent()) {
85
            if (!$dataClass = $formParent->getConfig()->getDataClass()) {
86
                $form = $formParent;
87
                continue;
88
            }
89
90
            return $this->objectInfo->getAssociationTargetClass($dataClass, $form->getName());
0 ignored issues
show
Bug introduced by
The method getAssociationTargetClass() does not exist on Koff\Bundle\I18nFormBund...nfo\ObjectInfoInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Koff\Bundle\I18nFormBund...nfo\ObjectInfoInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

90
            return $this->objectInfo->/** @scrutinizer ignore-call */ getAssociationTargetClass($dataClass, $form->getName());
Loading history...
91
        }
92
    }
93
94
    /**
95
     * @param array $objectFieldsConfig
96
     * @param array $formExcludedFields
97
     *
98
     * @return array
99
     */
100
    private function filteringUsuableFields(array $objectFieldsConfig, array $formExcludedFields)
101
    {
102
        $excludedFields = array_merge($this->globalExcludedFields, $formExcludedFields);
103
104
        $usualableFields = [];
105
        foreach ($objectFieldsConfig as $fieldName => $fieldConfig) {
106
            if (in_array($fieldName, $excludedFields, true)) {
107
                continue;
108
            }
109
110
            $usualableFields[$fieldName] = $fieldConfig;
111
        }
112
113
        return $usualableFields;
114
    }
115
}
116