Problem/Motivation
Drupal core ships with several list field storage, for example 'List (text)', 'List (integer)'. These fields allow the site administrator to enter allowed values from the UI. These fields also support an 'allowed_values_function' callback as an alternative to hardcoding these values.
When using an allowed_values_function, the Views filter differs from the allowed_values version as well as the Drupal core views filtering.
Allowed values:
Allowed values callback:
Proposed resolution
Use the Options views filter for fields with an allowed_values_function, so a filter can have multiple values.
Remaining tasks
- Write a patch
- Review
- Commit
User interface changes
The Views UI shows the Options filter for fields with an allowed_values_function.
API changes
None.
Data model changes
None.


Comments
Comment #2
idebr commentedAttached patch changes the views filter from Numeric to Options for option fields with an allowed_values_function.
Field storage configuration for testing purposes:
node.field_program_type_with_callback
Comment #3
drunken monkeyThanks a lot for reporting this! I wasn't aware of this method of specifying the available options, but of course we should support this, too. Your code also looks pretty good already, just made a few small tweaks – please see/test/review the attached patch.
We should also add test coverage for this, to make sure it keeps working. Would be great if you could add that, too!
Comment #4
idebr commentedRe #3
I would be happy to supply a test! It appears that currently there are not a whole lot of tests available for the Field/Views UI. Could you provide some pointers to what type of tests you would like to have?
Comment #5
drunken monkeyGreat, thanks a lot!
I'd suggest a test like the following:
\Drupal\Tests\search_api\Functional\ViewsTest::regressionTest2949022()method.keywordswould be easiest, since that's already added as a Views filter as well) to have such an options callback.search_api_test_views.module.Please ask if you need any further pointers.
Comment #6
drunken monkeySetting to NR for the tests.
Comment #7
allie mickaThe options_allowed_values might be a better fit for this, as it implements caching and whatever other magic might be useful to the output. Patch updated accordingly.
I'm not sure of how to handle an upgrade path for this. When I changed this code in my own environment, I wound up with a broken handler and I had to remove and re-add the affected field. Surely this has happened before?
Comment #8
drunken monkeyHm, not sure why the handler broke. Probably it didn't have the settings it expected to get? Because I don't think Views actually takes the
plugin_idconfig into account at all (not sure why it's there), so I don't think it will care if that changes. Or does it?In any case, since it's not a trivial change, I don't think we can provide an update path for this, since it wouldn't be possible for us to determine which filters need to be updated. (I don't think accessing the Field API is “allowed” in update hooks.)
Which does raise the question what to do about this, if this really does break handlers (and, thus, views). We definitely want to avoid that when someone just updates the module, so maybe we'll need to have a config setting for whether to use this new code? Pretty ugly and making things unnecessarily complicated, but might still be the best solution overall.
Any other opinions/input on this?
Comment #9
idebr commentedLocally I used the same method as #7. However, this can be updated programmatically using hook_post_update_NAME :
Comment #10
allie mickaBummer that you can't go out and find where field handlers have been used during an update hook.
My recollection is the handler was indeed looking for settings that weren't there. Do you think there might be some way to keep the original handler if it was already established during _search_api_views_get_handlers()? Is that information available at that point? If so, nothing would change unless/until you removed and re-added the field and it wouldn't break in the interim.
Comment #11
drunken monkeyI'm not sure I understand you correctly, but if you do, then no, that's not possible. Views uses a single set of "Views data" for the whole site to determine which tables and fields are available and which handlers are available for each of them. There is no way to have a view keep using an old plugin while updating the Views data to use a new plugin for the same field. We'd have to define a second, "fallback" version of the field with the old handler, and switch all existing definitions to that version. But that version would then also appear in the selection when adding a new filter.
Comment #12
ronaldtebrake commentedNot sure if I can fully weigh in on the upgrade path issue here, since I'm working on a Distro and had to use some ConfigOverrides that add filters instead of update / change existing. So the fact that I'm not seeing a broken handler might not be very useful information.
However, the issue itself is indeed solved for my by #7.
I have rerolled this for usage on 1.15 so I can add this patch to our composer.json and make sure the allowed values callback is taken in to account correctly. Would be happy to share any helpful information.
And thanks for all your input!
Comment #13
sboden commentedWrote/rerolled the patch for search_api 1.29.0
I wrote the patch before finding this issue, in hindsight in exactly the same way as the already existing patches. Could this patch be merged, so we don't have to keep rerolling it: the patch is a clean solution. I'm using it in production on a Drupal 9.5.7.
Comment #14
drunken monkey@ sboden: Same as for the old patch, this is missing tests and an upgrade path.
Comment #15
sboden commentedTests are missing, ok.
For the upgrade path, that might be tricky. But, when you define a field with allowed_values_function, you can't use allowed_values in the Drupal GUI anymore - the options are mutually exclusive. So the patch is actually "new" functionality: without the patch search_api would only take allowed_values into account, after the patch allowed_values_function is also taken into account which people who defined a field as such would want to use. When allowed_values_function is filled in, allowed_values is empty anyway.
Are there people who defined a filter on a field using allowed_values_function but assume users will filter using its key as search criteria (without dropdown), I doubt it. That's e.g. why I ended up on this issue.
Comment #16
drunken monkeyAs described in #7, even if this is likely the expected behavior in general, specifically at an update this might break people’s views, which should really be avoided, if possible. Especially for a new feature, not a bug fix.
Comment #17
linhnm commentedRe-rolled for 1.31
Comment #18
socialnicheguru commentedDoes not work on the latest dev#34ccd9343
Comment #19
panda2ekino commentedRe-rolled for 1.38
i just move file previous patch code used in
search_api.views.inctosearch_api.views_hooksComment #20
socialnicheguru commentedno longer works with dev version of module
Comment #21
gueguerreiroRe-rolled patch for 1.40.
The code now uses the new [#Hook] method classes, so I placed the code included in the patches there instead (SearchApiViewsHooks.php).