Activity.get with custom field in return parameter returns unrelated custom fields in APIv3
This is a rather obscure bug we hit recently, and while I don't think it's worth fixing at this point in the APIv3 lifecycle, I'm documenting it here in case anyone else runs into it.
In APIv3, when a custom field is requested via the return
parameter, Civi will also return other custom fields if they have a default value set. This includes cases where the custom field is not enabled for the relevant activity type and where the relevant activity doesn't actually have a record in the corresponding custom field table.
We have code that roughly looks like this:
civicrm_api3('Activity', 'get', [
'return' => ['id', 'custom_39'],
'id' => 631,
]);
On the same installation, there's another custom field group that is not enabled for the associated activity type. This field group has a custom field - custom_40
- with a default value set. The following API result is produced:
{
"is_error": 0,
"version": 3,
"count": 1,
"id": 631,
"values": [
{
"id": "631",
"custom_39": "bar",
"source_contact_id": "203",
"source_contact_name": "demo@example.com",
"source_contact_sort_name": "demo@example.com",
"custom_40": "2",
"custom_40_-1": "2"
}
]
}
(In our case, the results were modified and later passed back into an Activity.create
API call. This has the side-effect of actually creating a database row for an activity-type-limited custom field group, which is arguably kind of a bug as well.)
None of this behaviour applies to APIv4, so I'm happy to leave this as-is.