Updated: Comment #0

Problem/Motivation

Because drupal_array_merge_deep() has no option for preserving integer keys, the call in line 294 of options_element.module can corrupt the #options key of the options element.

Steps to reproduce

  1. Add a list field to a content type with integer keys for the allowed values, that do not represent the natural array order, i.e. use 10, 100, 1000, instead of 0, 1, 2, ...
  2. Add a node of that content type and fill out the field
  3. Go back to the edit page of the field
  4. Without changing anything, submit the form
    Expected result
    The form submission is successful
    Actual result
    You get a validation error saying
    Allowed values list: some values are being removed while currently in use.
  5. To investigate the problem, look closer now at the keys that the options element is presenting.
    Expected result
    10, 100, 100
    Actual result
    0, 1, 2

Proposed resolution

It would be nice if drupal_array_merge_deep_array() had an option for preserving integer keys, just like the equivalent method in D8 has. I re-opened #1825466: Allow NestedArray::mergeDeepArray() to preserve integer keys for the purpose of backporting, but I don't think we need to wait for that.

The problem occurs only, because in _options_element_add_allowed_values_element() $default_element declares the #options key as an empty array. This causes drupal_array_merge_deep(_array)() to merge array() with the passed-in $element['#options'], if that exists. In all 2 cases where the function is called, however $element['#options'] is set. So we can just remove the default empty array and get rid of this problem.

This is an behavioral change in the _options_element_add_allowed_values_element() function, but since that is marked private by the leading underscore I'm not sure that should be considered an API change. One could, of course, also find 100%-BC-compatible solutions to this problem.

Remaining tasks

Review patch.

User interface changes

-

API changes

- (Maybe, see above)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tstoeckler’s picture

Status: Active » Needs review
FileSize
704 bytes

Here's the patch.

Tested this locally and it works as expected.

quicksketch’s picture

Status: Needs review » Fixed

This works for me. We don't really need to provide #options anyway, since it'll be provided by hook_element_info() if needed to prevent notices. Committed to 7.x-1.x.

  • Commit 3def9b2 on 7.x-1.x by quicksketch:
    Issue #2205823 by tstoeckler: Options element corrupts integer keys of...

Status: Fixed » Closed (fixed)

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