Completed
Pull Request — master (#602)
by Tom
07:07
created

AnnotationBuilder::getFormSpecification()   C

Complexity

Conditions 12
Paths 23

Size

Total Lines 56

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 12.0048

Importance

Changes 0
Metric Value
dl 0
loc 56
ccs 30
cts 31
cp 0.9677
rs 6.5333
c 0
b 0
f 0
cc 12
nc 23
nop 1
crap 12.0048

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace DoctrineORMModule\Form\Annotation;
6
7
use ArrayObject;
8
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
9
use Doctrine\Common\Persistence\ObjectManager;
10
use DoctrineModule\Form\Element;
11
use Laminas\EventManager\EventManagerInterface;
12
use Laminas\Form\Annotation\AnnotationBuilder as ZendAnnotationBuilder;
13
use function get_class;
14
use function in_array;
15
use function is_object;
16
17
class AnnotationBuilder extends ZendAnnotationBuilder
18
{
19
    public const EVENT_CONFIGURE_FIELD       = 'configureField';
20
    public const EVENT_CONFIGURE_ASSOCIATION = 'configureAssociation';
21
    public const EVENT_EXCLUDE_FIELD         = 'excludeField';
22
    public const EVENT_EXCLUDE_ASSOCIATION   = 'excludeAssociation';
23
24
    protected ObjectManager $objectManager;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
25
26
    /**
27
     * Constructor. Ensures ObjectManager is present.
28
     */
29
    public function __construct(ObjectManager $objectManager)
30
    {
31 4
        $this->objectManager = $objectManager;
32
    }
33 4
34 4
    /**
35
     * {@inheritDoc}
36
     */
37
    public function setEventManager(EventManagerInterface $events)
38
    {
39 4
        parent::setEventManager($events);
40
41 4
        (new ElementAnnotationsListener($this->objectManager))->attach($this->getEventManager());
42
43 4
        return $this;
44
    }
45 4
46
    /**
47
     * Overrides the base getFormSpecification() to additionally iterate through each
48
     * field/association in the metadata and trigger the associated event.
49
     *
50
     * This allows building of a form from metadata instead of requiring annotations.
51
     * Annotations are still allowed through the ElementAnnotationsListener.
52
     *
53
     * {@inheritDoc}
54
     */
55
    public function getFormSpecification($entity)
56
    {
57 6
        $formSpec    = parent::getFormSpecification($entity);
58
        $metadata    = $this->objectManager->getClassMetadata(is_object($entity) ? get_class($entity) : $entity);
59 6
        $inputFilter = $formSpec['input_filter'];
60 6
61 6
        $formElements = [
62
            Element\ObjectSelect::class,
63
            Element\ObjectMultiCheckbox::class,
64 6
            Element\ObjectRadio::class,
65
        ];
66
67
        foreach ($formSpec['elements'] as $key => $elementSpec) {
68
            $name          = $elementSpec['spec']['name'] ?? null;
69 6
            $isFormElement = (isset($elementSpec['spec']['type']) &&
70 6
                              in_array($elementSpec['spec']['type'], $formElements));
71 6
72 6
            if (! $name) {
73
                continue;
74 6
            }
75
76
            if (! isset($inputFilter[$name])) {
77
                $inputFilter[$name] = new ArrayObject();
78 6
            }
79 6
80
            $params = [
81
                'metadata'    => $metadata,
82
                'name'        => $name,
83 6
                'elementSpec' => $elementSpec,
84 6
                'inputSpec'   => $inputFilter[$name],
85 6
            ];
86 6
87
            if ($this->checkForExcludeElementFromMetadata($metadata, $name)) {
88
                $elementSpec = $formSpec['elements'];
89 6
                unset($elementSpec[$key]);
90 6
                $formSpec['elements'] = $elementSpec;
91 6
92 6
                if (isset($inputFilter[$name])) {
93
                    unset($inputFilter[$name]);
94 6
                }
95 6
96
                $formSpec['input_filter'] = $inputFilter;
97
                continue;
98 6
            }
99 6
100
            if ($metadata->hasField($name) || (! $metadata->hasAssociation($name) && $isFormElement)) {
101
                $this->getEventManager()->trigger(self::EVENT_CONFIGURE_FIELD, $this, $params);
102 4
            } elseif ($metadata->hasAssociation($name)) {
103 4
                $this->getEventManager()->trigger(self::EVENT_CONFIGURE_ASSOCIATION, $this, $params);
104 4
            }
105 4
        }
106
107
        $formSpec['options'] = ['prefer_form_input_filter' => true];
108
109 6
        return $formSpec;
110
    }
111 6
112
    /**
113
     * @return mixed
114
     */
115
    protected function checkForExcludeElementFromMetadata(ClassMetadata $metadata, string $name) : bool
116
    {
117
        $params = ['metadata' => $metadata, 'name' => $name];
118
        $result = false;
119 4
120
        if ($metadata->hasField($name)) {
121 4
            $result = $this->getEventManager()->trigger(self::EVENT_EXCLUDE_FIELD, $this, $params);
122 4
        } elseif ($metadata->hasAssociation($name)) {
123
            $result = $this->getEventManager()->trigger(self::EVENT_EXCLUDE_ASSOCIATION, $this, $params);
124 4
        }
125 4
126 4
        if ($result) {
127 4
            $result = (bool) $result->last();
128
        }
129
130 4
        return $result;
131 4
    }
132
}
133