![Announcement icon Announcement icon](https://cdn.statically.io/img/www.drupal.org/files/styles/grid-2-2x-square/public/announcements/drupal-evergreen-logo-280X280px%20%281%29_0.jpg?itok=PHpn6rCb)
Problem/Motivation
- Proper existence/functioning of field data requires that both the module providing the field storage definition (FSD) and the module providing the field type are installed.
- For configurable fields, the module providing the FSD is field.module, and field_system_info_alter() makes the field type's module required. Meanwhile, each field type module lists field.module as its dependency, which maybe doesn't make sense anymore, but as a result, that's effectively making field.module required so long as there's any configurable field, which is the desired result.
- For non-configurable fields, the module defining the FSD can/should add the field type's module as a dependency, so as long as the FSD-providing module is installed, we're successfully preventing uninstallation of the type's module.
- But, there's currently nothing preventing the FSD-providing module itself from being uninstalled.
Postponed on #2278017: When a content entity type providing module is uninstalled, the entities are not fully deleted, leaving broken reference (and thus also on #2335879: Change SqlContentEntityStorageSchema::requiresEntityDataMigration() to ask the old storage handler if it has data rather than assuming yes unless NULL storage which is blocking 2278017).
Proposed resolution
- Add code to
system_system_info_alter()
to make FSD-providing modules required if they have data.
Remaining tasks
Task | Novice task? | Contributor instructions | Complete? |
---|---|---|---|
Add automated tests | Instructions | ||
Draft a change record for the API changes | Instructions |
User interface changes
API changes
Comment | File | Size | Author |
---|---|---|---|
#59 | entity-field_prevent_uninstall-2338873-59.patch | 14.75 KB | plach |
#59 | entity-field_prevent_uninstall-2338873-59.interdiff.txt | 2.66 KB | plach |
#55 | entity-field_prevent_uninstall-2338873-55.patch | 14.69 KB | plach |
#55 | entity-field_prevent_uninstall-2338873-55.interdiff.txt | 706 bytes | plach |
#54 | interdiff.txt | 2.09 KB | swentel |
![Tag1 logo](https://cdn.statically.io/img/www.drupal.org/files/ads/tag1-issue-sponsorship.png)
Comments
Comment #1
effulgentsia CreditAttribution: effulgentsia commentedComment #2
effulgentsia CreditAttribution: effulgentsia commentedComment #4
effulgentsia CreditAttribution: effulgentsia commentedCome to think of it, I'm confused why we need this. Since this is for code-defined fields, shouldn't the module that adds the field to the entity type be the one to declare a dependency on the field type module? For example, node.info.yml has a dependency on text.module.
Comment #5
effulgentsia CreditAttribution: effulgentsia commentedOh, I see. The above is what threw me. So it's not necessarily the "field type" that's in use. The "provider" is the module that adds the field to the entity type, not the module that provides the field type.
Issue title and summary probably need fixing then.
Comment #6
effulgentsia CreditAttribution: effulgentsia commentedSame patch as #1, but without ending in
*install.patch
, since apparently, testbot doesn't like that.Comment #8
effulgentsia CreditAttribution: effulgentsia commentedComment #10
plachI posted a slightly different approach in #2298525-94: Test issue for Make ContentEntityDatabaseStorage handle changes in the entity schema definition. Not rerolling this as you made progress in parallel. I think the approach over there makes sense (it checks field data instead of the whole entity data), feedback welcome :)
Comment #11
yched CreditAttribution: yched commentedRe #5: well, if this is not about field types, I'm not sure what the rationale is ?
Comment #12
catchComment #13
plachThis includes the new approach mentioned in #10. The aggregator changes are needed to fix the
ConfigImportAllTest
, that was failing with the following exception:Which means the
Feed.php
is loaded beforeaggregator.module
. Moving the constant to an autoloaded file fixes this.Comment #15
plachRerolled after #2337927: SqlContentEntityStorage::onFieldStorageDefinition(Create|Update|Delete)() is broken for base fields.
Comment #17
plachSorry, wrong patch
Comment #18
xjmItsy-bitsy API change that would need a CR, I guess, though I think it would make sense to move this fix to its own issue? Especially since I don't follow why the patch is exposing this.
I'm trying to wrap my head around the implications of this. Is there a specific way to reproduce the data integrity issue in HEAD? Also, we'll for sure need test coverage here.
Comment #21
effulgentsia CreditAttribution: effulgentsia commentedFixed the title and summary based on me actually understanding the issue now :)
Removed reference to #2282119: Make the Entity Field API handle field purging from the summary, since I think the solution here might continue to make sense even after then, so adding that issue as just a related issue instead.
Comment #22
chx CreditAttribution: chx commentedAt least
$entity_type->isFieldable()
needs to change to$entity_type->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')
Comment #23
BerdirFieldableEntityinterface, actually, but yes.
Comment #24
xjmSo this is closely related to #2278017: When a content entity type providing module is uninstalled, the entities are not fully deleted, leaving broken reference, which is currently blocked on #2324055: Split up the module manager into runtime information and extension information.. @chx suggested the solution being proposed there might be more robust than a
system_info_alter()
. Thoughts?Comment #25
plachIt probably makes sense to follow the same approach, so let's wait for #2278017: When a content entity type providing module is uninstalled, the entities are not fully deleted, leaving broken reference to go in and figure out how to proceed here. Actually if we are able to address base field purging soon, we might even won't fix this.
Comment #26
xjmComment #27
YesCT CreditAttribution: YesCT commentedComment #28
fago#2278017: When a content entity type providing module is uninstalled, the entities are not fully deleted, leaving broken reference is close thus getting started with this one.
Comment #29
fagoPatch attached.
Attaching a version including #2278017: When a content entity type providing module is uninstalled, the entities are not fully deleted, leaving broken reference for the test bot as well.
Comment #30
fagoComment #31
fagoFixed an accidental change in KernelTestBaseTest.
Comment #33
plach#2278017: When a content entity type providing module is uninstalled, the entities are not fully deleted, leaving broken reference was committed.
This is already looking very good to me, I can't RTBC it though because I provided patches here.
Comment #34
fagoThanks. Re-uploading patch re-rolled against 8.0.x without any further changes.
Comment #36
chx CreditAttribution: chx commentedyay no more hook_system_info_alter . can we remove those that were added prior? just a random note.
Comment #37
tim.plunkett#2392293: Refactor hook_system_info_alter implementations to use ModuleUninstallValidatorInterface was opened for that
Comment #38
fagoWe should probably skip the fields in #15 to avoid *lots* of count queries being run for configurable fields. For configurable fields field data is going to be purged on uninstall anyway.
Also, as discussed with plach it would be nice to have countFieldData() available for all fieldable storages, but it looks like we miss an interface for them. I think it would make sense to create one and move it there though. It's a small API change, but in practice I doubt anyone is doing fieldable storage controllers which aren't based on ContentEntityStorageBase right now.
Comment #39
plachDiscussed with @fago the introduction of
FieldableEntityStorageInterface
so we can simplify code a bit.Also implemented @chx's suggestion from #36:
Comment #40
fagoThere is #2391829: ContentUninstallValidator relies on the not required ContentEntityStorage::hasData() method for moving this one, so I'd suggest to leave it where it is for now to prevent two changes moving it around.
Comment #41
plachFixed missing pieces from #38 and #40.
Comment #44
plachThis should be green again.
Comment #45
tim.plunkettThat overlaps with #2392293: Refactor hook_system_info_alter implementations to use ModuleUninstallValidatorInterface, which has the 1:1 conversion but also with PHPUnit tests.
Comment #46
plachReverted changes...
Comment #47
plachMeh
Comment #48
plachThis looks good enough to me, RTBC anyone?
Comment #49
yched CreditAttribution: yched commentedThe
$module_name != 'field'
check in the inner if() should be moved first thing in the method ?Comment #50
plachIt should, thanks :)
Comment #51
yched CreditAttribution: yched commentedThanks. Then the comment about why we skip field module should be moved accordingly.
Comment #52
plachOh, god, I'm sorry :(
Comment #53
pfrenssenHad a quick look, found a couple of documentation issues.
s/Dynamically//
This documentation is still identical to DynamicallyFieldableEntityStorageInterface, but this contains a subset of that, and having the "dynamic" part removed I suppose this is not correct any more.
This smells like it could better be split up in two methods: countFieldData() and hasFieldData(). That is probably out of scope for this issue.
Oops! Comment exceeds 80 characters ;)
Comment #54
swentel CreditAttribution: swentel commentedComment #55
plachFixed some more PHP docs.
Comment #56
effulgentsia CreditAttribution: effulgentsia commentedPatch looks good. "Needs change record" tag was added in #18, but the patch no longer includes that change, so removing the tag. I think this is ready.
Comment #57
alexpottcontent is what Node entities are called. Not everything is content. So this message could read something like
"There is content for the field Blah on entity type Content"
An @todo without an issue - do we really want to leave this in? If we do it needs a better explanation of why it is there and what better means.
Comment #58
alexpottAlso faics the reason text is never actually tested.
Comment #59
plachFixed #57 and #58.
Comment #60
alexpottThis issue addresses a critical bug and is allowed per https://www.drupal.org/core/beta-changes. Committed 85764e4 and pushed to 8.0.x. Thanks!