Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

ZF2-417 Form Annotation Hydrator options support #2378

Closed
wants to merge 1 commit into from

2 participants

@cgmartin

Backwards compatible to support both string and array annotations:

@Annotation\Hydrator("Zend\Stdlib\Hydrator\ObjectProperty")
or
@Annotation\Hydrator({"type":"Zend\Stdlib\Hydrator\ClassMethods", "options": {"underscoreSeparatedKeys": false}})

Some API additions, so this PR is targeted against the develop branch.

@ghost Unknown referenced this pull request from a commit
@weierophinney weierophinney Merge branch 'feature/zf2-417' into develop
Close #2378
68a17af
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 18, 2012
  1. @cgmartin
This page is out of date. Refresh to see the latest.
View
43 library/Zend/Form/Annotation/AbstractArrayOrStringAnnotation.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Form
+ */
+
+namespace Zend\Form\Annotation;
+
+use Zend\Form\Exception;
+
+/**
+ * @package Zend_Form
+ * @subpackage Annotation
+ */
+abstract class AbstractArrayOrStringAnnotation
+{
+ /**
+ * @var array|string
+ */
+ protected $value;
+
+ /**
+ * Receive and process the contents of an annotation
+ *
+ * @param array $data
+ * @throws Exception\DomainException if a 'value' key is missing, or its value is not an array or string
+ */
+ public function __construct(array $data)
+ {
+ if (!isset($data['value']) || (!is_array($data['value']) && !is_string($data['value']))) {
+ throw new Exception\DomainException(sprintf(
+ '%s expects the annotation to define an array or string; received "%s"',
+ get_class($this),
+ isset($data['value']) ? gettype($data['value']) : 'null'
+ ));
+ }
+ $this->value = $data['value'];
+ }
+}
View
4 library/Zend/Form/Annotation/Hydrator.php
@@ -21,12 +21,12 @@
* @package Zend_Form
* @subpackage Annotation
*/
-class Hydrator extends AbstractStringAnnotation
+class Hydrator extends AbstractArrayOrStringAnnotation
{
/**
* Retrieve the hydrator class
*
- * @return null|string
+ * @return null|string|array
*/
public function getHydrator()
{
View
26 library/Zend/Form/Factory.php
@@ -351,9 +351,9 @@ protected function prepareAndInjectObject($objectName, FieldsetInterface $fields
* Takes a string indicating a hydrator class name (or a concrete instance), instantiates the class
* by that name, and injects the hydrator instance into the form.
*
- * @param string $hydratorOrName
- * @param FieldsetInterface $fieldset
- * @param string $method
+ * @param string|array|Hydrator\HydratorInterface $hydratorOrName
+ * @param FieldsetInterface $fieldset
+ * @param string $method
* @return void
* @throws Exception\DomainException If $hydratorOrName is not a string, does not resolve to a known class, or
* the class does not implement Hydrator\HydratorInterface
@@ -365,14 +365,27 @@ protected function prepareAndInjectHydrator($hydratorOrName, FieldsetInterface $
return;
}
- if (!is_string($hydratorOrName)) {
+ if (!is_string($hydratorOrName) && !is_array($hydratorOrName)) {
throw new Exception\DomainException(sprintf(
- '%s expects string hydrator class name; received "%s"',
+ '%s expects string hydrator class name or an array specification; received "%s"',
$method,
(is_object($hydratorOrName) ? get_class($hydratorOrName) : gettype($hydratorOrName))
));
}
+ if (is_array($hydratorOrName)) {
+ if (!isset($hydratorOrName['type'])) {
+ throw new Exception\DomainException(sprintf(
+ '%s expects array specification to have a type value',
+ $method
+ ));
+ }
+ $hydratorOptions = (isset($hydratorOrName['options'])) ? $hydratorOrName['options'] : array();
+ $hydratorOrName = $hydratorOrName['type'];
+ } else {
+ $hydratorOptions = array();
+ }
+
if (!class_exists($hydratorOrName)) {
throw new Exception\DomainException(sprintf(
'%s expects string hydrator name to be a valid class name; received "%s"',
@@ -389,6 +402,9 @@ protected function prepareAndInjectHydrator($hydratorOrName, FieldsetInterface $
$hydratorOrName
));
}
+ if (!empty($hydratorOptions) && $hydrator instanceof Hydrator\HydratorOptionsInterface) {
+ $hydrator->setOptions($hydratorOptions);
+ }
$fieldset->setHydrator($hydrator);
}
View
2  library/Zend/Stdlib/Hydrator/AbstractHydrator.php
@@ -56,7 +56,7 @@ public function getStrategy($name)
$name
));
}
-
+
return $this->strategies['*'];
}
View
45 library/Zend/Stdlib/Hydrator/ClassMethods.php
@@ -17,22 +17,61 @@
* @package Zend_Stdlib
* @subpackage Hydrator
*/
-class ClassMethods extends AbstractHydrator
+class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface
{
/**
* Flag defining whether array keys are underscore-separated (true) or camel case (false)
* @var boolean
*/
- protected $underscoreSeparatedKeys;
+ protected $underscoreSeparatedKeys = true;
/**
* Define if extract values will use camel case or name with underscore
- * @param boolean $underscoreSeparatedKeys
+ * @param boolean|array $underscoreSeparatedKeys
*/
public function __construct($underscoreSeparatedKeys = true)
{
parent::__construct();
+ $this->setUnderscoreSeparatedKeys($underscoreSeparatedKeys);
+ }
+
+ /**
+ * @param array|\Traversable $options
+ * @return ClassMethods
+ * @throws Exception\InvalidArgumentException
+ */
+ public function setOptions($options)
+ {
+ if ($options instanceof Traversable) {
+ $options = ArrayUtils::iteratorToArray($options);
+ } elseif (!is_array($options)) {
+ throw new Exception\InvalidArgumentException(
+ 'The options parameter must be an array or a Traversable'
+ );
+ }
+ if (isset($options['underscoreSeparatedKeys'])) {
+ $this->setUnderscoreSeparatedKeys($options['underscoreSeparatedKeys']);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param boolean $underscoreSeparatedKeys
+ * @return ClassMethods
+ */
+ public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys)
+ {
$this->underscoreSeparatedKeys = $underscoreSeparatedKeys;
+ return $this;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function getUnderscoreSeparatedKeys()
+ {
+ return $this->underscoreSeparatedKeys;
}
/**
View
25 library/Zend/Stdlib/Hydrator/HydratorOptionsInterface.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Stdlib
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+/**
+ * @category Zend
+ * @package Zend_Stdlib
+ * @subpackage Hydrator
+ */
+interface HydratorOptionsInterface
+{
+ /**
+ * @param array|\Traversable $options
+ * @return HydratorOptionsInterface
+ */
+ public function setOptions($options);
+}
View
11 tests/ZendTest/Form/Annotation/AnnotationBuilderTest.php
@@ -187,6 +187,17 @@ public function testCanHandleOptionsAnnotation()
$this->assertEquals(array('class' => 'label'), $username->getLabelAttributes());
}
+ public function testCanHandleHydratorArrayAnnotation()
+ {
+ $entity = new TestAsset\Annotation\EntityWithHydratorArray();
+ $builder = new Annotation\AnnotationBuilder();
+ $form = $builder->createForm($entity);
+
+ $hydrator = $form->getHydrator();
+ $this->assertInstanceOf('Zend\Stdlib\Hydrator\ClassMethods', $hydrator);
+ $this->assertFalse($hydrator->getUnderscoreSeparatedKeys());
+ }
+
public function testAllowTypeAsElementNameInInputFilter()
{
$entity = new TestAsset\Annotation\EntityWithTypeAsElementName();
View
16 tests/ZendTest/Form/FactoryTest.php
@@ -317,6 +317,22 @@ public function testCanCreateFormsAndSpecifyHydrator()
$this->assertInstanceOf('Zend\Stdlib\Hydrator\ObjectProperty', $hydrator);
}
+ public function testCanCreateHydratorFromArray()
+ {
+ $form = $this->factory->createForm(array(
+ 'name' => 'foo',
+ 'hydrator' => array(
+ 'type' => 'Zend\Stdlib\Hydrator\ClassMethods',
+ 'options' => array('underscoreSeparatedKeys' => false),
+ ),
+ ));
+
+ $this->assertInstanceOf('Zend\Form\FormInterface', $form);
+ $hydrator = $form->getHydrator();
+ $this->assertInstanceOf('Zend\Stdlib\Hydrator\ClassMethods', $hydrator);
+ $this->assertFalse($hydrator->getUnderscoreSeparatedKeys());
+ }
+
public function testCanCreateHydratorFromConcreteClass()
{
$form = $this->factory->createForm(array(
View
26 tests/ZendTest/Form/TestAsset/Annotation/EntityWithHydratorArray.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Form
+ */
+
+namespace ZendTest\Form\TestAsset\Annotation;
+
+use Zend\Form\Annotation;
+
+/**
+ * @Annotation\Name("user")
+ * @Annotation\Attributes({"legend":"Register"})
+ * @Annotation\Hydrator({"type":"Zend\Stdlib\Hydrator\ClassMethods", "options": {"underscoreSeparatedKeys": false}})
+ */
+class EntityWithHydratorArray
+{
+ /**
+ * @Annotation\Options({"label":"Username:", "label_attributes": {"class": "label"}})
+ */
+ public $username;
+}
View
10 tests/ZendTest/Stdlib/HydratorTest.php
@@ -179,6 +179,16 @@ public function testHydratorClassMethodsUnderscore()
$this->assertEquals($test->hasBar(), false);
}
+ public function testHydratorClassMethodsOptions()
+ {
+ $hydrator = new ClassMethods();
+ $this->assertTrue($hydrator->getUnderscoreSeparatedKeys());
+ $hydrator->setOptions(array('underscoreSeparatedKeys' => false));
+ $this->assertFalse($hydrator->getUnderscoreSeparatedKeys());
+ $hydrator->setUnderscoreSeparatedKeys(true);
+ $this->assertTrue($hydrator->getUnderscoreSeparatedKeys());
+ }
+
public function testHydratorClassMethodsIgnoresInvalidValues()
{
$hydrator = new ClassMethods(true);
Something went wrong with that request. Please try again.