Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
weierophinney opened this issue Dec 31, 2019 · 1 comment · Fixed by #207
Closed

Comments

@weierophinney
Copy link
Member

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.


Originally posted by @prendit at zendframework/zend-form#125

@ghost
Copy link

ghost commented Jan 3, 2020

This is messing up my code too. I tried the fix above and it works. I'm planning to handle the fix locally for now, but a fix for this would be very much appreciated.

If anyone is wondering about the use case for this, I'm working on an enterprise level JSON based medical API. I'm composing together input filters from my various Doctrine entities (using the AnnotationBuilder) to allow nested POST operations.

Slamdunk added a commit that referenced this issue Mar 13, 2023
Fixes #22: "ComposedObject" Annotation does not add inputSpec to element configuration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant