Add Entity Reference custom field type (implementing EntityRef QuickForm element type)
Overview
EntityRef
ist a QuickForm element type being used to reference CiviCRM entities in several forms. But there is no custom field type implementing this, apart from the ContactReference custom field type, which is (surprise!) restricted to referencing contacts.
Allowing users to model their "real world" use cases in CiviCRM using the UI without mis-using entity types for things they have not been intended for, just because you need some kind of relation between two things, would be a great improvement.
At this time, we are evaluating requirements for a current project where this might be needed, but wanted to discuss our thoughts with some Core people, especially @colemanw who already offered help with reviewing code, before we start, because this will have to be a PR to Core, probably with some refactoring involved.
Example use-case
With either Core or custom entities (such as multi-value custom field groups or ECK entities), you might want to model references to different "things" in your business logic, not just contacts.
Imagine a Project entity that you would like to add references to contacts, but also to specific activities, contributions, etc. - without a Project having to be a contact type or a Case, or a Campaign because that might not be suitable because of reasons.
Current behaviour
Only contact entites can be referenced in custom fields.
Proposed behaviour
- Add a custom field type Entity Reference with configurable
- entity type
- label property (a property of the selected entity type that will be used for displaying the referenced entity when rendering the field value)
- entity filters (API parameters for the entity)
- Migrate the Contact Reference custom field type to be an Entity Reference field type with Contact as the referenceable entity type and the
display_name
as the label property - Maybe allow custom field types be extendable, i.e. allow extensions to define additional custom field types
- Maybe add support for SearchKit (e.g. for defining filters or providing widget displays)
Technical Details
-
Contact Reference fields currently store their API filters in the
filter
column of thecivicrm_custom_field
table. The entity itself might be just added there - The label/title property might be stored in the
attributes
column, which is used for different stuff depending on the custom field type. Alternatively, a new column could be added to thecivicrm_custom_field
table (just as there are columns for other field types), although this is not that good of a design IMO - Alternatively, all field-type-specific configuration could be migrated into a generic JSON-formatted
configuration
orproperties
column, at least for this new field type for now. There are many columns only needed for specific field types:mask
options_per_line
text_length
start_date_years
end_date_years
date_format
time_format
note_columns
note_rows
option_group_id
filter
I think adding a new custom field type that stores its configuration in existing columns would be a good first step. Any thoughts on that?
After storing information about a custom field in civicrm_custom_field, a table is created for each group or set of custom fields to store the value of each field for each instance of the set of custom fields. The name of this table is stored in custom_field_group.table_name. This table correlates each record of custom field values with the entity they extend using meta-data about the custom field set to identify the table extended (I think there is a translation of value in custom_field_group.extends to the table name of the entity extended) and the id of the instance extended.
It would be good to support regular CiviCRM entities that are implemented as tables as well as the higher order entities of Order and Payment that have id fields and APIs but not table implementations.
Funding
Required: 40
Pledged:
- Third Sector Design - 8
- Systopia - 18
- Megaphone tech - 4 (depending on timeframe)
- JMA - 10
- Humanists UK - 5