If you add dpm($element); within the function form_get_error($element) in form.inc, part of the array will be like this:

    [#parents] => Array
        (
            [0] => functions
            [1] => 1
            [2] => check
        )

    [#array_parents] => Array
        (
            [0] => functions
            [1] => 1
            [2] => check
        )

i.e. $form['#parents'] seems to be a duplicate of $form['#array_parents'].

Is this duplication intentional?
It might cause confusions and bugs further down the road.
(tested on D6).

Comments

casey’s picture

Not sure about this, but I think #array_parents is for internal use whilst #parents can be used to alter the actual formstructure.

I guess this needs to be documented.

casey’s picture

Title: duplicate details in form array(). » FAPI #array_parents is not documented
sun’s picture

#array_parents contains the actual parent array keys of an element in a form structure.

For example:

$form['foo']['bar']['beer'] = array(...);

The element 'beer' will always have:

'#array_parents' => array('foo', 'bar', 'beer')

...

#parents always contains the parent array keys of an element in the submitted form values.

This is heavily influenced by previously defined #parents further up the tree, or, when speaking of tree, it's also affected by whether some element above the element defined #tree, or, whether the element itself defines #tree.

For example:

$form['foo']['bar'] = array(...);

will end up in

$form_state['values']['bar'] = '...';

and we'll see

'#parents' => array('bar')

For example:

$form['foo']['bar'] = array(...);
$form['foo']['#tree'] = TRUE;

will end up in

$form_state['values']['foo']['bar'] = '...';

and we'll see

'#parents' => array('foo', 'bar')

For example:

$form['foo']['bar'] = array(...);
$form['foo']['#parents'] = array('beer');

will end up in

$form_state['values']['beer']['bar'] = '...';

and we'll see

'#parents' => array('beer', 'bar')

For example:

$form['foo']['bar'] = array('#default_value' => 'bar');
$form['foo']['#tree'] = TRUE;
$form['foo']['bar']['beer'] = array('#default_value' => 'beer');
$form['foo']['bar']['beer']['#tree'] = FALSE;

will end up in

$form_state['values']['foo']['bar'] = 'bar';
$form_state['values']['beer'] = 'beer';

and we'll see

'#parents' => array('foo', 'bar')
'#parents' => array('beer')
yched’s picture

Gosh - never realized that #array_parents was about the $form structure. Hm, this sounds like we could remove Field API's manually created $form['#fields'][$field_name]['form_path'] - or at least have it automatically populated for us...

sun’s picture

effulgentsia’s picture

Component: forms system » documentation

Based on #727126: drupal_execute()/drupal_form_submit() doc says it returns something. It doesn't., I'm assuming these kinds of issues belong to the "documentation" component.

jhodgdon’s picture

OK... So it looks like #array_parents is for internal use only, and people creating $form arrays should not be doing anything to or with it. Correct? In which case, does it really belong in the FAPI reference? Maybe not?

effulgentsia’s picture

People creating forms should never set #array_parents.

Rarely, but sometimes, people might want to read #array_parents in order to walk a $form structure back to the element. Examples:

1) In an AJAX callback, you need to send back just the part of $form that changed. Hypothetically, this might need to be based on something relative to $form_state['clicked_button'] (like its parent or grandparent in the $form structure). So you can use $form_state['clicked_button']['#array_parents'] to walk $form to the part that needs to be returned to the browser. This is alluded to in the docblock for drupal_rebuild_form(), but there's no example for it in HEAD.

2) Some reason other than the above. The only example in HEAD is within Field API: field_form_element_after_build()/field_default_form_errors()/field_add_more_js(). Note, the field_add_more_js() usage is similar to #1, but different, in that it's not based on the button that was clicked, but on information that was put into $form_state for the field as a whole.

Seems like the reason to document it is to avoid the confusion that started this issue, and maybe to reinforce in people the difference between $form structure (#array_parents) and input control naming and $form_state['values'] structure (#parents).

jhodgdon’s picture

I don't think we have other internal-use-only parts of $form documented in the FAPI reference at the moment...

arhak’s picture

Rarely, but sometimes, people might want to read #array_parents in order to walk a $form structure back to the element.

which by the way, can't be achieved for radio/radios neither hidden, since they have not #array_parents at all

I'm not saying it is (or not) a bug, just that it needs documentation as well
something to refer when I'm doing discrimination like:

if (empty($element['#array_parents']) && in_array($element['#type'], array('radio', 'radios', 'hidden'))) {
  ...
}
arhak’s picture

BTW, IMO it is out of question that it should be documented
I'm using #parents to walk $form_state['values'] while #array_parents to walk $form (mostly from an $element to its parent or siblings)

EDIT: typo

sun’s picture

Form API reference used to contain all properties known to Form API some time ago, including internals. Didn't look up whether that's still the case, but that was very very very helpful in the past.

jhodgdon’s picture

Status: Active » Postponed

OK, it should be documented, I'm convinced. And yes, we still have at least some internal-use items in the FAPI doc.

I'd like to defer fixing this right now though. We're dreaming up a better way to generate the extremely difficult to maintain Form API reference page, over in the API module issue queue.
#100680: [meta] Make API module generate Form API documentation

rfay’s picture

Assigned: Unassigned » rfay
Status: Postponed » Active

I'll try to add this into the existing FAPI reference, if you have no objection, jhodgdon.

jhodgdon’s picture

There are about 6 issues I postponed for this.... If you want to do all or some of them, that's fine, but there are plenty of other doc issues that could be worked on. :)

rfay’s picture

Status: Active » Fixed

Added #array_parents to the doc: http://drupal.org/cvs?commit=369134

Thanks, sun, for the complete exposition. That made it easy. But it was so good I added a pointer to it.

JohnWoltman’s picture

Status: Fixed » Needs work

Line 131's href points to #access instead of #array_parents

rfay’s picture

Status: Needs work » Fixed

@JohnWoltman, thanks for your conscientious attention.

JohnWoltman’s picture

Status: Fixed » Closed (fixed)

I noticed it when using the FAPI reference :)

qqboy’s picture

Issue summary: View changes

why can not reply to a specific post. What i want to say to @sun is: if possible or why not use code details to make your points clearer. one year ago, i see you post, i nearly understand, but now i see again, then i thought i understand, but still feel not able to explain what you said by code details, such as what line of code can explain what you said.