ZF-11831: Form's default translator incorrectly passed to subforms, causing override of subform elements' default translators
Description
If a form is validated, the translator of the form will be passed through all subforms. It's the same bug as ZF-9330 (for form elements) which was resolved long ago except that subforms were left out while fixing.
Only add "$this->hasTranslator()" in Form.php line 2261 (1.11.11) as it was done in line 2246 for elements
foreach ($this->getSubForms() as $key => $form) {
if (null !== $translator && $this->hasTranslator()
&& !$form->hasTranslator()) {
Comments
Posted by Adam Lundrigan (adamlundrigan) on 2011-10-20T18:11:47.000+0000
The Form/SubForm case is a special one. As a Form and an Element are completely separate entities, they can each have their own default translators (set via {{setDefaultTranslator}} method). However, SubForm is a sub-class of Form, and since the default translator is stored in a static class variable of {{Zend_Form}}, all forms and sub-forms share the same default translator. Determining an element's translator is a four step process:
If a validator was set with {{setValidator}}, return it.
If no validator was set, but a default validator was set with {{setDefaultValidator}}, return it.
If no default validator was set either, look up the key {{Zend_Validate}} in {{Zend_Registry}} and return it.
If no key {{Zend_Validate}} exists in {{Zend_Registry}}, return null
The only case where your suggested addition would make an impact is when {{$this->hasTranslator()}} is false while the two existing conditions are true. In this case, {{$translator}} contains the default translator instance, and that instance is passed down to all the sub-forms. Since all forms (both Form and SubForm) always have the same default translator definition, that's not a problem. I've attached a patch with a unit test showing this behaviour.
Unless you can provide a specific example where the existing behavior is a problem, I will recommend that this issue be closed as "Not an Issue".
Posted by Bjoern Mueller (coolsurfers) on 2011-10-20T18:34:25.000+0000
Let me try to explain:
during initalisation I'm setting up two translation objects: "Zend_Registry::set('Zend_Translate', $translate)" [1] to my own Tramslate Object and setting a Default Translater for Validate: Zend_Validate_Abstract::setDefaultTranslator( $validateTranslation ); [2]
If a form exists with 2 elements and an additional subform with 2 elements (all 4 elements with a float validator for example) the error message of the elements of the form are translated by [2 - Default Translator of Zend_Validate] while the elements of the subform are translated by [1, cause the default Validation Translator is overwritten by the subform translator]
Posted by Adam Lundrigan (adamlundrigan) on 2011-10-21T00:50:38.000+0000
@Bjoern:
Aha! I figured I was missing the point, but I couldn't see where at the time. The attached test (ZF-11831_v2.patch) should reproduce the issue you are seeing. The result when I run it against trunk is:
After adapting the fix applied in ZF-9364 for elements to this case:
The failing test above passes, as does the entire {{Zend_Form}} suite.
Thanks for your help and patience in sorting this issue out!
Posted by Adam Lundrigan (adamlundrigan) on 2011-10-21T01:33:01.000+0000
Fixed in trunk r24515 Merged to release-1.11 in r24516 r24517.
Posted by Adam Lundrigan (adamlundrigan) on 2011-10-21T01:50:18.000+0000
ZF2 Pull Request issued. https://github.com/zendframework/zf2/pull/517