Needs work
Project:
Drupal core
Version:
main
Component:
options.module
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
11 Jan 2014 at 00:49 UTC
Updated:
1 May 2026 at 15:41 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
yched commentedComment #2
plopescMoving the code from
options_allowed_values()toListItemBase::getSettableOptions()does not make any problem.However,
options_allowed_values()is also called fromDrupal\field\Plugin\views\argument\FieldListandDrupal\field\Plugin\views\argument\ListString, where I was unable to access toListItemBase::getSettableOptions().We could duplicate the code in those view plugins, but this looks weird IMHO. Or maybe create a service which could be accessible both both places. Or there is a hidden way to access to the Field Item from the view plugins I'm unable to find...
Any thoughts?
Regards.
Comment #3
dawehnerIt seems to be that making this method protected was kind of wrong?
Comment #4
yched commented@dawehner - hmm, there's no protected method here ?
Well, views calls options_allowed_values() without the non-optionnal second argument (and rightfully so, there is no known $entity in this calling context...). So it's probably not working anyway...
Actually, that's probably tied to #2012130: Regression: Views integration for "list" field types is broken, which I haven't followed in a while :-/
(also, it's a bit weird that those two FieldList and ListString classes are almost 1:1 duplicates ?)
Comment #5
plopescSo, should we postpone this issue on #2012130: Regression: Views integration for "list" field types is broken or maybe move the function to
ListItemBase::getSettableOptions()and manage the allowed values issue in views there?Comment #6
yched commentedPostponing sounds safer IMO. Sorry for pointing you to a deadend issue @plopesc :-)
Comment #7
sunHuh. Am I missing something?
Comment #9
sunOops.
Comment #11
sunOK, I guess I assumed we'd have made more progress on the Entity Field API DX by now ;-)
Not sure how to resolve these:
It looks like
$fieldcan be aListItemBase,FieldConfig, orConfigFieldItemList, depending on what exactly the code in context understands under$field? :P ;)Comment #12
yched commented@sun :
You're adding a getAllowedValues() method on ListItemBase, i.e an object like $entity->field_name[0]
But then you're calling it on:
- (in the views handlers) a FieldDefininitionInterface object, i.e field_info_field($e_t, $field_name) or $entity->field_name->getFieldDefinition()
- (in OptionsDefaultFormatter) a FieldItemList, i.e an object like $entity->field_name
So yeah, Call to undefined method :-)
Note that the View case is one of the challenges : it needs a list of allowed values for the field without having an actual entity, and thus without a FieldItem object. So if the getAllowedValues() method lives on the FieldItem class, it needs to be a static.
When EntityNG was introduced, it masively used $field variables to refer to field values ($entity->field_name), while the "old" Field API masively used $field to refer to field definitions (field_info_field()).
Naming conventions have been agreed upon since then: $field_items / $items for values, $field_definition for definitions.
The code has been progressively updated to reflect those naming conventions, but it's very likely that there are remnants, we usually try fix them when we see them.
I don't see where the ambiguity would be in the code involved in the patch though ?
Comment #13
andypostThis function blocks "merge Drupal\options\Plugin\Field\FieldType\ListBooleanItem into Drupal\Core\Field\Plugin\Field\FieldType\BooleanItem"
Comment #20
claudiu.cristeaThis fulfills #1577902: [META] Remove all usages of drupal_static() & drupal_static_reset() regarding removal of
drupal_static()& Co. fromoptions_allowed_values().Comment #21
andypostComment #22
plopescHello,
I tried to work today on this issue. It seems that finally I got something workable, but it's been more complex than expected. The fact that
FieldStorageDefinitionInterface::getOptionsProvider()method requires to pass an entity made it quite hard in the Views situation, where the entity was not directly available.Also the fact that requiring an instance of
ListItemBaseto have access to that options that can be directly accessible from the fieldStorage made it a bit tricky.Not sure if this is the best approach or maybe we could try to use a service or similar that could manage the options allowed values.
Attaching a prrof of concept path. Let's see if testbot agrees.
Regards
Comment #23
plopescUpdating issue status
Comment #24
plopescAttaching a new version. Last one had the wrong base path.
Sorry for the noise.
Comment #26
plopescNew version trying to solve issues found by testbot.
Comment #28
plopescNew try fixing tests.
Comment #30
plopescAnother try
Comment #31
aleevasComment #32
berdirthis does mean we lose the ability to use this function in combination with a allowed values callback?
Also, looks like the cacheable-feature was removed.
And I don't think the approach you have with views is feasible, the APi was defined for entity to be optional.
Maybe a static method or a service as you suggested would be better.
Comment #33
plopescHello,
Thank you for your review. As mentioned in my last comment, this approach is not the best and needs some improvements in order to get the final solution.
Regarding your comments:
We did not use the allowed values callback in that situation because the method is defined at the
ListItemBaselevel and in that method I don't have access to it, so the less bad solution was to use the allowed values property.Given that we store the allowed values as a property at the
ListItemBaselevel, I believe it's not necessary to add the cache layer.It is optional in the current APi, but if we rely on the
FieldStorageDefinitionInterface::getOptionsProvider(), it is now required. In the issue where it was introduced, it was commented that it could be optional in the future. However, it has not happened yet.Agree, otherwise I think we would have to break so many things to have this in place.
Do you have any idea? Some discussion or guidance would be much appreciated.
Comment #34
plopescHi,
Here is a new patch following a simpler approach as a proof of concept. Just replace
options_allowed_valueswith a service that behaves in the same way.Of course, it would require some cleanup, but just throwing the idea to start the discussion.
Comment #36
plopescSorry, forgot to add the new file to the patch.
Comment #37
idebr commentedThe related issue #1909744: Allow adding predefined lists to the options fields via plugins implements a plugin manager for predefined list that provides the same DX as the current
options_allowed_values()Comment #40
hardik_patel_12 commentedUpdating deprecating message drupal:8.8.0 and will be removed from drupal:9.0.0 to drupal:9.1.0 and will be removed from drupal:10.0.0
Comment #41
heddnLinking #3161345: options_allowed_values() cache pollution, which would effect what we're working on here.
Comment #44
berdirthe local variable doesn't do anything it seems, the method is over after this.
same.
Also the usual deprecation version updates.
Comment #45
dhirendra.mishra commentedI have re-rolled it against 9.3.x and fix from #44.
Kindly review it
Comment #46
berdirSee coding standard issues linked on "Custom Commands Failed".
Comment #47
ankithashettyTried fixing custom command failure errors, thanks!
Comment #48
joachim commentedLooks good overall, but:
All of these calls to the new service should have it injected into the plugin.
Comment #49
geek-merlin@plopesc #33:
The current patch essentially moves code from a function to a static method, which is IMHO not the idea of the original IS.
I think that this (FieldStorageDefinitionInterface::getOptionsProvider()) is the way to go, rather than last patch. Or du i miss something?
Comment #50
vsujeetkumar commentedFixed the "custom command fail issue", I am not sure that link is correct, Please have a look and advise.
Comment #51
berdirso the drupalci check expects the next @see after @deprecated to be a link to the change record. We could still keep the old reference as long as it's below the URL.
The URL would need to go the change record though, and not this issue.
\Drupal\Core\Field\FieldStorageDefinitionInterface::getOptionsProvider() has a required $entity argument, while this service does not. I don't think that it is possible to online the implementation directly into \Drupal\options\Plugin\Field\FieldType\ListItemBase::getSettableOptions() because getting a list item object without an entity is very tricky and would require to create a dummy content entity at runtime for e.g. views filters. All the calls in the options.module views filter/argument plugins do not pass an entity and can't do so.
I don't see a problem with having this as a separate service, seems like the only feasible option?
Comment #52
berdirRe #48: typed data plugins do not support DI. But views plugins do, see below.
"Array containing" seems a but superfluous, suggestion: "Cached allowed values, keyed by field target type, field name and whether or not an entity was provided as context"
this description needs to be synced with what's on options_allowed_values(), this trait doesn't exist anymore.
I'd suggest to use getAllowedValues(), I think we're going away from methods that have that shortened way. Helps to make it clear that it returns that value and doesn't set or something.
the views filter plugins could use DI.
Comment #53
dhirendra.mishra commentedWorked on points 1 and 4 (DI) from #52.
Other points still need work...
Hopefully it helps somewhere...
Comment #59
claudiu.cristeaComment #60
claudiu.cristeaComment #62
nicxvan commentedIt'd expand this to both remaining functions probably
Comment #63
nicxvan commentedComment #64
nicxvan commentedComment #65
nicxvan commentedComment #66
claudiu.cristeaReady for review.
Comment #67
claudiu.cristeaComment #68
smustgrave commentedSorry this one appears to need a rebase please.
Comment #69
claudiu.cristeaCreated #3583435: PP-1 Deprecate/remove ListItemBase::submitFieldStorageUpdate() as followup which is blocked on this.
Ready for a new review
Comment #70
smustgrave commentedLooks good to me but will let nicxvan mark it as he’s been more involved in the review already
Comment #71
nicxvan commentedI think this is ready now!
This one is surprisingly complex and there is one follow up.
Deprecations are the correct versions and consistent.
Only thing that might be worth thinking about is
OptionsAllowedValuesInterface, but it might make sense to allow that to be swapped out.New files have
declare(strict_types=1);Comment #72
larowlanWe had a broader plan for how to tackle this in #2329937: Allow definition objects to provide options as part of the D8 entity API lifecycle.
We just never got time to finish it - but the API over there still sounds very solid.
In this issue we're moving the legacy function and introducing OptionsAllowedValuesInterface which is another API we will have to support/deprecate if we ever finish that work.
Was any consideration given to moving the logic of OptionsAllowedValues internal to
ListItemBase::getSettableOptionsand making that the new permanent API we replace `options_allowed_values` with?Then the views plugins could use `$this->getFieldStorageDefinition()->getOptionsProvider()->getSettableOptions()` instead of injecting the new service.
I'll ping @fago for his thoughts.
Comment #73
nicxvan commentedYes, in fact that was the original approach, looks like it was pivoted in 34 due to 32 and 33.
Comment #74
oily commentedRan the manual 'test-only' test. Output:
https://git.drupalcode.org/issue/drupal-2171397/-/jobs/9261107
LGTM.
Comment #75
nicxvan commentedThank you @oily, however, running test only is only really helpful for Bugs. This is a Task the test only fails because the new service that was created no longer exists, not because there is a specific test tracking something.
We don't need to run test only for Tasks.
Comment #76
oily commented@nicxvan Okay, thank you for the reminder. I misinterpreted the output, too.
Comment #77
nicxvan commentedNo problem!
Comment #78
nicxvan commentedI went through 32-34 in more detail and I think it's talking about the second parameter in
options_allowed_values(FieldStorageDefinitionInterface $definition, ?FieldableEntityInterface $entity = NULL)Looking in contrib about half or more of the calls seem to be without the optional parameter, putting it on ListItemBase essentially makes this required.
https://search.tresbien.tech/search?q=options_allowed_values
The views comment also seems accurate too, but I'm less sure I understood that correctly.
Comment #79
larowlanRe #78 thoughts then on emitting a deprecation error from the new interface if $entity is not passed?
That gives us a chance to move to the desired API in a subsequent major.
Comment #80
smustgrave commentedShould this be NW for the latest feedback?
Comment #81
nicxvan commentedYes