I'm shocked that this is wrong, but it appears to be. list_field_update_forbid attempts to block removing list values that are in use, but in reality, it blocks adding new values, not deleting old ones. http://php.net/array_diff says "Returns an array containing all the entries from array1 that are not present in any of the other arrays.". Shouldn't our two arguments be reversed?

Comments

yched’s picture

Odd. There are tests for the behavior, that currently pass. My manual testing, back in #932502: Changing allowed values in "List" fields, worked ok too.

However, it does seem that manually testing the behavior now indeed doesn't work.
Got to run right now, no time to apply the patch or check the tests.

mr.baileys’s picture

Title: list_field_update_forbid logic is backwards? prevents updates to fields that adds list values » list_field_update_forbid logic is backwards

My manual testing worked ok too

An additional validation handler outside of list_field_update_forbid() also checks for removal of an in-use list value, so your manual test might have correctly blocked you from removing a value prior to hook_field_update_forbid being invoked:

list_allowed_values_settings_validate() in list.module:161

    // Prevent removing values currently in use.
    if ($has_data) {
      $lost_keys = array_diff(array_keys($field['settings']['allowed_values']), array_keys($values));
      if (_list_values_in_use($field, $lost_keys)) {
        form_error($element, t('Allowed values list: some values are being removed while currently in use.'));
      }
    }

When I disable the above form validation, I can successfully remove an allowed value even though it's in use, so Doug's assessment is correct. The automated tests also seem to only cover the form validation, not the list_field_update_forbid() invocation.

Doug's patch looks correct to me (although we should probably add a test against hook_field_update_forbid() for list.module), but leaving for someone with more field-experience to handle this...

sun’s picture

Version: 7.x-dev » 8.x-dev
Issue tags: +Needs tests, +Needs backport to D7

The patch is correct. And this means we have major bugs in our tests, in case this is indeed tested already. :(

marcingy’s picture

Part of the issue is that the tests did not create any field data to actually perform tests against so the logic was never being run. 2 patches attached first is test only and second is test plus fix above.

catch’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

Looks great, one line fix, nice test.

yched’s picture

Status: Reviewed & tested by the community » Needs review

Sorry, please don't commit just yet, something bugs me in the tests; just checking.

yched’s picture

StatusFileSize
new2.29 KB

Same fix, with a test that is slightly better integrated with the existing ones.
I dare say this is still RTBC, but I'll leave someone else push it back.

marcingy’s picture

Status: Needs review » Reviewed & tested by the community
webchick’s picture

Status: Reviewed & tested by the community » Fixed

Egad! Nice find, and thank you SO much for the tests on this bad boy.

Committed and pushed to 8.x and 7.x. Thanks!

boombatower’s picture

Just came across this bug, I couldn't believe it. :) Guess these things happen.

Status: Fixed » Closed (fixed)
Issue tags: -Needs backport to D7

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