Completed
Push — master ( 189f41...f9b696 )
by Tom
9s
created

checkForExcludeElementFromMetadata()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
ccs 12
cts 12
cp 1
rs 9.2
cc 4
eloc 10
nc 6
nop 2
crap 4
1
<?php
2
3
namespace DoctrineORMModule\Form\Annotation;
4
5
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
6
use Doctrine\Common\Persistence\ObjectManager;
7
use DoctrineModule\Form\Element;
8
use Zend\EventManager\EventManagerInterface;
9
use Zend\Form\Annotation\AnnotationBuilder as ZendAnnotationBuilder;
10
11
/**
12
 * @author Kyle Spraggs <[email protected]>
13
 */
14
class AnnotationBuilder extends ZendAnnotationBuilder
15
{
16
    const EVENT_CONFIGURE_FIELD       = 'configureField';
17
    const EVENT_CONFIGURE_ASSOCIATION = 'configureAssociation';
18
    const EVENT_EXCLUDE_FIELD         = 'excludeField';
19
    const EVENT_EXCLUDE_ASSOCIATION   = 'excludeAssociation';
20
21
    /**
22
     * @var \Doctrine\Common\Persistence\ObjectManager
23
     */
24
    protected $objectManager;
25
26
    /**
27
     * Constructor. Ensures ObjectManager is present.
28
     *
29
     * @param \Doctrine\Common\Persistence\ObjectManager $objectManager
30
     */
31 4
    public function __construct(ObjectManager $objectManager)
32
    {
33 4
        $this->objectManager = $objectManager;
34 4
    }
35
36
    /**
37
     * {@inheritDoc}
38
     */
39 4
    public function setEventManager(EventManagerInterface $events)
40
    {
41 4
        parent::setEventManager($events);
42
43 4
        (new ElementAnnotationsListener($this->objectManager))->attach($this->getEventManager());
44
45 4
        return $this;
46
    }
47
48
    /**
49
     * Overrides the base getFormSpecification() to additionally iterate through each
50
     * field/association in the metadata and trigger the associated event.
51
     *
52
     * This allows building of a form from metadata instead of requiring annotations.
53
     * Annotations are still allowed through the ElementAnnotationsListener.
54
     *
55
     * {@inheritDoc}
56
     */
57 6
    public function getFormSpecification($entity)
58
    {
59 6
        $formSpec     = parent::getFormSpecification($entity);
60 6
        $metadata     = $this->objectManager->getClassMetadata(is_object($entity) ? get_class($entity) : $entity);
61 6
        $inputFilter  = $formSpec['input_filter'];
62
63
        $formElements = [
64 6
            Element\ObjectSelect::class,
65 6
            Element\ObjectMultiCheckbox::class,
66 6
            Element\ObjectRadio::class,
67 6
        ];
68
69 6
        foreach ($formSpec['elements'] as $key => $elementSpec) {
70 6
            $name          = isset($elementSpec['spec']['name']) ? $elementSpec['spec']['name'] : null;
71 6
            $isFormElement = (isset($elementSpec['spec']['type']) &&
72 6
                              in_array($elementSpec['spec']['type'], $formElements));
73
74 6
            if (! $name) {
75
                continue;
76
            }
77
78 6
            if (! isset($inputFilter[$name])) {
79 6
                $inputFilter[$name] = new \ArrayObject();
80 6
            }
81
82
            $params = [
83 6
                'metadata'    => $metadata,
84 6
                'name'        => $name,
85 6
                'elementSpec' => $elementSpec,
86 6
                'inputSpec'   => $inputFilter[$name],
87 6
            ];
88
89 6
            if ($this->checkForExcludeElementFromMetadata($metadata, $name)) {
90 6
                $elementSpec = $formSpec['elements'];
91 6
                unset($elementSpec[$key]);
92 6
                $formSpec['elements'] = $elementSpec;
93
94 6
                if (isset($inputFilter[$name])) {
95 6
                    unset($inputFilter[$name]);
96 6
                }
97
98 6
                $formSpec['input_filter'] = $inputFilter;
99 6
                continue;
100
            }
101
102 4
            if ($metadata->hasField($name) || (! $metadata->hasAssociation($name) && $isFormElement)) {
103 4
                $this->getEventManager()->trigger(static::EVENT_CONFIGURE_FIELD, $this, $params);
104 4
            } elseif ($metadata->hasAssociation($name)) {
105 4
                $this->getEventManager()->trigger(static::EVENT_CONFIGURE_ASSOCIATION, $this, $params);
106 4
            }
107 6
        }
108
109 6
        $formSpec['options'] = ['prefer_form_input_filter' => true];
110
111 6
        return $formSpec;
112
    }
113
114
    /**
115
     * @param ClassMetadata $metadata
116
     * @param $name
117
     * @return bool
118
     */
119 4
    protected function checkForExcludeElementFromMetadata(ClassMetadata $metadata, $name)
120
    {
121 4
        $params = ['metadata' => $metadata, 'name' => $name];
122 4
        $result = false;
123
124 4
        if ($metadata->hasField($name)) {
125 4
            $result = $this->getEventManager()->trigger(static::EVENT_EXCLUDE_FIELD, $this, $params);
126 4
        } elseif ($metadata->hasAssociation($name)) {
127 4
            $result = $this->getEventManager()->trigger(static::EVENT_EXCLUDE_ASSOCIATION, $this, $params);
128 4
        }
129
130 4
        if ($result) {
131 4
            $result = (bool)$result->last();
132 4
        }
133
134 4
        return $result;
135
    }
136
}
137