Problem/Motivation
Its not possible to remove the last third party setting on config import.
Proposed resolution
ConfigEntityStorage::updateFromStorageRecord()
creates a new entity and copies the values over to the existing entity. This then does not account for properties that are not in the export. The solution is to iterate over all the properties that could be exported. This means we need to refactor the code in ConfigEntityBase::toArray()
so we can get the property list in the ConfigEntityStorage class.
Remaining tasks
User interface changes
None
API changes
Move schema fallback from ConfigEntityBase::toArray()
to ConfigEntityType::getPropertiesToExport()
. Add optional $id
argument to ConfigEntityType::getPropertiesToExport()
that is used when using the schema fallback. The $id
argument is provided when using ConfigEntityBase::toArray()
so there is no loss in functionality.
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#50 | 2666392-50.patch | 16.37 KB | alexpott |
#50 | 45-50-interdiff.txt | 847 bytes | alexpott |
#45 | 2666392-45.patch | 16.37 KB | alexpott |
#45 | 43-45-interdiff.txt | 1.25 KB | alexpott |
#43 | 2666392-43.patch | 16.13 KB | alexpott |
Comments
Comment #2
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedThe path should fail because its a test only patch.
Comment #3
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedThe config export should contain the the empty third_party_settings property.
ConfigEntityStorage::updateFromStorageRecord
is related for the import, the foreach in line 458 iterates over the properties of the imported data only and not all properties of the config entity.The unset was introduced in #2361775: Third party settings dependencies cause config entity deletion.
Comment #6
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedComment #9
BoobaaRerolled the patch from #6 which solves the problem for me (and applies cleanly both to latest 8.1.x and 8.2.x).
Comment #11
alexpottI think this is exposing a bug in
ConfigEntityStorage::updateFromStorageRecord()
it is not copying over the values from the new entity to the existing entity properly.This solution is completely different from the the solution in #3 because it is a generic solution. Interdiff is to #2 - the test only patch.
Comment #12
alexpottComment #13
alexpottFor me this is at least a major bug because config imports produce an unexpected result - i.e. you can't remove the data. Also realised the new method on
ConfigEntityBase
needs to go on the interface. The reason it is underscored is because ConfigEntityBase will be one of the most extend classes we have and there is no point breaking existing code.Comment #14
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedComment #17
alexpottEvery time I change this interface I see this fail in ViewUI :)
Also we don't need to be mucking with uuid fields in updating an entity.
Comment #18
BerdirThere are some config entities that override toArray() and do special things.
If they add/remove properties completely, could that cause a problem in that the new method would not work as expected? Haven't really thought it through or identified a specific problem, just want to make sure that we don't introduce bugs for them.
Some of the overrides might also no longer be necessary, some example implementations:
EntityDisplayBase, just removes sub-keys
Flag (unecessary I think)
Currency/CurrencyLocale (not sure, many things could be removed probably but Xano likes to do special things ;))
search_api Server
FilterFormat (the roles thing is both unproblematic here I think and weird in general)
I think we did add new methods without underscore in minor versions before but probably none that are extended so often.
Comment #19
XanoCan we add this to a new, optional interface?
Comment #20
alexpott@Xano do you have config entities not extending from ConfigEntityBase?
Comment #21
alexpottComment #22
Xano@alexpott: I haven't, but it may break tests using Prophecy (unmocked method calls raise errors). It's technically a BC break, though, and I'm wondering if there is a feasible way to avoid that, and make it pretty again in D9.
Comment #23
alexpottWe explicitly stated that EntityInterface are subject to change and that you should inherit from the base classes and that we would change these interfaces by making additions in minors.
Comment #26
dawehnerThat's a totally valid question to think about.
I think this should not be an issue. When the configuration is removed, it won't be part of the schema, as it will never be exported to YML files in the first place, so the expected data doesn't change.
I doubt this kind of change will land in a patch release anyway. When its not a patch release we have clearly stated that adding methods is possible.
Personally as long we do that in a minor release, not using the underscore would be find.
Can we use '.sync' to make this test code more clear?
Comment #27
dawehnerComment #28
albertski CreditAttribution: albertski at Xeno Media, Inc. commentedI ran into a problem where we removed field groups from our node display but during configuration import on dev and production, it would not import. I wouldn't get any errors or anything.
Patch #17 fixed the issue for me. (Thanks @Berdir for pointing me here from my Drupal Answers question).
Not sure if I should mark this as RTBC or Needs Work. (I'm just not a big fan of having the underscore in _getPropertiesToExport()).
Comment #29
alexpottRe #26 - thanks for the review. I've fixed point 1. Re point 2. I'm not sure what you are getting at \Drupal\Tests\system\Functional\Entity\ConfigEntityImportTest::assertConfigUpdateImport() works by writing to the sync directory. I've improved the variable names - hopefully that helps.
Comment #30
alexpottComment #31
dawehnerThis looks great for me!
I guess this should be singular here? A third party setting.
Comment #32
alexpottFixed #31 = thanks @dawehner
Comment #33
alexpotthmmm... I've looked at this patch some more and I'm uncomfortable with adding getPropertiesToExport() to the ConfigEntityInterface when we have exactly the same method on the ConfigEntityTypeInterface. I think what we should do is move the config schema checking fallback to the ConfigEntityType implementation and deprecate it - basically make the
config_export
mandatory in Drupal 9. This is good for performance and doing things one way.Comment #37
xaqroxRerolled patch against 8.4.5, cuz I need it.
Comment #38
alexpottThanks for reminding me of this issue! Here's a patch with fixed tests.
Comment #39
alexpottLet's move the deprecation to another issue so this can be just about fixing the bug. See #2949021: Deprecate schema fallback in ConfigEntityType::getPropertiesToExport
Comment #40
alexpottCreated a change record - https://www.drupal.org/node/2949023
Comment #41
alexpottComment #42
mdrescher CreditAttribution: mdrescher commentedHi,
What's the status on this one? I am Running Drupal 8.5 in production, and got stung by this with the DisplaySuite module!
Can I use the patch in #37, #38 or #39 in 8.5?
Cheers,
Michel
Comment #43
alexpottRerolled.
@mdrescher the latest patch is probably the one to use. Out of the three you've asked about #39.
Comment #44
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedI could not find this hunk it the old core? Could you explain thy the special case for uuid is required? Thanks!
Comment #45
alexpottIt's because we're using the annotation (or schema) to get the list of properties to update. So both UUID and third_party are in there even if they are not in the incoming values. Without this change
Drupal\KernelTests\Core\Config\ConfigImporterTest
will fail.That said the uuid key is hardcoded in config storage so let's use that. Config Entities need to have a key of
uuid
- there's just no way to use a different value and the configuration system work. So there's one little bit of tidy up we can do.I've also improved the comment to explain how this occurs.
Comment #46
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedThe new comment looks good. I reviewed the patch with @alexpott in person at Drupal Dev Days. I think this is ready to go.
Comment #48
mdrescher CreditAttribution: mdrescher commented@alexpott, comment #43
In the end I didn't use the patch, but got rid of the settings through manual intervention on PROD and committing to master, which isn't ideal, but it worked.
Thanks for working on this!
Comment #49
catchTwo minor issues, otherwise I think this is OK. It's hard to follow with the annotation and configuration schema fallback but agreed deprecating it in a follow-up is the best option here.
Is this not injected because we want to remove the code path? If so is it worth a comment to say that explicitly
We should reverse the sentence, the 'it' is a bit confusing in there.
"Falls back to determining the properties using configuration schema, if the config entity properties are not declared".
Comment #50
alexpottRe #49.1 Not really - it's because service injection into an entity type class it not possible. See \Drupal\Core\Entity\EntityType::getBundleConfigDependency() and \Drupal\Core\Entity\EntityType::getBundleLabel().
Fixed .2
Comment #51
catchCommitted b55ed6b and pushed to 8.6.x. Thanks!
Comment #53
Wim LeersDidn't this introduce a subtle BC break?
Per the CR (https://www.drupal.org/node/2949023):
But "properties to export" only is referring to top-level schema keys, and those are always the same, aren't they? There are situations where you don't have a configuration entity ID to pass in, yet still need the schema fallback — for example when determining which top-level keys ("fields") will be exposed via REST API or JSON API or GraphQL for a configuration entity type.
(We encountered this in #2977669: Spec Compliance: some entity types have an "id", "type" or "uuid" field, this violates the spec. First reported at #2483407-33: Allow configuration schema fallback in ConfigEntityType::getPropertiesToExport() to work without an ID.)
Comment #54
alexpott@Wim Leers nope this didn't introduce any BC - it was the same before this patch was committed. If we didn't have an ID then schema fallback didn't weork. Please don't re-open this issue. Let's continue to discuss the problem in #2483407: Allow configuration schema fallback in ConfigEntityType::getPropertiesToExport() to work without an ID.
Comment #55
Wim LeersOkay, so this didn't turn #2483407: Allow configuration schema fallback in ConfigEntityType::getPropertiesToExport() to work without an ID into a duplicate of this after all. Thanks for clarifying!
Sorry for reopening — looking back, I don't know how I concluded this was a subtle BC break… 🤔
P.S.: this issue's CR was not yet published — did that.
Comment #56
Wim LeersUpdate: apparently there is a subtle BC break, but a different one than I described 😅
See #2986901: Followup for #2666392: ConfigEntityTypeInterface::getPropertiesToExport no longer returns NULL, throws exception instead.
Comment #60
pfrenssen