Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added ability to compose collections via Zend Form annotations #5420

Closed
wants to merge 2 commits into from

2 participants

@carnage

This patch resolves issue #5410

library/Zend/Form/Annotation/ComposedObject.php
((12 lines not shown))
+ *
+ * @return bool
+ */
+ public function isCollection()
+ {
+ return is_array($this->value) && isset($this->value['is_collection']) && $this->value['is_collection'];
+ }
+
+ /**
+ * Retrieve the options for the composed object
+ *
+ * @return array
+ */
+ public function getOptions()
+ {
+ return isset($this->value['options'])?$this->value['options']:array();
@weierophinney Owner

CS -- wrap the operators (? and :) with spaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney weierophinney commented on the diff
...y/Zend/Form/Annotation/ElementAnnotationsListener.php
@@ -136,8 +137,19 @@ public function handleComposedObjectAnnotation($e)
if (!isset($specification['type'])) {
$specification['type'] = 'Zend\Form\Fieldset';
}
- $elementSpec['spec'] = $specification;
- $elementSpec['spec']['name'] = $name;
+ if ($annotation->isCollection()) {
@weierophinney Owner

You need to check that the annotation is of the correct type before attempting to call isCollection on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@carnage

It's not visible from the diff, but the method already checks that further up

 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');
        $filterSpec  = $e->getParam('filterSpec');

        // Compose input filter into parent input filter
        $inputFilter = $specification['input_filter'];
        if (!isset($inputFilter['type'])) {
            $inputFilter['type'] = 'Zend\InputFilter\InputFilter';
        }
        $e->setParam('inputSpec', $inputFilter);
        unset($specification['input_filter']);

        // Compose specification as a fieldset into parent form/fieldset
        if (!isset($specification['type'])) {
            $specification['type'] = 'Zend\Form\Fieldset';
        }
        if ($annotation->isCollection()) {
            $elementSpec['spec']['type'] = 'Zend\Form\Element\Collection';
            $elementSpec['spec']['name'] = $name;
            $elementSpec['spec']['options'] = new ArrayObject($annotation->getOptions());
            $elementSpec['spec']['options']['target_element'] = $specification;

            if (isset($specification['hydrator'])) {
                $elementSpec['spec']['hydrator'] = $specification['hydrator'];
            }
        } else {
            $elementSpec['spec'] = $specification;
            $elementSpec['spec']['name'] = $name;
        }
    }

The whole method for reference

@weierophinney weierophinney was assigned
@weierophinney

Merged to develop for release with 2.3.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 5, 2013
  1. @carnage
Commits on Nov 6, 2013
  1. @carnage

    Fixes cs

    carnage authored
This page is out of date. Refresh to see the latest.
View
25 library/Zend/Form/Annotation/ComposedObject.php
@@ -19,7 +19,7 @@
*
* @Annotation
*/
-class ComposedObject extends AbstractStringAnnotation
+class ComposedObject extends AbstractArrayOrStringAnnotation
{
/**
* Retrieve the composed object classname
@@ -28,6 +28,29 @@ class ComposedObject extends AbstractStringAnnotation
*/
public function getComposedObject()
{
+ if (is_array($this->value)) {
+ return $this->value['target_object'];
+ }
return $this->value;
}
+
+ /**
+ * Is this composed object a collection or not
+ *
+ * @return bool
+ */
+ public function isCollection()
+ {
+ return is_array($this->value) && isset($this->value['is_collection']) && $this->value['is_collection'];
+ }
+
+ /**
+ * Retrieve the options for the composed object
+ *
+ * @return array
+ */
+ public function getOptions()
+ {
+ return isset($this->value['options']) ? $this->value['options'] : array();
+ }
}
View
16 library/Zend/Form/Annotation/ElementAnnotationsListener.php
@@ -10,6 +10,7 @@
namespace Zend\Form\Annotation;
use Zend\EventManager\EventManagerInterface;
+use Zend\Stdlib\ArrayObject;
/**
* Default listeners for element annotations
@@ -136,8 +137,19 @@ public function handleComposedObjectAnnotation($e)
if (!isset($specification['type'])) {
$specification['type'] = 'Zend\Form\Fieldset';
}
- $elementSpec['spec'] = $specification;
- $elementSpec['spec']['name'] = $name;
+ if ($annotation->isCollection()) {
@weierophinney Owner

You need to check that the annotation is of the correct type before attempting to call isCollection on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $elementSpec['spec']['type'] = 'Zend\Form\Element\Collection';
+ $elementSpec['spec']['name'] = $name;
+ $elementSpec['spec']['options'] = new ArrayObject($annotation->getOptions());
+ $elementSpec['spec']['options']['target_element'] = $specification;
+
+ if (isset($specification['hydrator'])) {
+ $elementSpec['spec']['hydrator'] = $specification['hydrator'];
+ }
+ } else {
+ $elementSpec['spec'] = $specification;
+ $elementSpec['spec']['name'] = $name;
+ }
}
/**
View
16 tests/ZendTest/Form/Annotation/AnnotationBuilderTest.php
@@ -168,6 +168,22 @@ public function testAllowsComposingChildEntities()
$this->assertTrue($composed->has('password'));
}
+ public function testAllowsComposingMultipleChildEntities()
+ {
+ $entity = new TestAsset\Annotation\EntityComposingMultipleEntities();
+ $builder = new Annotation\AnnotationBuilder();
+ $form = $builder->createForm($entity);
+
+ $this->assertTrue($form->has('composed'));
+ $composed = $form->get('composed');
+
+ $this->assertInstanceOf('Zend\Form\Element\Collection', $composed);
+ $target = $composed->getTargetElement();
+ $this->assertInstanceOf('Zend\Form\FieldsetInterface', $target);
+ $this->assertTrue($target->has('username'));
+ $this->assertTrue($target->has('password'));
+ }
+
public function testCanHandleOptionsAnnotation()
{
$entity = new TestAsset\Annotation\EntityUsingOptions();
View
24 tests/ZendTest/Form/TestAsset/Annotation/EntityComposingMultipleEntities.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace ZendTest\Form\TestAsset\Annotation;
+
+use Zend\Form\Annotation;
+
+/**
+ * @Annotation\Name("hierarchical")
+ */
+class EntityComposingMultipleEntities
+{
+ /**
+ * @Annotation\Name("composed")
+ * @Annotation\ComposedObject({"target_object":"ZendTest\Form\TestAsset\Annotation\Entity", "is_collection":"true"})
+ */
+ public $child;
+}
Something went wrong with that request. Please try again.