فهرست منبع

ZF-10411: Ensure elements added to groups later are not rendered by both form and group

- DisplayGroup now tracks the form owning it
- DisplayGroup calls new method on form, removeFromIteration(), for each method
  added to it. removeFromIteration() removes the element from the $_order array
  of the form.

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@22930 44c647ce-9c0f-0410-b52a-842ac1e357ba
matthew 15 سال پیش
والد
کامیت
aedd3b81d7
3فایلهای تغییر یافته به همراه101 افزوده شده و 4 حذف شده
  1. 21 2
      library/Zend/Form.php
  2. 42 0
      library/Zend/Form/DisplayGroup.php
  3. 38 2
      tests/Zend/Form/FormTest.php

+ 21 - 2
library/Zend/Form.php

@@ -1785,7 +1785,6 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
             if (isset($this->_elements[$element])) {
                 $add = $this->getElement($element);
                 if (null !== $add) {
-                    unset($this->_order[$element]);
                     $group[] = $add;
                 }
             }
@@ -1798,12 +1797,17 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
         $name = (string) $name;
 
         if (is_array($options)) {
+            $options['form']     = $this;
             $options['elements'] = $group;
         } elseif ($options instanceof Zend_Config) {
             $options = $options->toArray();
+            $options['form']     = $this;
             $options['elements'] = $group;
         } else {
-            $options = array('elements' => $group);
+            $options = array(
+                'form'     => $this,
+                'elements' => $group,
+            );
         }
 
         if (isset($options['displayGroupClass'])) {
@@ -1850,6 +1854,7 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
         }
 
         $this->_displayGroups[$name] = $group;
+        $group->setForm($this);
 
         if (!empty($this->_displayGroupPrefixPaths)) {
             $this->_displayGroups[$name]->addPrefixPaths($this->_displayGroupPrefixPaths);
@@ -3278,6 +3283,20 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
     }
 
     /**
+     * Remove an element from iteration
+     * 
+     * @param  string $name Element/group/form name
+     * @return void
+     */
+    public function removeFromIteration($name)
+    {
+        if (array_key_exists($name, $this->_order)) {
+            unset($this->_order[$name]);
+            $this->_orderUpdated = true;
+        }
+    }
+
+    /**
      * Sort items according to their order
      *
      * @return void

+ 42 - 0
library/Zend/Form/DisplayGroup.php

@@ -66,6 +66,13 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
     protected $_elements = array();
 
     /**
+     * Form object to which the display group is currently registered
+     * 
+     * @var Zend_Form
+     */
+    protected $_form;
+
+    /**
      * Whether or not a new element has been added to the group
      * @var bool
      */
@@ -276,6 +283,35 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
     }
 
     /**
+     * Set form object to which the display group is attached
+     * 
+     * @param  Zend_Form $form 
+     * @return Zend_Form_DisplayGroup
+     */
+    public function setForm(Zend_Form $form)
+    {
+        $this->_form = $form;
+
+        // Ensure any elements attached prior to setting the form are now 
+        // removed from iteration by the form
+        foreach ($this->getElements() as $element) {
+            $form->removeFromIteration($element->getName());
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get form object to which the group is attached
+     * 
+     * @return Zend_Form|null
+     */
+    public function getForm()
+    {
+        return $this->_form;
+    }
+
+    /**
      * Filter a name to only allow valid variable characters
      *
      * @param  string $value
@@ -432,6 +468,12 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
     {
         $this->_elements[$element->getName()] = $element;
         $this->_groupUpdated = true;
+
+        // Display group will now handle display of element
+        if (null !== ($form = $this->getForm())) {
+            $form->removeFromIteration($element->getName());
+        }
+
         return $this;
     }
 

+ 38 - 2
tests/Zend/Form/FormTest.php

@@ -2922,8 +2922,6 @@ class Zend_Form_FormTest extends PHPUnit_Framework_TestCase
     public function getView()
     {
         $view = new Zend_View();
-        $libPath = dirname(__FILE__) . '/../../../library';
-        $view->addHelperPath($libPath . '/Zend/View/Helper');
         return $view;
     }
 
@@ -4380,6 +4378,16 @@ class Zend_Form_FormTest extends PHPUnit_Framework_TestCase
         $t2 = $this->form->getDecorators();
         $this->assertEquals($t1, $t2);
     }
+
+    /**
+     * @group ZF-10411
+     */
+    public function testAddingElementToDisplayGroupManuallyShouldPreventRenderingByForm()
+    {
+        $form = new Zend_Form_FormTest_AddToDisplayGroup();
+        $html = $form->render($this->getView());
+        $this->assertEquals(1, substr_count($html, 'Customer Type'), $html);
+    }
 }
 
 class Zend_Form_FormTest_DisplayGroup extends Zend_Form_DisplayGroup
@@ -4394,6 +4402,34 @@ class Zend_Form_FormTest_FormExtension extends Zend_Form
     }
 }
 
+class Zend_Form_FormTest_WithDisplayGroup extends Zend_Form
+{
+    public function init()
+    {
+        $this->addElement('text', 'el1', array(
+            'label'    => 'Title',
+            'required' => true,
+        ));
+        $this->addDisplayGroup(array('el1'), 'group1', array(
+            'legend' => 'legend 1',
+        ));
+    }
+}
+
+class Zend_Form_FormTest_AddToDisplayGroup extends Zend_Form_FormTest_WithDisplayGroup
+{
+    public function init()
+    {
+        parent::init();
+        $element = new Zend_Form_Element_Text('el2', array(
+            'label' => 'Customer Type',
+        ));
+
+        $this->addElement($element);
+        $this->group1->addElement($element);
+    }
+}
+
 if (PHPUnit_MAIN_METHOD == 'Zend_Form_FormTest::main') {
     Zend_Form_FormTest::main();
 }