Errors with multiple-contact reference field handling
Further to #2939 (closed), another issue has come to light with the way CiviCRM core handles contact reference fields with multiple selection.
In _civicrm_api3_custom_data_get()
, the possibility of multiple selection is not allowed for. This means that an array of values can be passed to CRM_Core_DAO::getFieldValue()
which fails because it expects a scalar $searchValue
.
// Shim to restore legacy behavior of ContactReference custom fields
if (!empty($fieldInfo[$id]) && $fieldInfo[$id]['data_type'] === 'ContactReference') {
$returnArray['custom_' . $id . '_id'] = $returnArray[$key . '_id'] = $val;
$returnArray['custom_' . $id] = $returnArray[$key] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $val, 'sort_name');
}
You also get a PHP warning Warning: Illegal offset type
, and on PHP 8 this would result in a fatal error.
Suggested modification to code:
// Shim to restore legacy behavior of ContactReference custom fields
if (!empty($fieldInfo[$id]) && $fieldInfo[$id]['data_type'] === 'ContactReference') {
$returnArray['custom_' . $id . '_id'] = $returnArray[$key . '_id'] = $val;
if (is_array($val)) {
$lookupValues = [];
foreach ($val as $contactId) {
$lookupValues[] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactId, 'sort_name');
}
$returnArray['custom_' . $id] = $returnArray[$key] = $lookupValues;
}
else {
$returnArray['custom_' . $id] = $returnArray[$key] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $val, 'sort_name');
}
}