Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

"ComposedObject" Annotation does not add inputSpec to element configuration #125

Open
prendit opened this issue Oct 20, 2016 · 1 comment

Comments

@prendit
Copy link

prendit commented Oct 20, 2016

I noticed, that my form was not validating correctly. After some digging in code, I found, that although inputSpec is properly set in ElementAnnotationsListener::handleComposedObjectAnnotation, it gets ignored in AnnotationBuilder::configureElement

So here is what I found was causing it, and how I fixed it (although I am not sure, if that is correct):
AnnotationBulder.php:

    protected function configureElement($annotations, $reflection, $formSpec, $filterSpec)
    {
        // If the element is marked as exclude, return early
        if ($this->checkForExclude($annotations)) {
            return;
        }

        $events = $this->getEventManager();
        $name   = $this->discoverName($annotations, $reflection);

        $elementSpec = new ArrayObject([
            'flags' => [],
            'spec'  => [
                'name' => $name
            ],
        ]);
        $inputSpec = new ArrayObject([
            'name' => $name,
        ]);

        $params = [
            'name'        => $name,
            'elementSpec' => $elementSpec,
            'inputSpec'   => $inputSpec,  // Before the fix, this would not change its vallue
            'formSpec'    => $formSpec,
            'filterSpec'  => $filterSpec,
        ];
        foreach ($annotations as $annotation) {
            $params['annotation'] = $annotation;
// -> This causes ElementAnnotationsListener::handleComposedObjectAnnotation to configure the element
            $events->trigger(__FUNCTION__, $this, $params);
        }
        // Rest of the code is omitted (not relevant)
    }

ElementAnnotationsListener.php:

public function handleComposedObjectAnnotation($e)
    {
        $annotation = $e->getParam('annotation');
        if (!$annotation instanceof ComposedObject) {
            return;
        }

        $class             = $annotation->getComposedObject();
        $annotationManager = $e->getTarget();
        $specification     = $annotationManager->getFormSpecification($class);

        $name        = $e->getParam('name');
        $elementSpec = $e->getParam('elementSpec');

        if ($annotation->isCollection()) {
// Omitted, not relevant
        } else {
            // Compose input filter into parent input filter
            $inputFilter = $specification['input_filter'];
            if (!isset($inputFilter['type'])) {
                $inputFilter['type'] = 'Zend\InputFilter\InputFilter';
            }

// So here is what causes the problem:
// For some reason setting inputSpec like this causes it to be ignored in AnnotationBuilder::configureElement
//            $e->setParam('inputSpec', $inputFilter);
// This seems to work, now the composed object receives the correct inputSpec
            /** @var ArrayObject $inputSpec */
            $inputSpec = $e->getParam('inputSpec');
            $inputSpec->exchangeArray($inputFilter);

            unset($specification['input_filter']);
// Rest of the code is omitted, not relevant
        }
    }

I don't believe that this is expected behavior, because every other aspect of the element configuration can be set in ElementAnnotationsListener::handleComposedObjectAnnotation.

@weierophinney
Copy link
Member

This repository has been closed and moved to laminas/laminas-form; a new issue has been opened at laminas/laminas-form#22.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants