Problem/Motivation
Having special base classes and interfaces for configurable field types causes various problems/confusion (e.g. #2191709: Remove the "configurable" flag on field types) and makes progress harder on further unyfing configurable / base fields (e.g. #2150511: [meta] Deduplicate the set of available field types).
#2144327: Make all field types provide a schema() was the first step in this direction and this issue completes the goal.
Proposed resolution
Remove ConfigFieldItemBase
, ConfigFieldItemInterface
, ConfigFieldItemList
and ConfigFieldItemListInterface
and move the code from those base classes up a level.
Remaining tasks
Review the patch, commit, rejoice.
User interface changes
None.
API changes
- Configurable field types won't need to extend a special base class / implement a special interface, they just set a
configurable = TRUE
annotation property - Checking if a field type is configurable must be done with
FieldDefinitionInterface::isConfigurable()
(which is the current best practice anyway) instead ofinstanceof ConfigFieldItemListInterface
Comment | File | Size | Author |
---|---|---|---|
#48 | 2192259-no-cfield-48.patch | 40.89 KB | andypost |
#48 | interdiff.txt | 739 bytes | andypost |
Comments
Comment #1
amateescu CreditAttribution: amateescu commentedHere's an initial patch to get things started.
Comment #4
amateescu CreditAttribution: amateescu commentedOops, that patch was a bit old, this one should install at least.
Comment #5
amateescu CreditAttribution: amateescu commentedComment #7
BerdirI thought configurable defaults to TRUE anyway? Or is supposed to...
Comment #8
andypostOverall +1 to get rid of this classes & interfaces, the only difference between configurable and "none-configurable" that last does not provides default widget and formatter that was fixed in #2191709-11: Remove the "configurable" flag on field types
Why you wanna leave "configurable", I think "no_ui" better describes what this for
This makes developers to write more, but most of time contrib will provide a configurable fields, and TRUE is default in annotation
Comment #9
amateescu CreditAttribution: amateescu commentedRight, configurable is true by default :/
Comment #11
andypostMaybe better to find that items produced from "field instance"? because relying on some annotation in storage controller is bad idea
maybe just field instance? as variable named...
Also isConfigurable could simply check that $instance initialized...
this code already does that
suppose this needs test. base fields should have cardinality 1
what fallback could be done for fields that have no default widget
seems need separate issue - wtf email default formater from text module?
Comment #12
andypostComment #13
amateescu CreditAttribution: amateescu commentedActually, we should postpone this on #2114707: Allow per-bundle overrides of field definitions as that issue will clear the waters a bit in this area.
Comment #14
amateescu CreditAttribution: amateescu commentedSince #2114707: Allow per-bundle overrides of field definitions is rtbc, let's see how far we get with a reroll and a combined patch.
Comment #16
BerdirThe test fails are related to serialization, somehow the entity ends up with two langcode field items, one of them being empty.
No idea why that would be caused by this, so I asked @damiankloip to have a look.
Comment #17
damiankloip CreditAttribution: damiankloip commentedComment #18
BerdirThat limitation is removed in #597236: Add entity caching to core, so I'm fine with doing whatever needs to be done to make it work and then move on.
Ah, this is the what caused the rest tests to fail, we previously didn't validate the cardinality of base fields.. nice.
Can we move this within the "if (isset($data['langcode']) {" above, where it is used to set $langcode? That would be much more self-explaining than down here.
Other than that, I think this is ready to fly :)
To respond to @andypost's review above:
1. See my point above, will no longer be needed after that issue, so really doesn't matter what we chose.
2. This code is gone.
3. This too.
4. We're just moving code around here and rest.module was so nice to confirm that it works ;)
5. This I'm not sure about, can we throw an exception for now? I would simply say that a field that can be created through the UI must have a default_widget.
6. Unrelated.
Comment #19
damiankloip CreditAttribution: damiankloip commentedAgreed, that makes sense. Added a comment too (for future selves :)).
Comment #20
BerdirThat's fine, we still have 5. from @andypost's review, but I think we can deal with that in #2191709: Remove the "configurable" flag on field types?
However, based on a short discussions with @Crell, I got reminded that we in fact have a base field that has a cardinality > 1 and that is the user.roles field.
Right now, it's not possible to configure this for base fields, it's hardcoded to 1. That means that the validation will fail when trying to validate a user with more than one assigned user roles.
That's not happening right now, which means that UserValidationTest is missing test coverage for multiple roles. As this would introduce a bug and break rest for users with more than one role, I think it's blocking this issue, which means that we a) need test coverage for validating a user with more than one role (which should be valid) and add a setCardinality() to FieldDefinition.
Comment #21
fagoFrom where does the caller know whether it should present the form or skip it? Would it make sense to put this into an optional interface instead, e.g. FieldSettingsFormInterface or so?
Or is knowing this not important anyway?
Comment #22
damiankloip CreditAttribution: damiankloip commentedThrow an exception like this? If it's wrong, sorry, I don;t have much day to day business in this area of the code :)
I don't have time to write those tests now, I might in the next couple of days unless someone else gets there first.
Comment #23
yched CreditAttribution: yched commented@fago #21 : the caller (field_ui) calls the "form settings" methods only for fields where the settings can actually be saved - I.e. config fields.
The goal is that any field type can be used for config fields, so it's not up to the field type class to decide. Moving the methods to a separate interface (+ then with a base class ?) would be ... exactly what we have now :)
Comment #24
andypostSuppose the decision about "configurability" could be done per entity by some method
isBaseField()
otoh field_ui could override base fields definition to store instance settings and default values per bundle
Comment #25
amateescu CreditAttribution: amateescu commentedThat's being discussed in #2044859: Convert user roles to entity_reference_field and I still think that we cannot have multiple value support for base fields, for the reasons already stated in that issue.
Hence, IMO, there are no tests to write because we currently just give the impression that user roles is a multi-value base field, when it's not. And we can continue the discussion in the issue above instead of holding up this patch..
Also, I don't think we should address #11-5 here. I think the proper place to throw an exception is in the definition process phase of the field type plugin discovery, when we can check if the field type specifies a default widget or not.
Posting a new patch which reverts the interdiff from #22 :)
Comment #26
andypostThis applies to formatters too.
I disagree here, field type plugin manager should find and instantiate plugins, and corresponding managers (formatter and widget) or glue code should care about default values.
In #2191709: Remove the "configurable" flag on field types I specifically returns NULL when no default widget or formatter found in
getInstance()
.Probably we could introduce some kind of BrokenWidget and BrokenFormatter plugin to throw notice when formatter or widget not found
Comment #27
amateescu CreditAttribution: amateescu commentedSince we don't have an agreement on what to do when a field type doesn't specify a default widget/formatter, we should move that discussion to a different issue in order to move forward here :)
Comment #28
BerdirWe don't support to handle storage for multivalue base fields, but we have to handle the user role base field *somehow*. Which we already do.
However, we need a way to make set the correct cardinality there, otherwise it will be impossible to save users with more than one role through rest. And it is possible to do so right now, so IMHO, we need to fix that here.
I'm fine with moving the default widget problem to another issue.
Comment #29
andypostDiscussed with @Berdir at IRC - let's add
FieldDefinition::setCardinality()
with user role testAlso filed #2213727: Allow field types without default widget or formatter
So I think that one is RTBC
PS: removed @todo points to closed issue
Comment #31
amateescu CreditAttribution: amateescu commentedI don't get it, why do we bring #2044859: Convert user roles to entity_reference_field in scope here?
Comment #32
andypost@amateescu Do you have another idea to test cardinality?
I think it's a good usage of the api addition that have a great test coverage
Comment #33
amateescu CreditAttribution: amateescu commentedI don't see how we can test something that we don't support. If we want to have cardinality > 1 for base fields, this needs to work:
Otherwise.. where's the "good usage of the api"?
Comment #34
BerdirTrying to explain:
Yes, we should *not* make it an ER field here, agree with @amatescu on that as mentioned below too. We do need cardinality however:
This patch moves the cardinality validation from ConfigFieldItemBase to FieldItemBase. That means the cardinality is now (correctly) validated for base fields, and they must only have a single item. This is why the rest tests failed above as it added two languages, one being empty (that was then filtered out before saving).
We currently did not have any test cases that covered this, but the user roles field *has* unlimited cardinality, and we need a way to define that or it would be impossible to validate users with multiple roles. This is something introduced in this issue, so we have to fix it here.
Now, yes, your snippet does not work, but that has nothing to do with the cardinality. Passing in a single role would break as well. The issue to fix that is #1751274: Do not query user_roles directly and it should also work for multiple cardinality then.
We have to support cardinality for base fields, that does not mean that we need to support storage for them out of the box.
int
I think this should be @return $this now, without description?
It would be nice to extend FieldDefinitionTest::testFieldCardinality(), it already has a todo for this :)
Let's not do this here, this has nothing to do with this issue. We should only set the cardinality here.
Why do we need the config?
Let's keep the @todo, we still need to validate that only valid roles are assigned once we maked it an ER field and so on.
Comment #35
andypost1-3) Fixed
4) reverted
5) reverted, this is needed to import roles (anonymous and authorized)
6) reverted, updated @todo with proper issue #
Comment #36
andypostAdd test for user roles cardinality
Comment #38
BerdirThanks, I think that looks good now!
If my explanations didn't convince someone, speak up now :)
Two spaces after int, but I think we can clean that up on commit?
Comment #39
amateescu CreditAttribution: amateescu commentedWell.. you have my opinion. If a field needs to store multiple values, it shouldn't be a base field. Basically, I completely disagree with this:
Comment #40
andypostRe-roll to remove 2 spaces.
I think we can't be so strict here, because contrib could alter any definition, so fieldList is responsive about storage
Comment #41
alexpottDrupal\Core\Field\ConfigFieldItemList<code> still exists and implements the removed interface <code>ConfigFieldItemListInterface
Comment #42
andypostEDIT
ConfigFieldItemList
removalComment #44
andypostRe-roll after #2169361: Convert COMMENT_HIDDEN & COMMENT_CLOSED & COMMENT_OPEN to a constant on the comment field interface
Comment #46
andypost44: 2192259-no-cfield-44.patch queued for re-testing.
Comment #48
andypostAnd one more merge error
Comment #49
sunBack to RTBC. This looks like a great simplification, awesome! :-)
Comment #50
alexpottCommitted 7ce95f3 and pushed to 8.x. Thanks!
Existing change notices to update:
Comment #51
andypostAs I see all this change notices are outdated, maybe there's some issue to re-work them?
Comment #52
yched CreditAttribution: yched commentedyched_afk dances at the commit :) Awesome!
Comment #53
andypostUpdated https://drupal.org/node/2101747 & https://drupal.org/node/2076489 & https://drupal.org/node/2111927
https://drupal.org/node/2064123 needs serious changes, so better to wait for #2191709: Remove the "configurable" flag on field types