public static function relationship() { $relType = CRM_Utils_Request::retrieve('rel_type', 'Positive', CRM_Core_DAO::$_nullObject, TRUE); $relContactID = CRM_Utils_Request::retrieve('rel_contact', 'Positive', CRM_Core_DAO::$_nullObject, TRUE); $relationshipID = CRM_Utils_Request::retrieve('rel_id', 'Positive', CRM_Core_DAO::$_nullObject); // this used only to determine add or update mode $caseID = CRM_Utils_Request::retrieve('case_id', 'Positive', CRM_Core_DAO::$_nullObject, TRUE); // check if there are multiple clients for this case, if so then we need create // relationship and also activities for each contacts // get case client list $clientList = CRM_Case_BAO_Case::getCaseClients($caseID); $ret = array('is_error' => 0); foreach ($clientList as $sourceContactID) { $relationParams = array('relationship_type_id' => $relType . '_a_b', 'contact_check' => array($relContactID => 1), 'is_active' => 1, 'case_id' => $caseID, 'start_date' => date("Ymd")); $relationIds = array('contact' => $sourceContactID); // check if we are editing/updating existing relationship if ($relationshipID && $relationshipID != 'null') { // here we need to retrieve appropriate relationshipID based on client id and relationship type id $caseRelationships = new CRM_Contact_DAO_Relationship(); $caseRelationships->case_id = $caseID; $caseRelationships->relationship_type_id = $relType; $caseRelationships->contact_id_a = $sourceContactID; $caseRelationships->find(); while ($caseRelationships->fetch()) { $relationIds['relationship'] = $caseRelationships->id; $relationIds['contactTarget'] = $relContactID; } $caseRelationships->free(); } // create new or update existing relationship $return = CRM_Contact_BAO_Relationship::legacyCreateMultiple($relationParams, $relationIds); if (!empty($return[4][0])) { $relationshipID = $return[4][0]; //create an activity for case role assignment.CRM-4480 CRM_Case_BAO_Case::createCaseRoleActivity($caseID, $relationshipID, $relContactID); } else { $ret = array('is_error' => 1, 'error_message' => ts('The relationship type definition for the case role is not valid for the client and / or staff contact types. You can review and edit relationship types at <a href="%1">Administer >> Option Lists >> Relationship Types</a>.', array(1 => CRM_Utils_System::url('civicrm/admin/reltype', 'reset=1')))); } } CRM_Utils_JSON::output($ret); }
/** * Add on behalf of organization and it's location. * * This situation occurs when on behalf of is enabled for the contribution page and the person * signing up does so on behalf of an organization. * * @param array $behalfOrganization * array of organization info. * @param int $contactID * individual contact id. One. * who is doing the process of signup / contribution. * * @param array $values * form values array. * @param array $params * @param array $fields * Array of fields from the onbehalf profile relevant to the organization. */ public static function processOnBehalfOrganization(&$behalfOrganization, &$contactID, &$values, &$params, $fields = NULL) { $isNotCurrentEmployer = FALSE; $dupeIDs = array(); $orgID = NULL; if (!empty($behalfOrganization['organization_id'])) { $orgID = $behalfOrganization['organization_id']; unset($behalfOrganization['organization_id']); } else { // get the Employee relationship type id $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', 'Employee of', 'id', 'name_a_b'); // keep relationship params ready $relParams['relationship_type_id'] = $relTypeId . '_a_b'; $relParams['is_permission_a_b'] = 1; $relParams['is_active'] = 1; $isNotCurrentEmployer = TRUE; } // formalities for creating / editing organization. $behalfOrganization['contact_type'] = 'Organization'; if (!$orgID) { // check if matching organization contact exists $dedupeParams = CRM_Dedupe_Finder::formatParams($behalfOrganization, 'Organization'); $dedupeParams['check_permission'] = FALSE; $dupeIDs = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Organization', 'Unsupervised'); // CRM-6243 says to pick the first org even if more than one match if (count($dupeIDs) >= 1) { $behalfOrganization['contact_id'] = $orgID = $dupeIDs[0]; // don't allow name edit unset($behalfOrganization['organization_name']); } } else { // if found permissioned related organization, allow location edit $behalfOrganization['contact_id'] = $orgID; // don't allow name edit unset($behalfOrganization['organization_name']); } // handling for image url if (!empty($behalfOrganization['image_URL'])) { CRM_Contact_BAO_Contact::processImageParams($behalfOrganization); } // create organization, add location $orgID = CRM_Contact_BAO_Contact::createProfileContact($behalfOrganization, $fields, $orgID, NULL, NULL, 'Organization'); // create relationship if ($isNotCurrentEmployer) { $relParams['contact_check'][$orgID] = 1; $cid = array('contact' => $contactID); CRM_Contact_BAO_Relationship::legacyCreateMultiple($relParams, $cid); } // if multiple match - send a duplicate alert if ($dupeIDs && count($dupeIDs) > 1) { $values['onbehalf_dupe_alert'] = 1; // required for IPN $params['onbehalf_dupe_alert'] = 1; } // make sure organization-contact-id is considered for recording // contribution/membership etc.. if ($contactID != $orgID) { // take a note of contact-id, so we can send the // receipt to individual contact as well. // required for mailing/template display ..etc $values['related_contact'] = $contactID; //make this employee of relationship as current //employer / employee relationship, CRM-3532 if ($isNotCurrentEmployer && $orgID != CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'employer_id')) { $isNotCurrentEmployer = FALSE; } if (!$isNotCurrentEmployer && $orgID) { //build current employer params $currentEmpParams[$contactID] = $orgID; CRM_Contact_BAO_Contact_Utils::setCurrentEmployer($currentEmpParams); } // contribution / signup will be done using this // organization id. $contactID = $orgID; } }
public function testRelCreateWithinDiffTypeStudentSponsor() { //check for Student to Sponcer $relTypeParams = array('name_a_b' => 'StudentToSponsor', 'name_b_a' => 'SponsorToStudent', 'contact_type_a' => 'Individual', 'contact_sub_type_a' => $this->student, 'contact_type_b' => 'Organization', 'contact_sub_type_b' => $this->sponsor); $relTypeIds = array(); $relType = CRM_Contact_BAO_RelationshipType::add($relTypeParams, $relTypeIds); $params = array('relationship_type_id' => $relType->id . '_a_b', 'is_active' => 1, 'contact_check' => array($this->organization_sponsor => 1)); $ids = array('contact' => $this->indivi_student); list($valid, $invalid, $duplicate, $saved, $relationshipIds) = CRM_Contact_BAO_Relationship::legacyCreateMultiple($params, $ids); $this->assertEquals($valid, 1); $this->assertEquals(empty($relationshipIds), FALSE); $this->relationshipTypeDelete($relType->id); }
/** * Create Current employer relationship for a individual. * * @param int $contactID * Contact id of the individual. * @param $organization * (id or name). * @param int $previousEmployerID * @param bool $newContact * */ public static function createCurrentEmployerRelationship($contactID, $organization, $previousEmployerID = NULL, $newContact = FALSE) { //if organization name is passed. CRM-15368,CRM-15547 if ($organization && !is_numeric($organization)) { $organizationParams['organization_name'] = $organization; $dedupeParams = CRM_Dedupe_Finder::formatParams($organizationParams, 'Organization'); $dedupeParams['check_permission'] = FALSE; $dupeIDs = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Organization', 'Unsupervised'); if (is_array($dupeIDs) && !empty($dupeIDs)) { // we should create relationship only w/ first org CRM-4193 foreach ($dupeIDs as $orgId) { $organization = $orgId; break; } } else { //create new organization $newOrg = array('contact_type' => 'Organization', 'organization_name' => $organization); $org = CRM_Contact_BAO_Contact::create($newOrg); $organization = $org->id; } } if ($organization && is_numeric($organization)) { $cid = array('contact' => $contactID); // get the relationship type id of "Employee of" $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', 'Employee of', 'id', 'name_a_b'); if (!$relTypeId) { CRM_Core_Error::fatal(ts("You seem to have deleted the relationship type 'Employee of'")); } // create employee of relationship $relationshipParams = array('is_active' => TRUE, 'relationship_type_id' => $relTypeId . '_a_b', 'contact_check' => array($organization => TRUE)); list($valid, $invalid, $duplicate, $saved, $relationshipIds) = CRM_Contact_BAO_Relationship::legacyCreateMultiple($relationshipParams, $cid); // In case we change employer, clean previous employer related records. if (!$previousEmployerID && !$newContact) { $previousEmployerID = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'employer_id'); } if ($previousEmployerID && $previousEmployerID != $organization) { self::clearCurrentEmployer($contactID, $previousEmployerID); } // set current employer self::setCurrentEmployer(array($contactID => $organization)); $relationshipParams['relationship_ids'] = $relationshipIds; // Handle related memberships. CRM-3792 self::currentEmployerRelatedMembership($contactID, $organization, $relationshipParams, $duplicate, $previousEmployerID); } }
/** * Handle the values in import mode. * * @param int $onDuplicate * The code for what action to take on duplicates. * @param array $values * The array of values belonging to this line. * * @param bool $doGeocodeAddress * * @return bool * the result of this processing */ public function import($onDuplicate, &$values, $doGeocodeAddress = FALSE) { $config = CRM_Core_Config::singleton(); $this->_unparsedStreetAddressContacts = array(); if (!$doGeocodeAddress) { // CRM-5854, reset the geocode method to null to prevent geocoding $config->geocodeMethod = NULL; } // first make sure this is a valid line //$this->_updateWithId = false; $response = $this->summary($values); $statusFieldName = $this->_statusFieldName; if ($response != CRM_Import_Parser::VALID) { $importRecordParams = array($statusFieldName => 'INVALID', "{$statusFieldName}Msg" => "Invalid (Error Code: {$response})"); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); return $response; } $params =& $this->getActiveFieldParams(); $formatted = array('contact_type' => $this->_contactType); static $contactFields = NULL; if ($contactFields == NULL) { $contactFields = CRM_Contact_DAO_Contact::import(); } //check if external identifier exists in database if (!empty($params['external_identifier']) && (!empty($params['id']) || in_array($onDuplicate, array(CRM_Import_Parser::DUPLICATE_SKIP, CRM_Import_Parser::DUPLICATE_NOCHECK)))) { if ($internalCid = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params['external_identifier'], 'id', 'external_identifier')) { if ($internalCid != CRM_Utils_Array::value('id', $params)) { $errorMessage = ts('External ID already exists in Database.'); array_unshift($values, $errorMessage); $importRecordParams = array($statusFieldName => 'ERROR', "{$statusFieldName}Msg" => $errorMessage); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); return CRM_Import_Parser::DUPLICATE; } } } if (!empty($this->_contactSubType)) { $params['contact_sub_type'] = $this->_contactSubType; } if ($subType = CRM_Utils_Array::value('contact_sub_type', $params)) { if (CRM_Contact_BAO_ContactType::isExtendsContactType($subType, $this->_contactType, FALSE, 'label')) { $subTypes = CRM_Contact_BAO_ContactType::subTypePairs($this->_contactType, FALSE, NULL); $params['contact_sub_type'] = array_search($subType, $subTypes); } elseif (!CRM_Contact_BAO_ContactType::isExtendsContactType($subType, $this->_contactType)) { $message = "Mismatched or Invalid Contact Subtype."; array_unshift($values, $message); return CRM_Import_Parser::NO_MATCH; } } //get contact id to format common data in update/fill mode, //if external identifier is present, CRM-4423 if ($this->_updateWithId && empty($params['id']) && !empty($params['external_identifier'])) { if ($cid = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params['external_identifier'], 'id', 'external_identifier')) { $formatted['id'] = $cid; } } //format common data, CRM-4062 $this->formatCommonData($params, $formatted, $contactFields); $relationship = FALSE; $createNewContact = TRUE; // Support Match and Update Via Contact ID if ($this->_updateWithId) { $createNewContact = FALSE; if (empty($params['id']) && !empty($params['external_identifier'])) { if ($cid) { $params['id'] = $cid; } } $error = _civicrm_api3_deprecated_duplicate_formatted_contact($formatted); if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) { $matchedIDs = explode(',', $error['error_message']['params'][0]); if (count($matchedIDs) >= 1) { $updateflag = TRUE; foreach ($matchedIDs as $contactId) { if ($params['id'] == $contactId) { $contactType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params['id'], 'contact_type'); if ($formatted['contact_type'] == $contactType) { //validation of subtype for update mode //CRM-5125 $contactSubType = NULL; if (!empty($params['contact_sub_type'])) { $contactSubType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params['id'], 'contact_sub_type'); } if (!empty($contactSubType) && (!CRM_Contact_BAO_ContactType::isAllowEdit($params['id'], $contactSubType) && $contactSubType != CRM_Utils_Array::value('contact_sub_type', $formatted))) { $message = "Mismatched contact SubTypes :"; array_unshift($values, $message); $updateflag = FALSE; $this->_retCode = CRM_Import_Parser::NO_MATCH; } else { $updateflag = FALSE; $this->_retCode = CRM_Import_Parser::VALID; } } else { $message = "Mismatched contact Types :"; array_unshift($values, $message); $updateflag = FALSE; $this->_retCode = CRM_Import_Parser::NO_MATCH; } } } if ($updateflag) { $message = "Mismatched contact IDs OR Mismatched contact Types :"; array_unshift($values, $message); $this->_retCode = CRM_Import_Parser::NO_MATCH; } } } else { $contactType = NULL; if (!empty($params['id'])) { $contactType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params['id'], 'contact_type'); if ($contactType) { if ($formatted['contact_type'] == $contactType) { //validation of subtype for update mode //CRM-5125 $contactSubType = NULL; if (!empty($params['contact_sub_type'])) { $contactSubType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params['id'], 'contact_sub_type'); } if (!empty($contactSubType) && (!CRM_Contact_BAO_ContactType::isAllowEdit($params['id'], $contactSubType) && $contactSubType != CRM_Utils_Array::value('contact_sub_type', $formatted))) { $message = "Mismatched contact SubTypes :"; array_unshift($values, $message); $this->_retCode = CRM_Import_Parser::NO_MATCH; } else { $newContact = $this->createContact($formatted, $contactFields, $onDuplicate, $params['id'], FALSE, $this->_dedupeRuleGroupID); $this->_retCode = CRM_Import_Parser::VALID; } } else { $message = "Mismatched contact Types :"; array_unshift($values, $message); $this->_retCode = CRM_Import_Parser::NO_MATCH; } } else { // we should avoid multiple errors for single record // since we have already retCode and we trying to force again. if ($this->_retCode != CRM_Import_Parser::NO_MATCH) { $message = "No contact found for this contact ID:" . $params['id']; array_unshift($values, $message); $this->_retCode = CRM_Import_Parser::NO_MATCH; } } } else { //CRM-4148 //now we want to create new contact on update/fill also. $createNewContact = TRUE; } } if (isset($newContact) && is_a($newContact, 'CRM_Contact_BAO_Contact')) { $relationship = TRUE; } elseif (is_a($error, 'CRM_Core_Error')) { $newContact = $error; $relationship = TRUE; } } //fixed CRM-4148 //now we create new contact in update/fill mode also. $contactID = NULL; if ($createNewContact || $this->_retCode != CRM_Import_Parser::NO_MATCH && $this->_updateWithId) { //CRM-4430, don't carry if not submitted. foreach (array('prefix_id', 'suffix_id', 'gender_id') as $name) { if (!empty($formatted[$name])) { $options = CRM_Contact_BAO_Contact::buildOptions($name, 'get'); if (!isset($options[$formatted[$name]])) { $formatted[$name] = CRM_Utils_Array::key((string) $formatted[$name], $options); } } } if ($this->_updateWithId && !empty($params['id'])) { $contactID = $params['id']; } $newContact = $this->createContact($formatted, $contactFields, $onDuplicate, $contactID, TRUE, $this->_dedupeRuleGroupID); } if (isset($newContact) && is_object($newContact) && $newContact instanceof CRM_Contact_BAO_Contact) { $relationship = TRUE; $newContact = clone $newContact; $contactID = $newContact->id; $this->_newContacts[] = $contactID; //get return code if we create new contact in update mode, CRM-4148 if ($this->_updateWithId) { $this->_retCode = CRM_Import_Parser::VALID; } } elseif (isset($newContact) && CRM_Core_Error::isAPIError($newContact, CRM_Core_ERROR::DUPLICATE_CONTACT)) { // if duplicate, no need of further processing if ($onDuplicate == CRM_Import_Parser::DUPLICATE_SKIP) { $errorMessage = "Skipping duplicate record"; array_unshift($values, $errorMessage); $importRecordParams = array($statusFieldName => 'DUPLICATE', "{$statusFieldName}Msg" => $errorMessage); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); return CRM_Import_Parser::DUPLICATE; } $relationship = TRUE; # see CRM-10433 - might return comma separate list of all dupes $dupeContactIDs = explode(',', $newContact['error_message']['params'][0]); $dupeCount = count($dupeContactIDs); $contactID = array_pop($dupeContactIDs); // check to see if we had more than one duplicate contact id. // if we have more than one, the record will be rejected below if ($dupeCount == 1) { // there was only one dupe, we will continue normally... if (!in_array($contactID, $this->_newContacts)) { $this->_newContacts[] = $contactID; } } } if ($contactID) { // call import hook $currentImportID = end($values); $hookParams = array('contactID' => $contactID, 'importID' => $currentImportID, 'importTempTable' => $this->_tableName, 'fieldHeaders' => $this->_mapperKeys, 'fields' => $this->_activeFields); CRM_Utils_Hook::import('Contact', 'process', $this, $hookParams); } if ($relationship) { $primaryContactId = NULL; if (CRM_Core_Error::isAPIError($newContact, CRM_Core_ERROR::DUPLICATE_CONTACT)) { if (CRM_Utils_Rule::integer($newContact['error_message']['params'][0])) { $primaryContactId = $newContact['error_message']['params'][0]; } } else { $primaryContactId = $newContact->id; } if ((CRM_Core_Error::isAPIError($newContact, CRM_Core_ERROR::DUPLICATE_CONTACT) || is_a($newContact, 'CRM_Contact_BAO_Contact')) && $primaryContactId) { //relationship contact insert foreach ($params as $key => $field) { list($id, $first, $second) = CRM_Utils_System::explode('_', $key, 3); if (!($first == 'a' && $second == 'b') && !($first == 'b' && $second == 'a')) { continue; } $relationType = new CRM_Contact_DAO_RelationshipType(); $relationType->id = $id; $relationType->find(TRUE); $direction = "contact_sub_type_{$second}"; $formatting = array('contact_type' => $params[$key]['contact_type']); //set subtype for related contact CRM-5125 if (isset($relationType->{$direction})) { //validation of related contact subtype for update mode if ($relCsType = CRM_Utils_Array::value('contact_sub_type', $params[$key]) && $relCsType != $relationType->{$direction}) { $errorMessage = ts("Mismatched or Invalid contact subtype found for this related contact."); array_unshift($values, $errorMessage); return CRM_Import_Parser::NO_MATCH; } else { $formatting['contact_sub_type'] = $relationType->{$direction}; } } $relationType->free(); $contactFields = NULL; $contactFields = CRM_Contact_DAO_Contact::import(); //Relation on the basis of External Identifier. if (empty($params[$key]['id']) && !empty($params[$key]['external_identifier'])) { $params[$key]['id'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params[$key]['external_identifier'], 'id', 'external_identifier'); } // check for valid related contact id in update/fill mode, CRM-4424 if (in_array($onDuplicate, array(CRM_Import_Parser::DUPLICATE_UPDATE, CRM_Import_Parser::DUPLICATE_FILL)) && !empty($params[$key]['id'])) { $relatedContactType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params[$key]['id'], 'contact_type'); if (!$relatedContactType) { $errorMessage = ts("No contact found for this related contact ID: %1", array(1 => $params[$key]['id'])); array_unshift($values, $errorMessage); return CRM_Import_Parser::NO_MATCH; } else { //validation of related contact subtype for update mode //CRM-5125 $relatedCsType = NULL; if (!empty($formatting['contact_sub_type'])) { $relatedCsType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params[$key]['id'], 'contact_sub_type'); } if (!empty($relatedCsType) && (!CRM_Contact_BAO_ContactType::isAllowEdit($params[$key]['id'], $relatedCsType) && $relatedCsType != CRM_Utils_Array::value('contact_sub_type', $formatting))) { $errorMessage = ts("Mismatched or Invalid contact subtype found for this related contact.") . ' ' . ts("ID: %1", array(1 => $params[$key]['id'])); array_unshift($values, $errorMessage); return CRM_Import_Parser::NO_MATCH; } else { // get related contact id to format data in update/fill mode, //if external identifier is present, CRM-4423 $formatting['id'] = $params[$key]['id']; } } } //format common data, CRM-4062 $this->formatCommonData($field, $formatting, $contactFields); //do we have enough fields to create related contact. $allowToCreate = $this->checkRelatedContactFields($key, $formatting); if (!$allowToCreate) { $errorMessage = ts('Related contact required fields are missing.'); array_unshift($values, $errorMessage); return CRM_Import_Parser::NO_MATCH; } //fixed for CRM-4148 if (!empty($params[$key]['id'])) { $contact = array('contact_id' => $params[$key]['id']); $defaults = array(); $relatedNewContact = CRM_Contact_BAO_Contact::retrieve($contact, $defaults); } else { $relatedNewContact = $this->createContact($formatting, $contactFields, $onDuplicate, NULL, FALSE); } if (is_object($relatedNewContact) || $relatedNewContact instanceof CRM_Contact_BAO_Contact) { $relatedNewContact = clone $relatedNewContact; } $matchedIDs = array(); // To update/fill contact, get the matching contact Ids if duplicate contact found // otherwise get contact Id from object of related contact if (is_array($relatedNewContact) && civicrm_error($relatedNewContact)) { if (CRM_Core_Error::isAPIError($relatedNewContact, CRM_Core_ERROR::DUPLICATE_CONTACT)) { $matchedIDs = explode(',', $relatedNewContact['error_message']['params'][0]); } else { $errorMessage = $relatedNewContact['error_message']; array_unshift($values, $errorMessage); $importRecordParams = array($statusFieldName => 'ERROR', "{$statusFieldName}Msg" => $errorMessage); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); return CRM_Import_Parser::ERROR; } } else { $matchedIDs[] = $relatedNewContact->id; } // update/fill related contact after getting matching Contact Ids, CRM-4424 if (in_array($onDuplicate, array(CRM_Import_Parser::DUPLICATE_UPDATE, CRM_Import_Parser::DUPLICATE_FILL))) { //validation of related contact subtype for update mode //CRM-5125 $relatedCsType = NULL; if (!empty($formatting['contact_sub_type'])) { $relatedCsType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $matchedIDs[0], 'contact_sub_type'); } if (!empty($relatedCsType) && (!CRM_Contact_BAO_ContactType::isAllowEdit($matchedIDs[0], $relatedCsType) && $relatedCsType != CRM_Utils_Array::value('contact_sub_type', $formatting))) { $errorMessage = ts("Mismatched or Invalid contact subtype found for this related contact."); array_unshift($values, $errorMessage); return CRM_Import_Parser::NO_MATCH; } else { $updatedContact = $this->createContact($formatting, $contactFields, $onDuplicate, $matchedIDs[0]); } } static $relativeContact = array(); if (CRM_Core_Error::isAPIError($relatedNewContact, CRM_Core_ERROR::DUPLICATE_CONTACT)) { if (count($matchedIDs) >= 1) { $relContactId = $matchedIDs[0]; //add relative contact to count during update & fill mode. //logic to make count distinct by contact id. if ($this->_newRelatedContacts || !empty($relativeContact)) { $reContact = array_keys($relativeContact, $relContactId); if (empty($reContact)) { $this->_newRelatedContacts[] = $relativeContact[] = $relContactId; } } else { $this->_newRelatedContacts[] = $relativeContact[] = $relContactId; } } } else { $relContactId = $relatedNewContact->id; $this->_newRelatedContacts[] = $relativeContact[] = $relContactId; } if (CRM_Core_Error::isAPIError($relatedNewContact, CRM_Core_ERROR::DUPLICATE_CONTACT) || $relatedNewContact instanceof CRM_Contact_BAO_Contact) { //fix for CRM-1993.Checks for duplicate related contacts if (count($matchedIDs) >= 1) { //if more than one duplicate contact //found, create relationship with first contact // now create the relationship record $relationParams = array(); $relationParams = array('relationship_type_id' => $key, 'contact_check' => array($relContactId => 1), 'is_active' => 1, 'skipRecentView' => TRUE); // we only handle related contact success, we ignore failures for now // at some point wold be nice to have related counts as separate $relationIds = array('contact' => $primaryContactId); list($valid, $invalid, $duplicate, $saved, $relationshipIds) = CRM_Contact_BAO_Relationship::legacyCreateMultiple($relationParams, $relationIds); if ($valid || $duplicate) { $relationIds['contactTarget'] = $relContactId; $action = $duplicate ? CRM_Core_Action::UPDATE : CRM_Core_Action::ADD; CRM_Contact_BAO_Relationship::relatedMemberships($primaryContactId, $relationParams, $relationIds, $action); } //handle current employer, CRM-3532 if ($valid) { $allRelationships = CRM_Core_PseudoConstant::relationshipType('name'); $relationshipTypeId = str_replace(array('_a_b', '_b_a'), array('', ''), $key); $relationshipType = str_replace($relationshipTypeId . '_', '', $key); $orgId = $individualId = NULL; if ($allRelationships[$relationshipTypeId]["name_{$relationshipType}"] == 'Employee of') { $orgId = $relContactId; $individualId = $primaryContactId; } elseif ($allRelationships[$relationshipTypeId]["name_{$relationshipType}"] == 'Employer of') { $orgId = $primaryContactId; $individualId = $relContactId; } if ($orgId && $individualId) { $currentEmpParams[$individualId] = $orgId; CRM_Contact_BAO_Contact_Utils::setCurrentEmployer($currentEmpParams); } } } } } } } if ($this->_updateWithId) { //return warning if street address is unparsed, CRM-5886 return $this->processMessage($values, $statusFieldName, $this->_retCode); } //dupe checking if (is_array($newContact) && civicrm_error($newContact)) { $code = NULL; if (($code = CRM_Utils_Array::value('code', $newContact['error_message'])) && $code == CRM_Core_Error::DUPLICATE_CONTACT) { $urls = array(); // need to fix at some stage and decide if the error will return an // array or string, crude hack for now if (is_array($newContact['error_message']['params'][0])) { $cids = $newContact['error_message']['params'][0]; } else { $cids = explode(',', $newContact['error_message']['params'][0]); } foreach ($cids as $cid) { $urls[] = CRM_Utils_System::url('civicrm/contact/view', 'reset=1&cid=' . $cid, TRUE); } $url_string = implode("\n", $urls); // If we duplicate more than one record, skip no matter what if (count($cids) > 1) { $errorMessage = ts('Record duplicates multiple contacts'); $importRecordParams = array($statusFieldName => 'ERROR', "{$statusFieldName}Msg" => $errorMessage); //combine error msg to avoid mismatch between error file columns. $errorMessage .= "\n" . $url_string; array_unshift($values, $errorMessage); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); return CRM_Import_Parser::ERROR; } // Params only had one id, so shift it out $contactId = array_shift($cids); $cid = NULL; $vals = array('contact_id' => $contactId); if ($onDuplicate == CRM_Import_Parser::DUPLICATE_REPLACE) { civicrm_api('contact', 'delete', $vals); $cid = CRM_Contact_BAO_Contact::createProfileContact($formatted, $contactFields, $contactId, NULL, NULL, $formatted['contact_type']); } elseif ($onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE) { $newContact = $this->createContact($formatted, $contactFields, $onDuplicate, $contactId); } elseif ($onDuplicate == CRM_Import_Parser::DUPLICATE_FILL) { $newContact = $this->createContact($formatted, $contactFields, $onDuplicate, $contactId); } // else skip does nothing and just returns an error code. if ($cid) { $contact = array('contact_id' => $cid); $defaults = array(); $newContact = CRM_Contact_BAO_Contact::retrieve($contact, $defaults); } if (civicrm_error($newContact)) { if (empty($newContact['error_message']['params'])) { // different kind of error other than DUPLICATE $errorMessage = $newContact['error_message']; array_unshift($values, $errorMessage); $importRecordParams = array($statusFieldName => 'ERROR', "{$statusFieldName}Msg" => $errorMessage); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); return CRM_Import_Parser::ERROR; } $contactID = $newContact['error_message']['params'][0]; if (!in_array($contactID, $this->_newContacts)) { $this->_newContacts[] = $contactID; } } //CRM-262 No Duplicate Checking if ($onDuplicate == CRM_Import_Parser::DUPLICATE_SKIP) { array_unshift($values, $url_string); $importRecordParams = array($statusFieldName => 'DUPLICATE', "{$statusFieldName}Msg" => "Skipping duplicate record"); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); return CRM_Import_Parser::DUPLICATE; } $importRecordParams = array($statusFieldName => 'IMPORTED'); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); //return warning if street address is not parsed, CRM-5886 return $this->processMessage($values, $statusFieldName, CRM_Import_Parser::VALID); } else { // Not a dupe, so we had an error $errorMessage = $newContact['error_message']; array_unshift($values, $errorMessage); $importRecordParams = array($statusFieldName => 'ERROR', "{$statusFieldName}Msg" => $errorMessage); $this->updateImportRecord($values[count($values) - 1], $importRecordParams); return CRM_Import_Parser::ERROR; } } // sleep(3); return $this->processMessage($values, $statusFieldName, CRM_Import_Parser::VALID); }