'rel_table_custom_groups' => [
'title' => ts('Custom Groups'),
'tables' => ['civicrm_custom_group'],
- 'url' => CRM_Utils_System::url('civicrm/admin/custom/group', 'reset=1'),
+ 'url' => CRM_Utils_System::url('civicrm/admin/custom/group'),
],
'rel_table_uf_groups' => [
'title' => ts('Profiles'),
foreach ($sqls as $sql) {
CRM_Core_DAO::executeQuery($sql, [], TRUE, NULL, TRUE);
}
- CRM_Dedupe_Merger::addMembershipToRealtedContacts($mainId);
+ CRM_Dedupe_Merger::addMembershipToRelatedContacts($mainId);
}
/**
* @throws \CiviCRM_API3_Exception
* @throws \Civi\API\Exception\UnauthorizedException
*/
- protected static function createContact($contactID, $params) {
+ protected static function updateContact(int $contactID, $params): void {
// This parameter causes blank fields to be be emptied out.
// We can probably remove.
$params['updateBlankLocInfo'] = TRUE;
- [$data] = CRM_Contact_BAO_Contact::formatProfileContactParams($params, [], $contactID);
+ $data = self::formatProfileContactParams($params, $contactID);
CRM_Contact_BAO_Contact::create($data);
}
+ /**
+ * Format profile contact parameters.
+ *
+ * Note this function has been duplicated from CRM_Contact_BAO_Contact
+ * in order to allow us to unravel all the work this class
+ * does to prepare to call this & create some sanity. Also start to
+ * eliminate a toxic function.
+ *
+ * @param array $params
+ * @param int $contactID
+ *
+ * @return array
+ */
+ private static function formatProfileContactParams(
+ $params,
+ int $contactID
+ ) {
+
+ $data = $contactDetails = [];
+
+ // get the contact details (hier)
+ $details = CRM_Contact_BAO_Contact::getHierContactDetails($contactID, []);
+
+ $contactDetails = $details[$contactID];
+ $data['contact_type'] = $contactDetails['contact_type'] ?? NULL;
+ $data['contact_sub_type'] = $contactDetails['contact_sub_type'] ?? NULL;
+
+ //fix contact sub type CRM-5125
+ if (array_key_exists('contact_sub_type', $params) &&
+ !empty($params['contact_sub_type'])
+ ) {
+ $data['contact_sub_type'] = CRM_Utils_Array::implodePadded($params['contact_sub_type']);
+ }
+ elseif (array_key_exists('contact_sub_type_hidden', $params) &&
+ !empty($params['contact_sub_type_hidden'])
+ ) {
+ // if profile was used, and had any subtype, we obtain it from there
+ //CRM-13596 - add to existing contact types, rather than overwriting
+ if (empty($data['contact_sub_type'])) {
+ // If we don't have a contact ID the $data['contact_sub_type'] will not be defined...
+ $data['contact_sub_type'] = CRM_Utils_Array::implodePadded($params['contact_sub_type_hidden']);
+ }
+ else {
+ $data_contact_sub_type_arr = CRM_Utils_Array::explodePadded($data['contact_sub_type']);
+ if (!in_array($params['contact_sub_type_hidden'], $data_contact_sub_type_arr)) {
+ //CRM-20517 - make sure contact_sub_type gets the correct delimiters
+ $data['contact_sub_type'] = trim($data['contact_sub_type'], CRM_Core_DAO::VALUE_SEPARATOR);
+ $data['contact_sub_type'] = CRM_Core_DAO::VALUE_SEPARATOR . $data['contact_sub_type'] . CRM_Utils_Array::implodePadded($params['contact_sub_type_hidden']);
+ }
+ }
+ }
+
+ $locationType = [];
+ $count = 1;
+
+ //add contact id
+ $data['contact_id'] = $contactID;
+ $primaryLocationType = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactID);
+
+ $billingLocationTypeId = CRM_Core_BAO_LocationType::getBilling();
+
+ $blocks = ['email', 'phone', 'im', 'openid'];
+
+ $multiplFields = ['url'];
+ // prevent overwritten of formatted array, reset all block from
+ // params if it is not in valid format (since import pass valid format)
+ foreach ($blocks as $blk) {
+ if (array_key_exists($blk, $params) &&
+ !is_array($params[$blk])
+ ) {
+ unset($params[$blk]);
+ }
+ }
+
+ $primaryPhoneLoc = NULL;
+ $session = CRM_Core_Session::singleton();
+ foreach ($params as $key => $value) {
+ [$fieldName, $locTypeId, $typeId] = CRM_Utils_System::explode('-', $key, 3);
+
+ if ($locTypeId == 'Primary') {
+ if (in_array($fieldName, $blocks)) {
+ $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactID, FALSE, $fieldName);
+ }
+ else {
+ $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactID, FALSE, 'address');
+ }
+ $primaryLocationType = $locTypeId;
+ }
+
+ if (is_numeric($locTypeId) &&
+ !in_array($fieldName, $multiplFields) &&
+ substr($fieldName, 0, 7) != 'custom_'
+ ) {
+ $index = $locTypeId;
+
+ if (is_numeric($typeId)) {
+ $index .= '-' . $typeId;
+ }
+ if (!in_array($index, $locationType)) {
+ $locationType[$count] = $index;
+ $count++;
+ }
+
+ $loc = CRM_Utils_Array::key($index, $locationType);
+
+ $blockName = self::getLocationEntityForKey($fieldName);
+
+ $data[$blockName][$loc]['location_type_id'] = $locTypeId;
+
+ //set is_billing true, for location type "Billing"
+ if ($locTypeId == $billingLocationTypeId) {
+ $data[$blockName][$loc]['is_billing'] = 1;
+ }
+
+ if ($contactID) {
+ //get the primary location type
+ if ($locTypeId == $primaryLocationType) {
+ $data[$blockName][$loc]['is_primary'] = 1;
+ }
+ }
+ elseif ($locTypeId == $defaultLocationId) {
+ $data[$blockName][$loc]['is_primary'] = 1;
+ }
+
+ if (in_array($fieldName, ['phone'])) {
+ if ($typeId) {
+ $data['phone'][$loc]['phone_type_id'] = $typeId;
+ }
+ else {
+ $data['phone'][$loc]['phone_type_id'] = '';
+ }
+ $data['phone'][$loc]['phone'] = $value;
+
+ //special case to handle primary phone with different phone types
+ // in this case we make first phone type as primary
+ if (isset($data['phone'][$loc]['is_primary']) && !$primaryPhoneLoc) {
+ $primaryPhoneLoc = $loc;
+ }
+
+ if ($loc != $primaryPhoneLoc) {
+ unset($data['phone'][$loc]['is_primary']);
+ }
+ }
+ elseif ($fieldName == 'email') {
+ $data['email'][$loc]['email'] = $value;
+ if (empty($contactID)) {
+ $data['email'][$loc]['is_primary'] = 1;
+ }
+ }
+ elseif ($fieldName == 'im') {
+ if (isset($params[$key . '-provider_id'])) {
+ $data['im'][$loc]['provider_id'] = $params[$key . '-provider_id'];
+ }
+ if (strpos($key, '-provider_id') !== FALSE) {
+ $data['im'][$loc]['provider_id'] = $params[$key];
+ }
+ else {
+ $data['im'][$loc]['name'] = $value;
+ }
+ }
+ elseif ($fieldName == 'openid') {
+ $data['openid'][$loc]['openid'] = $value;
+ }
+ else {
+ if ($fieldName === 'state_province') {
+ // CRM-3393
+ if (is_numeric($value) && ((int ) $value) >= 1000) {
+ $data['address'][$loc]['state_province_id'] = $value;
+ }
+ elseif (empty($value)) {
+ $data['address'][$loc]['state_province_id'] = '';
+ }
+ else {
+ $data['address'][$loc]['state_province'] = $value;
+ }
+ }
+ elseif ($fieldName === 'country') {
+ // CRM-3393
+ if (is_numeric($value) && ((int ) $value) >= 1000
+ ) {
+ $data['address'][$loc]['country_id'] = $value;
+ }
+ elseif (empty($value)) {
+ $data['address'][$loc]['country_id'] = '';
+ }
+ else {
+ $data['address'][$loc]['country'] = $value;
+ }
+ }
+ elseif ($fieldName === 'county') {
+ $data['address'][$loc]['county_id'] = $value;
+ }
+ elseif ($fieldName == 'address_name') {
+ $data['address'][$loc]['name'] = $value;
+ }
+ elseif (substr($fieldName, 0, 14) === 'address_custom') {
+ $data['address'][$loc][substr($fieldName, 8)] = $value;
+ }
+ else {
+ $data[$blockName][$loc][$fieldName] = $value;
+ }
+ }
+ }
+ else {
+ if (substr($key, 0, 4) === 'url-') {
+ $websiteField = explode('-', $key);
+ $data['website'][$websiteField[1]]['website_type_id'] = $websiteField[1];
+ $data['website'][$websiteField[1]]['url'] = $value;
+ }
+ elseif (in_array($key, CRM_Contact_BAO_Contact::$_greetingTypes, TRUE)) {
+ //save email/postal greeting and addressee values if any, CRM-4575
+ $data[$key . '_id'] = $value;
+ }
+ elseif (($customFieldId = CRM_Core_BAO_CustomField::getKeyID($key))) {
+ // for autocomplete transfer hidden value instead of label
+ if ($params[$key] && isset($params[$key . '_id'])) {
+ $value = $params[$key . '_id'];
+ }
+
+ // we need to append time with date
+ if ($params[$key] && isset($params[$key . '_time'])) {
+ $value .= ' ' . $params[$key . '_time'];
+ }
+
+ // if auth source is not checksum / login && $value is blank, do not proceed - CRM-10128
+ if (($session->get('authSrc') & (CRM_Core_Permission::AUTH_SRC_CHECKSUM + CRM_Core_Permission::AUTH_SRC_LOGIN)) == 0 &&
+ ($value == '' || !isset($value))
+ ) {
+ continue;
+ }
+
+ $valueId = NULL;
+ if (!empty($params['customRecordValues'])) {
+ if (is_array($params['customRecordValues']) && !empty($params['customRecordValues'])) {
+ foreach ($params['customRecordValues'] as $recId => $customFields) {
+ if (is_array($customFields) && !empty($customFields)) {
+ foreach ($customFields as $customFieldName) {
+ if ($customFieldName == $key) {
+ $valueId = $recId;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //CRM-13596 - check for contact_sub_type_hidden first
+ if (array_key_exists('contact_sub_type_hidden', $params)) {
+ $type = $params['contact_sub_type_hidden'];
+ }
+ else {
+ $type = $data['contact_type'];
+ if (!empty($data['contact_sub_type'])) {
+ $type = CRM_Utils_Array::explodePadded($data['contact_sub_type']);
+ }
+ }
+
+ CRM_Core_BAO_CustomField::formatCustomField($customFieldId,
+ $data['custom'],
+ $value,
+ $type,
+ $valueId,
+ $contactID,
+ FALSE,
+ FALSE
+ );
+ }
+ elseif ($key === 'edit') {
+ continue;
+ }
+ else {
+ if ($key === 'location') {
+ foreach ($value as $locationTypeId => $field) {
+ foreach ($field as $block => $val) {
+ if ($block === 'address' && array_key_exists('address_name', $val)) {
+ $value[$locationTypeId][$block]['name'] = $value[$locationTypeId][$block]['address_name'];
+ }
+ }
+ }
+ }
+ if ($key === 'phone' && isset($params['phone_ext'])) {
+ $data[$key] = $value;
+ foreach ($value as $cnt => $phoneBlock) {
+ if ($params[$key][$cnt]['location_type_id'] == $params['phone_ext'][$cnt]['location_type_id']) {
+ $data[$key][$cnt]['phone_ext'] = CRM_Utils_Array::retrieveValueRecursive($params['phone_ext'][$cnt], 'phone_ext');
+ }
+ }
+ }
+ elseif (in_array($key, ['nick_name', 'job_title', 'middle_name', 'birth_date', 'gender_id', 'current_employer', 'prefix_id', 'suffix_id'])
+ && ($value == '' || !isset($value)) &&
+ ($session->get('authSrc') & (CRM_Core_Permission::AUTH_SRC_CHECKSUM + CRM_Core_Permission::AUTH_SRC_LOGIN)) == 0 ||
+ ($key === 'current_employer' && empty($params['current_employer']))) {
+ // CRM-10128: if auth source is not checksum / login && $value is blank, do not fill $data with empty value
+ // to avoid update with empty values
+ continue;
+ }
+ else {
+ $data[$key] = $value;
+ }
+ }
+ }
+ }
+
+ if (!isset($data['contact_type'])) {
+ $data['contact_type'] = 'Individual';
+ }
+
+ return $data;
+ }
+
+ /**
+ * Get the relevant location entity for the array key.
+ *
+ * This function is duplicated from CRM_Contact_BAO_Contact to allow cleanup.
+ * See self::formatProfileContactParams
+ *
+ * Based on the field name we determine which location entity
+ * we are dealing with. Apart from a few specific ones they
+ * are mostly 'address' (the default).
+ *
+ * @param string $fieldName
+ *
+ * @return string
+ */
+ protected static function getLocationEntityForKey($fieldName) {
+ if (in_array($fieldName, ['email', 'phone', 'im', 'openid'])) {
+ return $fieldName;
+ }
+ if ($fieldName === 'phone_ext') {
+ return 'phone';
+ }
+ return 'address';
+ }
+
/**
* Load all non-empty fields for the contacts
*
*
* @param bool $checkPermissions
* Respect logged in user permissions.
- * @param bool|NULL $reloadCacheIfEmpty
+ * @param bool|null $reloadCacheIfEmpty
* If not set explicitly this is calculated but it is preferred that it be set
* per comments on isSelected above.
*
if (!isset($submitted['suffix_id']) && !empty($migrationInfo['main_details']['suffix_id'])) {
$submitted['suffix_id'] = $migrationInfo['main_details']['suffix_id'];
}
- self::createContact($mainId, $submitted);
+ self::updateContact($mainId, $submitted);
}
$transaction->commit();
CRM_Utils_Hook::post('merge', 'Contact', $mainId);
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
*/
- public static function addMembershipToRealtedContacts($contactID) {
+ public static function addMembershipToRelatedContacts($contactID) {
$dao = new CRM_Member_DAO_Membership();
$dao->contact_id = $contactID;
$dao->is_test = 0;
/**
* Build up the location block for the contact in dedupe-screen display format.
*
- * @param integer $cid
+ * @param int $cid
* @param array $blockInfo
* @param string $blockName
*