Problem/Motivation
1. Create field of type "List (text)" with field add form, and fill the allowed values (they are not empty).
2. Export config of this field. It will be something like this (filename: 'field.storage.taxonomy_term.field_type.yml'):
langcode: en
status: true
dependencies:
module:
- options
- taxonomy
id: taxonomy_term.field_type
name: field_type
entity_type: taxonomy_term
type: list_text
settings:
allowed_values:
-
value: City
label: City
-
value: 'Administrative area'
label: 'Administrative area'
-
value: Continent
label: Continent
-
value: Country
label: Country
-
value: Region
label: Region
allowed_values_function: ''
module: options
locked: false
cardinality: 1
translatable: true
indexes: { }
3. Try to import this config on some fresh-installed Drupal 8 site. You will get an error:
"The configuration property settings.allowed_values.0.label.0 doesn't exist."
If you put this config in module config/install directory, you will get following in your php error log:
[Sat Jul 26 00:47:02.830178 2014] [:error] [pid 4305] [client 127.0.0.1:36675] Uncaught PHP Exception InvalidArgumentException: "The configuration property settings.allowed_values.0.label.0 doesn't exist." at /var/www/drupal/drupal8-core/core/lib/Drupal/Core/Config/Schema/Mapping.php line 66, referer: http://d8.local/admin/modules/list/confirm
4. If allowed_values are empty in config ('allowed_values: { }'), the config imports normally.
Proposed resolution
Add new methods to the config entity storage to massage data structures. Use them when importing configuration.
Remaining tasks
No
User interface changes
No.
API changes
Two new methods on the config entity storage interface, only additions.
| Comment | File | Size | Author |
|---|---|---|---|
| #33 | 2310093.33.patch | 23.78 KB | alexpott |
| #33 | 25-33-interdiff.txt | 9.03 KB | alexpott |
| #32 | 2310093.32.patch | 30.43 KB | hussainweb |
| #32 | interdiff-25-32.txt | 2.19 KB | hussainweb |
| #25 | 2310093.25.patch | 30.61 KB | alexpott |
Comments
Comment #1
andyceo commentedComment #2
andypostThis could lead to data loss, because no field is imported
Comment #3
alexpottHmmm... I guess we need to use mapFromStorageRecords in the import functions.
Comment #4
andypostSingle config import is broken too but works differently
Comment #6
berdirYeah, can confirm this.
I don't think this should be in the configuration system component, maybe field system or options.module.
The imported structure looks like this:
Comment #7
alexpottThis fixes import, install and the single import - and adds a test for single import updating an entity. Still need to write tests for the importer and installer. Also we need to clean up the code and agree the approach -
updateFromStorageRecordandcreateFromStorageRecordare quite ugly - but I'm not sure how we can avoid this.Comment #9
alexpottFixed the test.
Comment #10
gábor hojtsyHopefully cleaner title for this issue.
Comment #11
gábor hojtsyLooking at the patch, it is definitely the new / current reality following #2293773: Field allowed values use dots in key names - not allowed in config that config entities should be created with mapping from storage record and not by setting each property one by one. Is it not possible to swap out storage and load from the install / staging storage relying on the same code that would otherwise map from storage? Is that a pipe dream? :) Looks like needing to repeat that code several times may be painful.
Comment #12
alexpott#2314347: Remove config.storage dependency from ConfigEntityStorage will make it easier to explore @Gábor Hojtsy's pipe dream.
Comment #15
alexpottI'm not sure that swapping out the config storage on the config entity storage is the right thing to do - the mapping takes place on the config entity storage level. And we can not swap the config entity storage out since it is overridden by several classes. Is the current approach in #9 that bad?
Comment #16
berdirYes, I don't have a better idea, so lets move on with this.
I guess we still need tests for list field types?
Needs proper documentation and we probably have to add them to ImportableEntityStorageInterface?
Not sure what the comments are trying to say :)
Yeah, we have tons of entity types now there, wondering if we should solve that differently and only add the field when it is needed by tests. Not here, obviously.
Comment #17
alexpottAdded a test for importing list_float fields.
re: #16
Comment #19
alexpottImproved the test to cover the config installer too.
Comment #21
alexpottInteresting fail - floats can be integers - we need to update SchemaCheckTrait!
The other fails are because the config was generate before #2313757: Remove text_processing option from text fields, expose existing string field types as plain text in UI
Comment #23
alexpottSo... we have a problem comparing configuration that contains floats which have integer values. Patch contains a solution to do cast the source config data using schema to ensure they don't match.
Comment #25
alexpottFixed tests.
Comment #28
alexpottHere is a better upstream fix for the storage comparer issue - https://github.com/symfony/symfony/pull/11976
The issue we have to best illustrated by the following code:
which outputs
Our float has become an integer!
Comment #29
catchComment #32
hussainwebI am trying to fix the tests. The problem is that the property names have been changed:
default_value_function->default_value_callbackname->field_nameThe interdiff shows these changes.
Comment #33
alexpottWe have to remove all the changes to ConfigImporter and StorageComparer now that floats are properly persisted by the Yaml Component- now that #2350917: Update Symfony YAML library to support whole number floats landed.
pseudo-Interdiff back to #25 since I had to revert stuff from my local branch
Comment #34
berdirWondering why the postCreate() is not below the comment as well, but I assume that this was copied from somewhere?
This looks good to me, I think a change record is not needed, maybe we can explain the new methods somewhere in an existing one about config entities (which are probably all hopelessly outdated ;))
Comment #35
catchCommitted/pushed to 8.0.x.
Assuming the comment placement is just referring to the hook, we can follow-up to move it if we want.
Comment #37
gábor hojtsyYayayayay. Can finally ship option fields in modules/profiles. This has been an issue with the D8 multilingual demo profile too :) Thanks folks!
Comment #39
br0kenNow this problem appears in
8.2.0-rc1and this is really annoying. Could someone confirm this?Comment #40
alexpott@BR0kEN rather than opening an issue that was fixed 2 years ago can you please open a new issue that describes the exact steps to reproduce what you are seeing?
Comment #41
br0kenDid, @alexpott. Waiting for your opinion here: https://www.drupal.org/node/2802379