Issue Type: Sub-task Created: 2010-03-26T15:49:37.000+0000 Last Updated: 2010-03-31T09:23:34.000+0000 Status: Resolved Fix version(s): Reporter: Christian Albrecht (alab) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend_Form
Related issues: Attachments:
When adding a SubForm to Form and adding An Element to that SubForm which has the same name as the SubForm, isValidPartial will error with 1) Zend_Form_FormTest::testIsValidPartialEqualSubFormAndElementName Invalid argument supplied for foreach()
/var/www/FRAMEWORKS/PHP/ZF/trunk/library/Zend/Form.php:2080 /var/www/FRAMEWORKS/PHP/ZF/trunk/library/Zend/Form.php:2090 /var/www/FRAMEWORKS/PHP/ZF/trunk/tests/Zend/Form/FormTest.php:1487
Based on what i have learned from patching the related issue in isValid i updatet the patch below, for the description why the Error occures see [ZF-9348]
To make the method isValidPartial() more readable and to be able to apply a solution the same way as above i changed the iteration from
<pre class="highlight">
foreach($data as $key => $val) {
if (null !== $this->getElement($key)) {
// validate Element
}
if (null !== $this->getSubForm($key)) {
$form->isValidPartial($data[$key]);
}
}
foreach($nonValidatedSubForms as $form) {
$form->isValidPartial($data);
}
into
<pre class="highlight">
foreach ($this->getElements() as $key => $element) {
if (isset($data[$key])) {
// validate Element
}
}
foreach ($this->getSubForms() as $key => $form) {
if (isset($data[$key]) && !$form->isArray()) { // Why !$form->isArray() see @[ZF-9348]
$form->isValidPartial($data[$key]);
} else {
$form->isValidPartial($data);
}
}
Which in my Opinion is basically the same.
In Full Notation Before Patch
<pre class="highlight">
foreach ($data as $key => $value) {
if (null !== ($element = $this->getElement($key))) {
if (null !== $translator && !$element->hasTranslator()) {
$element->setTranslator($translator);
}
$valid = $element->isValid($value, $data) && $valid;
} elseif (null !== ($subForm = $this->getSubForm($key))) {
if (null !== $translator && !$subForm->hasTranslator()) {
$subForm->setTranslator($translator);
}
$valid = $subForm->isValidPartial($data[$key]) && $valid;
$validatedSubForms[] = $key;
}
}
foreach ($this->getSubForms() as $key => $subForm) {
if (!in_array($key, $validatedSubForms)) {
if (null !== $translator && !$subForm->hasTranslator()) {
$subForm->setTranslator($translator);
}
$valid = $subForm->isValidPartial($data) && $valid;
}
}
And After Patch
<pre class="highlight">
foreach ($this->getElements() as $key => $element) {
if (isset($data[$key])) {
if (null !== $translator && !$element->hasTranslator()) {
$element->setTranslator($translator);
}
$valid = $element->isValid($data[$key], $data) && $valid;
}
}
foreach ($this->getSubForms() as $key => $form) {
if (null !== $translator && !$form->hasTranslator()) {
$form->setTranslator($translator);
}
if (isset($data[$key]) && !$form->isArray()) {
$valid = $form->isValidPartial($data[$key]) && $valid;
} else {
$valid = $form->isValidPartial($data) && $valid;
}
}
This tested patch fixes the issue, Unit Test included
<pre class="highlight">
Index: tests/Zend/Form/FormTest.php
===================================================================
--- tests/Zend/Form/FormTest.php (Revision 21667)
+++ tests/Zend/Form/FormTest.php (Arbeitskopie)
@@ -1473,7 +1473,25 @@
$this->assertTrue($this->form->isValid($data));
}
+ public function testIsValidPartialEqualSubFormAndElementName()
+ {
+ $this->form->addSubForm(new Zend_Form_SubForm(), 'foo')
+ ->foo->addElement('text', 'foo')
+ ->foo->setRequired(true)
+ ->addValidator('Identical',
+ false,
+ array('Foo Value'));
+ $foo = array('foo' =>
+ array('foo' => 'Foo Value'));
+ $this->assertTrue($this->form->isValidPartial($foo));
+
+ $this->form->foo->setIsArray(false);
+
+ $this->assertTrue($this->form->isValidPartial($foo));
+ }
+
+
// Display groups
public function testCanAddAndRetrieveSingleDisplayGroups()
Index: library/Zend/Form.php
===================================================================
--- library/Zend/Form.php (Revision 21667)
+++ library/Zend/Form.php (Arbeitskopie)
@@ -2077,30 +2077,24 @@
$translator = $this->getTranslator();
$valid = true;
- $validatedSubForms = array();
- foreach ($data as $key => $value) {
- if (null !== ($element = $this->getElement($key))) {
+ foreach ($this->getElements() as $key => $element) {
+ if (isset($data[$key])) {
if (null !== $translator && !$element->hasTranslator()) {
$element->setTranslator($translator);
}
- $valid = $element->isValid($value, $data) && $valid;
- } elseif (null !== ($subForm = $this->getSubForm($key))) {
- if (null !== $translator && !$subForm->hasTranslator()) {
- $subForm->setTranslator($translator);
- }
- $valid = $subForm->isValidPartial($data[$key]) && $valid;
- $validatedSubForms[] = $key;
+ $valid = $element->isValid($data[$key], $data) && $valid;
}
}
- foreach ($this->getSubForms() as $key => $subForm) {
- if (!in_array($key, $validatedSubForms)) {
- if (null !== $translator && !$subForm->hasTranslator()) {
- $subForm->setTranslator($translator);
- }
-
- $valid = $subForm->isValidPartial($data) && $valid;
+ foreach ($this->getSubForms() as $key => $form) {
+ if (null !== $translator && !$form->hasTranslator()) {
+ $form->setTranslator($translator);
}
+ if (isset($data[$key]) && !$form->isArray()) {
+ $valid = $form->isValidPartial($data[$key]) && $valid;
+ } else {
+ $valid = $form->isValidPartial($data) && $valid;
+ }
}
$this->_errorsExist = !$valid;
Posted by Christian Albrecht (alab) on 2010-03-29T05:54:22.000+0000
Updatet the Test, it checks now against $form->setIsArray(false) as well.
Posted by Matthew Weier O'Phinney (matthew) on 2010-03-31T09:23:34.000+0000
Patch applied in trunk and 1.10 release branch.