Spin-off from #558666: UX/security: Revamp text format/filter configuration

Fieldsets contained in a vertical tab #group are rendered twice, if the fieldset defines custom #parents.

I have absolutely no idea what vertical tabs have in common with #parents in the first place, but changing the logic to be based on #array_parents instead of #parents made them disappear entirely.

Debugging through this weird processing code some more, I found out that it doesn't add the fieldset's #group to $form_state if it defines custom #parents.

I have no idea why vertical tabs are stored by their #parents and not by their #group in $form_state in the first place, but trying to change this equally failed.

Let me state that I'm very confused by this code and the entire code smells like a hack. If you'd ask me, such code should not live in form.inc and definitely belongs into a separate module. But I guess that deserves a separate issue.

Attached patch fixes this bug.

However, I will not update the documentation, because I simply don't understand what this code tries to do, and why it thinks it has to do it. :(

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Status: Needs review » Needs work

The last submitted patch failed testing.

Status: Needs work » Needs review

sun requested that failed test be re-tested.

Status: Needs review » Needs work

The last submitted patch failed testing.

Status: Needs work » Needs review

sun requested that failed test be re-tested.

sun’s picture

Why did we introduce #type 'vertical_tabs' when each fieldset can be a #group on its own?

  // Each fieldset can be a group itself and gets a reference to all
  // elements in its group.
  $form_state['groups'][$parents]['#group_exists'] = TRUE;

If each fieldset can form a new vertical tabs group of its own, then the entire idea of introducing a separate #type to form groups is bogus?

Status: Needs review » Needs work

The last submitted patch failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
6.44 KB

So. The implementation is entirely wrong.

In-progress patch attached. Only remaining todo is that fieldsets that refer to a #group that does not exist are not rendered. I'm currently resolving that.

Dave Reid’s picture

Issue tags: +vertical tabs

Adding tag and subscribing.

sun’s picture

oopsie, forgot to merge the required drupal_render() change.

Status: Needs review » Needs work

The last submitted patch failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
9.06 KB

This one should pass and solves the odo I mentioned before.

sun’s picture

Priority: Normal » Critical

Since the current implementation breaks Form API, I seriously mark this as critical.

Patch passed, so RTBC? I really need to continue that Filter UI patch.

sun’s picture

Title: Vertical tabs do not work with fieldsets having custom #parents » Vertical tabs break Form API

Summary:

Problem

  • When a fieldset defines both #group and #parents, it is rendered twice.

Details

  • All form elements need to be able to define custom #parents to make the submitted form values appear at a certain location. If this breaks vertical tabs, then vertical tabs are broken.
  • All fieldsets are currently processed in form_process_fieldset(), conditionally checked for a #group property, and if existent, the fieldset is added to the corresponding group in $form_state by reference.
  • Additionally, form_process_fieldset() tries to make sure that a fieldset that should appear in a vertical tab, is not rendered at its original location by setting #printed = TRUE.
  • Additionally, form_process_fieldset() tries to make sure that all fieldsets that are contained in a vertical tab #group, but which are processed before the vertical tab #group is processed, are not rendered by setting #printed = TRUE.
  • Vertical tabs are supported recursively. This means that every fieldset that is processed can be a vertical tab container.
  • However, the group building (in $form_state) was entirely dependent on form elements that do not specify custom #parents and contained the assumption that #group == #parents.
  • As visible in my original patch, I was able to resolve the #parents problem by additionally accounting for #parents, but that broke "regular" vertical tab fieldsets that do not define custom #parents.

Resolution

  • Instead of trying to fully build vertical tabs groups and prevent rendering of fieldsets belonging to an existing group within form processing, we move the entire vertical tab processing to the stage where it belongs: rendering.
  • To accomplish this, we build up $form_state['groups'] during form processing for each fieldset that is processed, and we assign this entire data by reference to each fieldset's $element['#groups'] property.
  • The entire logic for rendering vertical tabs is moved into the existing form_pre_render_fieldset() function, where the entire form is already processed, but we still can access the vertical tabs groups to properly figure out which fieldset needs to be rendered (and where).
sun’s picture

Can we get this in?

sun’s picture

Status: Needs review » Fixed

ok, ahem....

Not really cool, but this fix was committed as part of #558666: UX/security: Revamp text format/filter configuration.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

yched’s picture