ZF-9540: Zend_Form isValid | isValidPartial resets individual SubForm Translator

Description

When setting a translator to a Form xor setting a default Translator in Zend_Registry and setting a translator to a SubForm of that Form, the indivdual SubForm Translator is resetted when calling isValid or isValidPartial.

This patch will fix this issue, unit test included


Index: tests/Zend/Form/FormTest.php
===================================================================
--- tests/Zend/Form/FormTest.php        (Revision 21649)
+++ tests/Zend/Form/FormTest.php        (Arbeitskopie)
@@ -3885,6 +3885,46 @@
         $this->assertEquals('Form message', $messages['bar']['isEmpty']);
     }    
 
+    public function testSubFormTranslatorPreferredOverDefaultTranslator()
+    {
+        $defaultTranslations = array(
+            'isEmpty' => 'Default message',
+        );
+        $formTranslations = array(
+            'isEmpty' => 'Form message',
+        );        
+        $subformTranslations = array(
+            'isEmpty' => 'SubForm message',
+        );        
+        $elementTranslations = array(
+            'isEmpty' => 'Element message',
+        );
+        $defaultTranslate = new Zend_Translate('array', $defaultTranslations);
+        $formTranslate    = new Zend_Translate('array', $formTranslations);
+        $subformTranslate = new Zend_Translate('array', $subformTranslations);
+        $elementTranslate = new Zend_Translate('array', $elementTranslations);
+        
+        Zend_Registry::set('Zend_Translate', $defaultTranslate);
+        $this->form->setTranslator($formTranslate);
+        $this->form->addSubForm(new Zend_Form_SubForm(), 'subform');
+        $this->form->subform->setTranslator($subformTranslate);
+        $this->form->subform->addElement('text', 'foo', array('required'=>true, 'translator'=>$elementTranslate));
+        $this->form->subform->addElement('text', 'bar', array('required'=>true));
+
+        $this->assertFalse($this->form->isValid(array('subform' => array('foo'=>'', 'bar'=>''))));
+        $messages = $this->form->getMessages('subform');
+
+        $this->assertEquals(2, count($messages));
+        $this->assertEquals('Element message', $messages['foo']['isEmpty']);
+        $this->assertEquals('SubForm message', $messages['bar']['isEmpty']);
+        
+        $this->assertFalse($this->form->isValidPartial(array('subform' => array('foo'=>'', 'bar'=>''))));
+        $messages = $this->form->getMessages('subform');
+        $this->assertEquals(2, count($messages));
+        $this->assertEquals('Element message', $messages['foo']['isEmpty']);
+        $this->assertEquals('SubForm message', $messages['bar']['isEmpty']);
+    }
+
     /**
      * Used by test methods susceptible to ZF-2794, marks a test as incomplete
      *
Index: library/Zend/Form.php
===================================================================
--- library/Zend/Form.php       (Revision 21649)
+++ library/Zend/Form.php       (Arbeitskopie)
@@ -2041,7 +2041,9 @@
             }
         }
         foreach ($this->getSubForms() as $key => $form) {
-            $form->setTranslator($translator);
+            if (null !== $translator && !$form->hasTranslator()) {
+                $form->setTranslator($translator);
+            }
             if (isset($data[$key])) {
                 $valid = $form->isValid($data[$key]) && $valid;
             } else {
@@ -2084,7 +2086,7 @@
                 }
                 $valid = $element->isValid($value, $data) && $valid;
             } elseif (null !== ($subForm = $this->getSubForm($key))) {
-                if (null !== $translator) {
+                if (null !== $translator && !$subForm->hasTranslator()) {
                     $subForm->setTranslator($translator);
                 }
                 $valid = $subForm->isValidPartial($data[$key]) && $valid;
@@ -2093,7 +2095,7 @@
         }
         foreach ($this->getSubForms() as $key => $subForm) {
             if (!in_array($key, $validatedSubForms)) {
-                if (null !== $translator) {
+                if (null !== $translator && !$subForm->hasTranslator()) {
                     $subForm->setTranslator($translator);
                 }
 
@@ -2743,6 +2745,17 @@
     }
 
     /**
+     * Does this Form or SubForm have its own specific translator?
+     * 
+     * @return bool
+     */
+    public function hasTranslator()
+    {
+        return (bool)$this->_translator;
+    }
+
+
+    /**
      * Get global default translator object
      *
      * @return null|Zend_Translate

Comments

Updated the test as there was a logical error, the test called $subform->isValid($elementsValuesArray) instead of the failing one $form->isValid($subformValuesArray);

The previous did not fail because there was no need for isValid to set a Translator on a SubForm, because there just was no SubForm appended to that SubForm, hehe :)

Fixed in trunk r21665 and release-1.10 branch r21666.