Issues

ZF-3358: Support out of the box validation with belongsTo/elementsBelongTo

Issue Type: Improvement Created: 2008-05-30T07:31:20.000+0000 Last Updated: 2010-03-18T08:13:54.000+0000 Status: Resolved Fix version(s): - 1.5.3 (28/Jul/08)

Reporter: Amr Mostafa (alienbrain) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend_Form

Related issues: - ZF-9456

Attachments: - Zend_Form-Improved_ElementsBelongTo.patch

Description

h4. Introduction: Zend_Form supports belongsTo (on element level) and elementsBelongTo (on form level) as more explicit and free ways of grouping fields using array notation. The other default way is using SubForms. A key difference between the two approaches is that with SubForms, Zend_Form knows what data structure to expect when validating and populating. So you can pass it the whole $_POST array for example, and it will loop and assign values.

With the belongsTo/elementsBelongTo approach however, the data structure inside a Zend_Form could be 1 level (flat). While in reality, it's going to result in a nested arrays of arrays inside $_POST once submitted. So the developer can no longer pass $_POST and expect Zend_Form to validate against or populate with.

This limitation is noted in the Advanced Zend_Form Usage section in the manual (the last paragraph): bq. Additionally, on the element level, you can specify individual elements may belong to particular arrays using Zend_Form_Element::setBelongsTo() method. However, doing this may cause issues when validating your element, and is not recommended in most cases.

This issue aims at improving the situation and hopefully removing this warning from the manual :)

h4. To reproduce: A full example is attached for convenience, however minimal important parts follow: h5. Zend_Form_Element's belongsTo:

<pre class="highlight">
$form->addElement('text', 'recipient', array(
    'label' => 'Ship to',
    'required' => true,
    'belongsTo' => 'shipping',
));

$form->addElement('submit', 'submit', array(
    'label' => 'Submit'.
));

if ($request->isPost()) {
    if ($form->isValid($request->getPost())) {
        // Execution never reach here. Form is never valid.
        echo 'Order Placed!';
    }
}

echo $form->render();

h5. Zend_Form's elementsBelongTo:

<pre class="highlight">
$form->setElementsBelongTo('shipping');

$form->addElement('text', 'recipient', array(
    'label' => 'Ship to',
    'required' => true,
));

$form->addElement('submit', 'submit', array(
    'label' => 'Submit'.
));

if ($request->isPost()) {
    if ($form->isValid($request->getPost())) {
        // Execution never reach here. Form is never valid.
        echo 'Order Placed!';
    }
}

echo $form->render();

Comments

Posted by Amr Mostafa (alienbrain) on 2008-05-30T07:43:07.000+0000

A ready to use example demonstrating the problem when using belongsTo (on the element's level). You just need to correct the path to zf.

Posted by Amr Mostafa (alienbrain) on 2008-05-30T07:43:31.000+0000

A ready to use example demonstrating the problem when using setElementsBelongTo (on the form's level). You just need to correct the path to zf.

Posted by Amr Mostafa (alienbrain) on 2008-05-30T07:50:57.000+0000

Attaching a patch which fixes this issue. It does that by parsing the belongsTo/setElementsBelongsTo and dissolving the value from given data (e.g. POST) based on that.

Posted by Matthew Weier O'Phinney (matthew) on 2008-05-30T08:56:55.000+0000

This was an excellently reported issue -- my thanks to you!

If you could provide unit tests for this functionality, that will make my job even easier. Regardless, I'm scheduling for the next mini release.

Posted by Amr Mostafa (alienbrain) on 2008-06-12T01:18:50.000+0000

Thanks Matthew, it's my pleasure! :)

I started writing the tests few days ago, but more importantly, when I ran the test suite of Zend_Form with the patch applied, I've noticed that 2 tests failed. So I decided to examine the situation again, and I'm working on an enhanced patch. But I need help :)

Why does FormElements decorator override the subForm's elementsBelongTo? For example:

<pre class="highlight">
$form->setElementsBelongTo('foo');
$subForm->setElementsBelongT('bar');
$subForm->addElement('text', 'name')->name->setLabel('Name');
$form->addSubForm($subForm, 'sub');

Produces:

<pre class="highlight">

While I'd expect it to produce:

<pre class="highlight">

or

<pre class="highlight">

Posted by Amr Mostafa (alienbrain) on 2008-06-20T12:26:01.000+0000

Attaching an updated patch for Zend_Form's elementsBelongTo.

This patch (Zend_Form-Improved_ElementsBelongTo.patch) includes unit tests, and integrates with isValid, isValidPartial, getMessages, getErrors and getValues. It also modifies FormElements decorator to produce the markup honoring elementsBelongTo, a unit test was added for that as well.

Posted by Matthew Weier O'Phinney (matthew) on 2008-07-22T08:24:29.000+0000

Patch reviewed and applied to trunk and 1.5/1.6 release branches.

Posted by Christian Albrecht (alab) on 2010-03-07T19:51:04.000+0000

Today i wondered who the smart guy was who wrote this _dissolveArrayValue() function. And it's really interesting to read your patch because just now these clean methods you wrote are corrupted again somehow. Living Code :) Maybe it's because the _dissolve function is so dreaded that it's hard to follow.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts