Zend Framework

Zend Form Method "getValues()" does not maintain subform names

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Won't Fix
  • Affects Version/s: 1.6.0
  • Fix Version/s: None
  • Component/s: Zend_Form
  • Labels:
    None

Description

function getValues() [1.6.0RC2 - 1.6.0] [LINE: 1286]
$values = array_merge($values, $fValues);

Naming a SubForm with a numeric value results in loss of that name when calling $form->getValues();

Since the storage of Subforms uses an associative array, it seems ZF should maintain those keys regardless of type. Using array_merge() will rekey any arrays with numeric values as keys resulting in the loss of that SubForm name.

Example
$form = new Zend_Form;
$form->addElement( new Zend_Form_Element_Text('username') );

$subform = new Zend_Form_SubForm();
$subform->addElement( new Zend_Form_Element_Text('subform_name') );

$form->addSubForm($subform, '12345'); // Naming it with a string that happens to be numeric

$simulated_request = array('username'=>'JoeTest', 
							'12345'=>array('subform_name'=>'FredTest')
							);
$form->populate($simulated_request);
$form_values = $form->getValues();
echo "<pre>".print_r($form_values, true);
Result
Array
(
    [username] => JoeTest
    [0] => Array
        (
            [subform_name] => FredTest
        )

)

Activity

Hide
Matthew Weier O'Phinney added a comment -

For a variety of reasons, we decided that element, sub form, and display group names must be valid variable names. This means that numeric names are not compatible with the design. We have no plans to alter that support.

Show
Matthew Weier O'Phinney added a comment - For a variety of reasons, we decided that element, sub form, and display group names must be valid variable names. This means that numeric names are not compatible with the design. We have no plans to alter that support.
Hide
Simon added a comment -

I can confirm this. Having a bit of memory, I do remember that PHP does not allow var names to start with digits. However, perhaps this "element, sub form, and display group names must be valid variable names" can be added to the docs somewhere. It helps save time. I'll add it as a comment for now.

Show
Simon added a comment - I can confirm this. Having a bit of memory, I do remember that PHP does not allow var names to start with digits. However, perhaps this "element, sub form, and display group names must be valid variable names" can be added to the docs somewhere. It helps save time. I'll add it as a comment for now.
Hide
Simon added a comment -

(A side note as to why integers as subform's names)

One subform per row.

You can get what you want by doing this:
$data = $this->getRequest()->getPost();

Rather than:

$data = $form->getValues()

But that of course is not validated. It works for me since for scafolding, as I want my subform's name to be the id of a row. Otherwise I need to use hidden elements or setName('id' . $rowid) and then substr($subformname, 2). Ugly. I guess a hidden element might be the correct way to do that.

Show
Simon added a comment - (A side note as to why integers as subform's names) One subform per row. You can get what you want by doing this: $data = $this->getRequest()->getPost(); Rather than: $data = $form->getValues() But that of course is not validated. It works for me since for scafolding, as I want my subform's name to be the id of a row. Otherwise I need to use hidden elements or setName('id' . $rowid) and then substr($subformname, 2). Ugly. I guess a hidden element might be the correct way to do that.
Hide
Jayesh Sheth added a comment -

Hi,

it seems that using dashes in element values creates unexpected results.

For example, imagine that I'm creating a multi-select element using the following ini configuration:

;Section
elements.section.type = "multiselect"
elements.section.options.class = "field"
elements.section.options.label = "Section"
elements.section.options.multiOptions.city-guide = "City Guide"
elements.section.options.multiOptions.citystreets = "City Streets"
elements.section.options.multiOptions.cityroads = "City Roads"
elements.section.options.value.cityroads = "cityroads"
elements.section.options.value.city-guide = "city-guide"

It won't work as expected. Only the "City Roads" option will be selected.

This is because when the config is converted into a PHP array, it cuts off the "city-" part of "city-guide":

Array
(
[class] => field
[label] => Section
[multiOptions] => Array
(
[guide] => City Guide
[citystreets] => City Streets
[cityroads] => City Roads
)

[value] => Array
(
[cityroads] => cityroads
[guide] => city-guide
)

)

Then it calls Zend_Form_Element_Multiselect->setValue(Array
(
[cityroads] => cityroads
[guide] => city-guide
)
)

Which would fail for the city-guide option.

I would prefer that it do either of the following (in order of preference):

  • replace dashes with an empty string, so that city-guide becomes 'cityguide' internally, and so setValue still works
  • throws an Exception whenever it encounters an invalid option name, with instructions on how to format it correctly

Additionally, the official documentation should have a bold note explain how this works.
Thanks!

Show
Jayesh Sheth added a comment - Hi, it seems that using dashes in element values creates unexpected results. For example, imagine that I'm creating a multi-select element using the following ini configuration: ;Section elements.section.type = "multiselect" elements.section.options.class = "field" elements.section.options.label = "Section" elements.section.options.multiOptions.city-guide = "City Guide" elements.section.options.multiOptions.citystreets = "City Streets" elements.section.options.multiOptions.cityroads = "City Roads" elements.section.options.value.cityroads = "cityroads" elements.section.options.value.city-guide = "city-guide" It won't work as expected. Only the "City Roads" option will be selected. This is because when the config is converted into a PHP array, it cuts off the "city-" part of "city-guide": Array ( [class] => field [label] => Section [multiOptions] => Array ( [guide] => City Guide [citystreets] => City Streets [cityroads] => City Roads ) [value] => Array ( [cityroads] => cityroads [guide] => city-guide ) ) Then it calls Zend_Form_Element_Multiselect->setValue(Array ( [cityroads] => cityroads [guide] => city-guide ) ) Which would fail for the city-guide option. I would prefer that it do either of the following (in order of preference):
  • replace dashes with an empty string, so that city-guide becomes 'cityguide' internally, and so setValue still works
  • throws an Exception whenever it encounters an invalid option name, with instructions on how to format it correctly
Additionally, the official documentation should have a bold note explain how this works. Thanks!

People

Vote (1)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: