Parcourir la source

[Form] Refactored RepeatedField to FormFactory

Bernhard Schussek il y a 14 ans
Parent
commit
848ec01f02

+ 32 - 0
src/Symfony/Component/Form/FormFactory.php

@@ -50,6 +50,7 @@ use Symfony\Component\Form\ValueTransformer\EntitiesToArrayTransformer;
 use Symfony\Component\Form\ValueTransformer\ValueTransformerChain;
 use Symfony\Component\Form\ValueTransformer\ArrayToChoicesTransformer;
 use Symfony\Component\Form\ValueTransformer\ArrayToPartsTransformer;
+use Symfony\Component\Form\ValueTransformer\ValueToDuplicatesTransformer;
 use Symfony\Component\Validator\ValidatorInterface;
 use Symfony\Component\Locale\Locale;
 
@@ -834,4 +835,35 @@ class FormFactory
 
         return $field;
     }
+
+    public function getRepeatedField($key, array $options = array())
+    {
+        $options = array_merge(array(
+            'template' => 'repeated',
+            'first_key' => 'first',
+            'second_key' => 'second',
+            'prototype' => null,
+        ), $options);
+
+        // Lazy creation of the prototype
+        if (!isset($options['prototype'])) {
+            $options['prototype'] = $this->getTextField('key');
+        }
+
+        $firstChild = clone $options['prototype'];
+        $firstChild->setKey($options['first_key']);
+        $firstChild->setPropertyPath($options['first_key']);
+
+        $secondChild = clone $options['prototype'];
+        $secondChild->setKey($options['second_key']);
+        $secondChild->setPropertyPath($options['second_key']);
+
+        return $this->getForm($key, $options)
+            ->setValueTransformer(new ValueToDuplicatesTransformer(array(
+                $options['first_key'],
+                $options['second_key'],
+            )))
+            ->add($firstChild)
+            ->add($secondChild);
+    }
 }

+ 0 - 108
src/Symfony/Component/Form/RepeatedField.php

@@ -1,108 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form;
-
-/**
- * A field for repeated input of values.
- *
- * Available options:
- *
- *  * first_key:        The key to use for the first field.
- *  * second_key:       The key to use for the second field.
- *
- * @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
- */
-class RepeatedField extends Form
-{
-    /**
-     * The prototype for the inner fields
-     * @var FieldInterface
-     */
-    protected $prototype;
-
-    /**
-     * Repeats the given field twice to verify the user's input.
-     *
-     * @param FieldInterface $innerField
-     */
-    public function __construct(FieldInterface $innerField, array $options = array())
-    {
-        $this->prototype = $innerField;
-
-        parent::__construct($innerField->getKey(), $options);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    protected function configure()
-    {
-        $this->addOption('first_key', 'first');
-        $this->addOption('second_key', 'second');
-
-        parent::configure();
-
-        $field = clone $this->prototype;
-        $field->setKey($this->getOption('first_key'));
-        $field->setPropertyPath($this->getOption('first_key'));
-        $this->add($field);
-
-        $field = clone $this->prototype;
-        $field->setKey($this->getOption('second_key'));
-        $field->setPropertyPath($this->getOption('second_key'));
-        $this->add($field);
-    }
-
-    /**
-     * Returns whether both entered values are equal
-     *
-     * @return Boolean
-     */
-    public function isFirstEqualToSecond()
-    {
-        return $this->get($this->getOption('first_key'))->getData() === $this->get($this->getOption('second_key'))->getData();
-    }
-
-    /**
-     * Sets the values of both fields to this value
-     *
-     * @param mixed $data
-     */
-    public function setData($data)
-    {
-        parent::setData(array(
-            $this->getOption('first_key') => $data,
-            $this->getOption('second_key') => $data
-        ));
-    }
-
-    /**
-     * Return the value of a child field
-     *
-     * If the value of the first field is set, this value is returned.
-     * Otherwise the value of the second field is returned. This way,
-     * this field will never trigger a NotNull/NotBlank error if any of the
-     * child fields was filled in.
-     *
-     * @return string The field value
-     */
-    public function getData()
-    {
-        // Return whichever data is set. This should not return NULL if any of
-        // the fields is set, otherwise this might trigger a NotNull/NotBlank
-        // error even though some value was set
-        $data1 = $this->get($this->getOption('first_key'))->getData();
-        $data2 = $this->get($this->getOption('second_key'))->getData();
-
-        return $data1 ?: $data2;
-    }
-}

+ 12 - 14
tests/Symfony/Tests/Component/Form/RepeatedFieldTest.php

@@ -11,16 +11,23 @@
 
 namespace Symfony\Tests\Component\Form;
 
+require_once __DIR__.'/TestCase.php';
+
 use Symfony\Component\Form\RepeatedField;
 use Symfony\Component\Form\Field;
 
-class RepeatedFieldTest extends \PHPUnit_Framework_TestCase
+class RepeatedFieldTest extends TestCase
 {
     protected $field;
 
     protected function setUp()
     {
-        $this->field = new RepeatedField(new Field('name'));
+        parent::setUp();
+
+        $this->field = $this->factory->getRepeatedField('name', array(
+            'prototype' => $this->factory->getField('foo'),
+        ));
+        $this->field->setData(null);
     }
 
     public function testSetData()
@@ -39,9 +46,9 @@ class RepeatedFieldTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals('foo', $this->field['first']->getDisplayedData());
         $this->assertEquals('bar', $this->field['second']->getDisplayedData());
-        $this->assertFalse($this->field->isFirstEqualToSecond());
+        $this->assertFalse($this->field->isTransformationSuccessful());
         $this->assertEquals($input, $this->field->getDisplayedData());
-        $this->assertEquals('foo', $this->field->getData());
+        $this->assertEquals(null, $this->field->getData());
     }
 
     public function testSubmitEqual()
@@ -52,17 +59,8 @@ class RepeatedFieldTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals('foo', $this->field['first']->getDisplayedData());
         $this->assertEquals('foo', $this->field['second']->getDisplayedData());
-        $this->assertTrue($this->field->isFirstEqualToSecond());
+        $this->assertTrue($this->field->isTransformationSuccessful());
         $this->assertEquals($input, $this->field->getDisplayedData());
         $this->assertEquals('foo', $this->field->getData());
     }
-
-    public function testGetDataReturnsSecondValueIfFirstIsEmpty()
-    {
-        $input = array('first' => '', 'second' => 'bar');
-
-        $this->field->submit($input);
-
-        $this->assertEquals('bar', $this->field->getData());
-    }
 }