Suggested commit message
Issue #2361615 by Berdir, Gábor Hojtsy: Field type config schemas are not in the base schema.
Problem/Motivation
In #2183983-74: Find hidden configuration schema issues @berdir found that several base field schemas are with modules even though they should be provided by the system because they are usable and in fact used without enabling the modules.
Proposed resolution
Move those field schemas to the system level.
Remaining tasks
Tests.
User interface changes
None.
API changes
None.
Comment | File | Size | Author |
---|---|---|---|
#38 | interdiff.txt | 2.22 KB | Gábor Hojtsy |
#38 | 2361615-field-base-schemas-38.patch | 12.13 KB | Gábor Hojtsy |
#36 | interdiff.txt | 807 bytes | Gábor Hojtsy |
#36 | 2361615-field-base-schemas-36.patch | 11.33 KB | Gábor Hojtsy |
#32 | interdiff.txt | 785 bytes | Gábor Hojtsy |
Comments
Comment #1
Gábor HojtsyThis is very much aligned with other field types in the same file. Several were missing, the string one was missing a storage settings item. This is based on @berdir's patch in #2183983-74: Find hidden configuration schema issues with updates to key names. The tests there do not apply this needs its own tests. @Berdir should be credited when this is committed, adding suggested commit message.
Comment #2
Gábor HojtsyCarrying on tags from that issues, since we are resolving part of it here
Comment #3
Gábor HojtsyThe storage settings schemas are probably not correct yet, I took them verbatim from @berdir, they need one by one checking. It is highly unlikely they are all sequences of strings(?).
Comment #4
BerdirI did that based on other examples, it looks very weird to me as well but something else didn't work ?
I also included the string schema in #2068655: Entity fields do not support case sensitive queries as I had to change text there. Will conflict with that but I don't really care what gets in first.
Comment #5
BerdirAlso, it should be possible to verify this by adding the schema trait stuff to the ContentTranslationSettingsTest. That exploded badly without this and should pass with these fixes.
Comment #6
alexpottI think this should be:
Comment #7
alexpottThis should just be of the
type: field.string.storage_settings
Use
type: field.string.field_settings
- actually string has no field settings afaicsSimilar to string this just has a max_length integer value
There are no uri field settings.
There are no created field settings or storage settings. Tempting to just set these to type: ignore - or somehow fix the field config entities to not export the empty array.
Exactly the same as created. There are none.
Comment #8
Gábor HojtsyImplemented suggestions based on @alexpott. By defining the sequence without an element type, we define it as having elements of type 'undefined' which fails validation with amy strict understanding of the schema such as with config_inspector or SchemaCheckTrait that we are going to use for the tests.
I also noticed that the string long type's default value should be text type, not string and likewise the created and changed field default value types need to be ints not string.
Fixed one more minor typo in entity reference comment.
Comment #9
Gábor HojtsyLet's see a test for the config files in the content translation settings test as @Berdir suggested. Did not run this locally yet.
Comment #12
Gábor HojtsyMost fails on the fix+test patch are about base field overrides schemas missing. @vijaycs85 also identified those at #2358263: Adding missing configuration schema for views blocks but was deemed out of scope there. It should not be a huge deal to fix it here.
Comment #13
Gábor HojtsyA first try at content translation settings and base field overrides (which seem to be singular and not multivalued in defaults).
Comment #15
BerdirThat assumption is not correct, base fields can be multi-valued (they do need custom storage for that now, though) and could have multiple default values. But I've noticed this as well.
It's not just the multi vs. single value. The problem is also that the schema defines properties, like 'value' and default values are most of the time specified as scalar, as the entity field api takes care of expanding that to the main property of the first field item.
We probably need to convert it internally at some point, similar to how we expand it during setValue(). So 'whatever' needs to become array(array('value' => 'whatever')). Also note that 'value' is not hardcoded but should be derived from the main property name method of the specified field type.
Comment #16
Gábor Hojtsy@Berdir:
All right, is this field type based? Where do I find this in code?
That does not seem to be related to this issue? If this is also field type specific, then fine because the schema defines those keys per field type now not on system level.
Comment #17
Berdirmulti or single values is not field type specific. All field types can have multiple values theoretically and that is why the schema/default value.
The problem is that you need to go from this:
To the correct structure, which would be:
The reason setDefaultValue(1) works is that $entity->$field = 1, works as well, and it basically has the following logic:
1. In FieldItemList::setValue(), we have this:
2. In FieldItemBase::setValue():
This is actually not correct, instead of just using the first property, it should use $definition->getFieldStorageDefinition()->getMainProperty(), which would return value/target_id.
What I would try is add similar logic to BaseFieldDefinition::setDefaultValue(), but it might be easier to reverse it: First if you do not have an array, convert it to array($main_property => $value), and second if the first array key is not numeric, convert it to array(0 => $value).
Comment #18
Gábor HojtsyIn short from a schema perspective we should assume multiple default values, same as for other places and just fix the base field override config to express it like so?
Comment #19
BerdirYes. And it might be easier to already convert it to multiple in the base field definition and not just the override, so you don't have the additional complexity there when comparing and so on.
Comment #20
Gábor HojtsyReworking the schemas as a first step for multi-default values, which basically means mostly back to #9, so I rolled an interdiff comparing to that directly.
Comment #22
vijaycs85I guess, this will fail. we need to provide element under sequence.
Comment #23
Gábor HojtsyFixing the schema issue first in the content translation settings. So we have separate test results, I am uploading the fix for the base field definition default values as a separate patch (which includes the schema fix). I extended the unit tests and they pass locally. Not sure what else will explode and how.
Edit: looks like @vijaycs85 already submitted the schema fix. So my interdiff includes that too but ignore that. :) Removed the schema only fix patch since @vijaycs85's will result in test feedback properly.
Comment #25
BerdirNot else if, just two separate ifs.. Both checks need to be applied if you pass in "1".
Comment #27
Gábor Hojtsy@Berdir: uhm, no? The first one already does array(array()), no need for the second one? Why inspect the array if we know what we find?
Comment #28
Gábor HojtsySo the impressive 1.4k exceptions are due to #2248709: The root type of a configuration object can not be a sequence, the get() method on sequences will not resolve to subkeys. We definitely should not fix it here and neither postpone this on fixing that because the content translation settings are to be refactored to third party setting on language settings anyway in #2363155: content_translation.settings config is not scalable, so the best we can do here is to type it with ignore. Oh well.
Comment #30
Gábor HojtsyWell, so ignore does not support get() either. Since that would be a crude workaround, instead of starting to fix things to make a crude workaround work (unrelated to this issue), I opted for a different workaround, not asserting the schema of the settings for now. Added appropriate todo comments to existing issues.
Comment #32
Gábor HojtsySo the remaining 2 fails are funnily due to the EntityTest type specifying a uid reference value in a totally wrong way. It either needs to be using the substructure also with the main property name or just pass in a literal integer like in my fix. That then works flawlessly.
Based on prior results and this one locally tested, it should be green.
Comment #36
Gábor HojtsySo this simplification of EntityTest's uid default value would require that the EntityViewsDataTest unit test mocks more of the services so to be able to look that up. We can avoid that extra complexity by providing the full array structure properly, since we know it anyway. This should be green.
Comment #37
BerdirWe should probably document somewhere what formats are supported here?
Comment #38
Gábor Hojtsy@Berdir: well the existing docs on the method actually document it quite well:
This is not in the diff scope but is already there prior to patch. It is true the patch does not accept an empty array or null gracefully anymore. Null would become a nested array with a value/target_id of null. Not what is intended :D
However there was no test coverage for this, so I added test coverage to the unit tests and fixed the code. Also documented the non-indexed array option that the above snippet did not document before.
Looks good?
Comment #39
vijaycs85Looks good.
Comment #40
alexpottHmmm... I don't think this can be an integer - should be a string since entity IDs do not have to be an integer. We are also missing the 'target_uuid' key. Other than that looks awesome.
Comment #41
alexpottActually let's handle #40 in a critical follow since this is just moving the definition into core and this patch unblocks discovering other schema issues.
Comment #42
alexpottThis issue addresses a critical bug and is allowed per #2350615: [policy, no patch] What changes can be accepted during the Drupal 8 beta phase?. Committed 8f89d7b and pushed to 8.0.x. Thanks!
Comment #44
Gábor Hojtsy@alexpott opened that followup at #2366877: Entity Reference field schema incorrect for reference.
Comment #45
Gábor Hojtsy