Api4 - Support portable export/import for dynamic foreign keys - #36338
Merged
Conversation
Dynamic FKs (e.g. an `entity_id` column paired with an `entity_table` discriminator, as used by PriceSetEntity, EntityTag, Note, etc.) had no way to export/import portably: ExportAction only checked the static `fk_entity` field, so such columns always fell back to a raw, non-portable database id, and DAOActionTrait::resolveFKValues() had no way to resolve a `.name`-suffixed dynamic FK back to an id on write. ExportAction now resolves the concrete target entity for each dynamic FK from the record's own discriminator column value, and uses a `field.name` lookup instead of the raw id when that target entity has a `name` field (falling back to the raw id otherwise, unchanged). resolveFKValues() gains the matching write-side resolution, using the sibling discriminator column already present in the record to pick the correct target DAO. This is a generic, entity-agnostic framework change with no behavior change for entities whose dynamic FK target has no `name` field.
|
🤖 Thank you for contributing to CiviCRM! ❤️ We will need to test and review this PR. 👷 Introduction for new contributors...
PR commands & links...
|
mattwire
marked this pull request as draft
July 27, 2026 16:40
mattwire
marked this pull request as ready for review
July 27, 2026 16:55
Member
|
Looks great @mattwire |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Adds support for exporting/importing entities which use dynamic foreign keys such as
PriceSetEntity,EntityTag,Note, etc.Split out from #35329, where portability of
PriceSetEntity.entity_idwas raised as an open question by @mattwire and @ufundo.Before
Cannot export/import entities with dynamic foreign key (entity_table/entity_id)
After
Can
Technical Details
entity_idcolumn paired with anentity_tablediscriminator, as used byPriceSetEntity,EntityTag,Note, etc.) had no way to export/import portably:ExportActiononly checked the staticfk_entityfield, so such columns always fell back to a raw, non-portable database id, andDAOActionTrait::resolveFKValues()had no way to resolve a.name-suffixed dynamic FK back to an id on write.ExportActionnow resolves the target entity for each dynamic FK from the record's ownentity_tablecolumn value, and uses afield.namelookup instead of the raw id when that target entity has anamefield (falling back to the raw id otherwise, unchanged).resolveFKValues()gains the matching write-side resolution, using the sibling discriminator column already present in the record to pick the correct target DAO.namefield.Test plan
tests/phpunit/api/v4/Action/ExportActionTest.php: exports aContributionPage-linkedPriceSetEntity(portable, hasname) and anEvent-linked one (noname, falls back to raw id as before); also tests the write-side round trip.tests/phpunit/api/v4/Entity/ManagedEntityTest.php,tests/phpunit/CRM/Core/ManagedEntitiesTest.php, and other dynamic-FK-adjacent tests (FkJoinTest,EntityFileTest,TagTest,GetFieldsTest,CoreUtilTest) pass with no regressions.Comments