Issues

ZF-8078: Zend_Form::getValues() does not return all the subforms

Description

My goal is to get my data back to me in a form like this:


raffle[id]
raffle[tickets][1][cost]
raffle[tickets][2][cost]

To that end, I have a form with two subforms created as such:

 
$form = new Zend_Form;
$form->addElement('hidden', 'id');
$form->setElementsBelongTo('raffle');
$form->addElement($element);
     
$form->addElement('submit', 'Submit');

$sf = new Zend_Form_SubForm();
$sf->addElement('text', 'cost');
$sf->setElementsBelongTo('tickets[1]');
$form->addSubForm($sf,'tickets[1]');
$sf2 = new Zend_Form_SubForm();
$sf2->addElement('text', 'cost');
$sf2->setElementsBelongTo('tickets[2]');
$form->addSubForm($sf2,'tickets[2]');

This appears to give me what I want, but in the output of $form->getValues, only the data from the second subform appears.

Comments

Might I suggest changing


foreach ($this->getSubForms() as $key => $subForm) {
            $fValues = $this->_attachToArray($subForm->getValues(true), $subForm->getElementsBelongTo());
            $values = array_merge($values, $fValues);
        }

to


foreach ($this->getSubForms() as $key => $subForm) {
            $fValues = $this->_attachToArray($subForm->getValues(true), $subForm->getElementsBelongTo());
            $values = array_merge_recursive($values, $fValues);
        }

This seems like the same issue. Please fix this.

I searched but found no other open issues for this, must not have searched enough :)

Same issue I was having, and also the same fix.

Can we at least have a comment on this? We've gone through two bug hunts and three minor releases since I reported this bug!

I now that my comment is not related to the issue, but you can archive the desired result with nested subforms. Like this:

//Create tickets as individual subforms: $first_ticket = new Zend_Form_SubForm(); $first_ticket->addElement("text", "cost", ...); $first_ticket->addElement("text", "type", ...);

//then bind those indivudual Subforms into an another subform, using numbers as names

$Tickets = new Zend_Form_SubForm(); $Tickets->addSubForm($first_ticket, "1"); // that makes [1][cost] [1][type] in html $Tickets->addSubForm($second_ticket, "2"); // that makes [2][cost] [2][type] in html

// Then add this Subform - which holds ticket as an array of individual subforms - // to your basic form with name "tickets"

$form = new Zend_Form();

$form->addSubForm($Tickets, "tickets");

// so you have elements with ticket[1][cost] name attrib on form fields.

It might require a lot more programming than your solution, but it works, and Subforms also makes possible to validate and handle your elements more easily.

Since raffle[tickets] is an array, it should be a subform, such as this:


$form = new Zend_Form;
$form->addElement('hidden', 'id');
$form->setElementsBelongTo('raffle');

$form->addElement('submit', 'Submit');

$sfTickets = new Zend_Form_SubForm();

$sfCost = new Zend_Form_SubForm();
$sfCost->addElement('text', 'cost');

$sfTickets->addSubForm($sfCost, '1');

$sfCost = new Zend_Form_SubForm();
$sfCost->addElement('text', 'cost');

$sfTickets->addSubForm($sfCost, '2');

$form->addSubForm($sfTickets,'tickets');

print_r($form->getValues());

outputs


Array
(
    [raffle] => Array
        (
            [id] => 
            [tickets] => Array
                (
                    [0] => Array
                        (
                            [cost] => 
                        )

                    [1] => Array
                        (
                            [cost] => 
                        )

                )

        )

)

Which is a bit closer to your desired structure, however is a zero-based array, rather then one-based.

@Avi this is not a correct solution as $fValues = $this->_attachToArray($subForm->getValues(true) is recursive anyway and merge_recursive does not add anything.

You might check if ZF-9350 resolves your issue.

@Christian I haven't tried your patches, but it looks like I may have been tackling the symptom of a greater problem. Good work! My patch does, however, work for the specific situation that I had.

Reopened because suggested fix is not reviewed and committed yet.

Hey Avi, i was a little fast with my Statement, indeed array_merge_recursive solves this issue. The rest is done with ZF-9586.

Resolving as duplicate of ZF-9586