/** * Delete Relationship Types. * * @param int $relationshipTypeId * * @throws CRM_Core_Exception * @return mixed */ public static function del($relationshipTypeId) { // make sure relationshipTypeId is an integer // @todo review this as most delete functions rely on the api & form layer for this // or do a find first & throw error if no find if (!CRM_Utils_Rule::positiveInteger($relationshipTypeId)) { throw new CRM_Core_Exception(ts('Invalid relationship type')); } //check dependencies // delete all relationships $relationship = new CRM_Contact_DAO_Relationship(); $relationship->relationship_type_id = $relationshipTypeId; $relationship->delete(); // remove this relationship type from membership types $mems = civicrm_api3('MembershipType', 'get', array('relationship_type_id' => array('LIKE' => "%{$relationshipTypeId}%"), 'return' => array('id', 'relationship_type_id', 'relationship_direction'))); foreach ($mems['values'] as $membershipTypeId => $membershipType) { $pos = array_search($relationshipTypeId, $membershipType['relationship_type_id']); // Api call may have returned false positives but currently the relationship_type_id uses // nonstandard serialization which makes anything more accurate impossible. if ($pos !== FALSE) { unset($membershipType['relationship_type_id'][$pos], $membershipType['relationship_direction'][$pos]); civicrm_api3('MembershipType', 'create', $membershipType); } } //fixed for CRM-3323 $mappingField = new CRM_Core_DAO_MappingField(); $mappingField->relationship_type_id = $relationshipTypeId; $mappingField->find(); while ($mappingField->fetch()) { $mappingField->delete(); } $relationshipType = new CRM_Contact_DAO_RelationshipType(); $relationshipType->id = $relationshipTypeId; return $relationshipType->delete(); }
public function runImport(&$form, $timeout = 55) { $mapper = $this->_mapper; $mapperFields = array(); $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'); $websiteTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Website', 'website_type_id'); $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); //initialize mapper perperty value. $mapperPeroperties = array('mapperRelated' => 'mapperRelatedVal', 'mapperLocTypes' => 'mapperLocTypesVal', 'mapperPhoneTypes' => 'mapperPhoneTypesVal', 'mapperImProviders' => 'mapperImProvidersVal', 'mapperWebsiteTypes' => 'mapperWebsiteTypesVal', 'mapperRelatedContactType' => 'mapperRelatedContactTypeVal', 'mapperRelatedContactDetails' => 'mapperRelatedContactDetailsVal', 'mapperRelatedContactLocType' => 'mapperRelatedContactLocTypeVal', 'mapperRelatedContactPhoneType' => 'mapperRelatedContactPhoneTypeVal', 'mapperRelatedContactImProvider' => 'mapperRelatedContactImProviderVal', 'mapperRelatedContactWebsiteType' => 'mapperRelatedContactWebsiteTypeVal'); foreach ($mapper as $key => $value) { //set respective mapper value to null. foreach (array_values($mapperPeroperties) as $perpertyVal) { ${$perpertyVal} = NULL; } $fldName = CRM_Utils_Array::value(0, $mapper[$key]); $header = array($this->_mapFields[$fldName]); $selOne = CRM_Utils_Array::value(1, $mapper[$key]); $selTwo = CRM_Utils_Array::value(2, $mapper[$key]); $selThree = CRM_Utils_Array::value(3, $mapper[$key]); $this->_mapperKeys[$key] = $fldName; //need to differentiate non location elements. if ($selOne && is_numeric($selOne)) { if ($fldName == 'url') { $header[] = $websiteTypes[$selOne]; $mapperWebsiteTypesVal = $selOne; } else { $header[] = $locationTypes[$selOne]; $mapperLocTypesVal = $selOne; if ($selTwo && is_numeric($selTwo)) { if ($fldName == 'phone') { $header[] = $phoneTypes[$selTwo]; $mapperPhoneTypesVal = $selTwo; } elseif ($fldName == 'im') { $header[] = $imProviders[$selTwo]; $mapperImProvidersVal = $selTwo; } } } } $fldNameParts = explode('_', $fldName, 3); $id = $fldNameParts[0]; $first = isset($fldNameParts[1]) ? $fldNameParts[1] : NULL; $second = isset($fldNameParts[2]) ? $fldNameParts[2] : NULL; if ($first == 'a' && $second == 'b' || $first == 'b' && $second == 'a') { $header[] = ucwords(str_replace("_", " ", $selOne)); $relationType = new CRM_Contact_DAO_RelationshipType(); $relationType->id = $id; $relationType->find(TRUE); $mapperRelatedContactTypeVal = $relationType->{"contact_type_{$second}"}; $mapperRelatedVal = $fldName; if ($selOne) { $mapperRelatedContactDetailsVal = $selOne; if ($selTwo) { if ($selOne == 'url') { $header[] = $websiteTypes[$selTwo]; $mapperRelatedContactWebsiteTypeVal = $selTwo; } else { $header[] = $locationTypes[$selTwo]; $mapperRelatedContactLocTypeVal = $selTwo; if ($selThree) { if ($selOne == 'phone') { $header[] = $phoneTypes[$selThree]; $mapperRelatedContactPhoneTypeVal = $selThree; } elseif ($selOne == 'im') { $header[] = $imProviders[$selThree]; $mapperRelatedContactImProviderVal = $selThree; } } } } } } $mapperFields[] = implode(' - ', $header); //set the respective mapper param array values. foreach ($mapperPeroperties as $mapperProKey => $mapperProVal) { $this->{"_{$mapperProKey}"}[$key] = ${$mapperProVal}; } } $this->_parser = new CRM_Contact_Import_Parser_Contact($this->_mapperKeys, $this->_mapperLocTypes, $this->_mapperPhoneTypes, $this->_mapperImProviders, $this->_mapperRelated, $this->_mapperRelatedContactType, $this->_mapperRelatedContactDetails, $this->_mapperRelatedContactLocType, $this->_mapperRelatedContactPhoneType, $this->_mapperRelatedContactImProvider, $this->_mapperWebsiteTypes, $this->_mapperRelatedContactWebsiteType); $this->_parser->run($this->_tableName, $mapperFields, CRM_Import_Parser::MODE_IMPORT, $this->_contactType, $this->_primaryKeyName, $this->_statusFieldName, $this->_onDuplicate, $this->_statusID, $this->_totalRowCount, $this->_doGeocodeAddress, CRM_Contact_Import_Parser::DEFAULT_TIMEOUT, $this->_contactSubType, $this->_dedupe); $contactIds = $this->_parser->getImportedContacts(); //get the related contactIds. CRM-2926 $relatedContactIds = $this->_parser->getRelatedImportedContacts(); if ($relatedContactIds) { $contactIds = array_merge($contactIds, $relatedContactIds); if ($form) { $form->set('relatedCount', count($relatedContactIds)); } } if ($this->_newGroupName || count($this->_groups)) { $groupAdditions = $this->_addImportedContactsToNewGroup($contactIds, $this->_newGroupName, $this->_newGroupDesc); if ($form) { $form->set('groupAdditions', $groupAdditions); } } if ($this->_newTagName || count($this->_tag)) { $tagAdditions = $this->_tagImportedContactsWithNewTag($contactIds, $this->_newTagName, $this->_newTagDesc); if ($form) { $form->set('tagAdditions', $tagAdditions); } } }
/** * adds $value['foo_display'] for each $value['foo'] enum from civicrm_relationship_type * * @param array $values (reference) the array up for enhancing * @return void */ static function addDisplayEnums(&$values) { $enumFields =& CRM_Contact_DAO_RelationshipType::getEnums(); foreach ($enumFields as $enum) { if (isset($values[$enum])) { $values[$enum . '_display'] = CRM_Contact_DAO_RelationshipType::tsEnum($enum, $values[$enum]); } } }
/** * Function to check if the relationship type selected between two contacts is correct * * @param int $contact_a 1st contact id * @param int $contact_b 2nd contact id * @param int $relationshipTypeId relationship type id * * @return boolean true if it is valid relationship else false * @access public * @static */ static function checkRelationshipType($contact_a, $contact_b, $relationshipTypeId) { $relationshipType = new CRM_Contact_DAO_RelationshipType(); $relationshipType->id = $relationshipTypeId; $relationshipType->selectAdd(); $relationshipType->selectAdd('contact_type_a, contact_type_b, contact_sub_type_a, contact_sub_type_b'); if ($relationshipType->find(true)) { require_once 'CRM/Contact/BAO/Contact.php'; $contact_type_a = CRM_Contact_BAO_Contact::getContactType($contact_a); $contact_type_b = CRM_Contact_BAO_Contact::getContactType($contact_b); $contact_sub_type_a = CRM_Contact_BAO_Contact::getContactSubType($contact_a); $contact_sub_type_b = CRM_Contact_BAO_Contact::getContactSubType($contact_b); if ((!$relationshipType->contact_type_a || $relationshipType->contact_type_a == $contact_type_a) && (!$relationshipType->contact_type_b || $relationshipType->contact_type_b == $contact_type_b) && (!$relationshipType->contact_sub_type_a || $relationshipType->contact_sub_type_a == $contact_sub_type_a) && (!$relationshipType->contact_sub_type_b || $relationshipType->contact_sub_type_b == $contact_sub_type_b)) { return true; } else { return false; } } return false; }
/** * This function is to get the result of the search for contact in relationship form * * @param array $params This contains elements for search criteria * * @access public * @return None * */ function search(&$params) { //max records that will be listed $searchValues = array(); if (CRM_Utils_Array::value('rel_contact', $params)) { if (is_numeric($params['rel_contact_id'])) { $searchValues[] = array('contact_id', '=', $params['rel_contact_id'], 0, 1); } else { $searchValues[] = array('sort_name', 'LIKE', $params['rel_contact'], 0, 1); } } $contactTypeAdded = false; $excludedContactIds = array($this->_contactId); if ($params['relationship_type_id']) { $relationshipType = new CRM_Contact_DAO_RelationshipType(); list($rid, $direction) = explode('_', $params['relationship_type_id'], 2); $relationshipType->id = $rid; if ($relationshipType->find(true)) { if ($direction == 'a_b') { $type = $relationshipType->contact_type_b; $subType = $relationshipType->contact_sub_type_b; } else { $type = $relationshipType->contact_type_a; $subType = $relationshipType->contact_sub_type_a; } $this->set('contact_type', $type); $this->set('contact_sub_type', $subType); if ($type == 'Individual' || $type == 'Organization' || $type == 'Household') { $searchValues[] = array('contact_type', '=', $type, 0, 0); $contactTypeAdded = true; } if ($subType) { $searchValues[] = array('contact_sub_type', '=', $subType, 0, 0); } } } if (!$contactTypeAdded && CRM_Utils_Array::value('contact_type', $params)) { $searchValues[] = array('contact_type', '=', $params['contact_type'], 0, 0); } // get the count of contact $contactBAO = new CRM_Contact_BAO_Contact(); $query = new CRM_Contact_BAO_Query($searchValues); $searchCount = $query->searchQuery(0, 0, null, true); $this->set('searchCount', $searchCount); if ($searchCount <= self::MAX_RELATIONSHIPS) { // get the result of the search $result = $query->searchQuery(0, 50, null); $config = CRM_Core_Config::singleton(); $searchRows = array(); //variable is set if only one record is foun and that record already has relationship with the contact $duplicateRelationship = 0; while ($result->fetch()) { $contactID = $result->contact_id; if (in_array($contactID, $excludedContactIds)) { $duplicateRelationship++; continue; } $duplicateRelationship = 0; $searchRows[$contactID]['id'] = $contactID; $searchRows[$contactID]['name'] = $result->sort_name; $searchRows[$contactID]['city'] = $result->city; $searchRows[$contactID]['state'] = $result->state_province; $searchRows[$contactID]['email'] = $result->email; $searchRows[$contactID]['phone'] = $result->phone; $contact_type = '<img src="' . $config->resourceBase . 'i/contact_'; require_once 'CRM/Contact/BAO/Contact/Utils.php'; $searchRows[$contactID]['type'] = CRM_Contact_BAO_Contact_Utils::getImage($result->contact_sub_type ? $result->contact_sub_type : $result->contact_type); } $this->set('searchRows', $searchRows); $this->set('duplicateRelationship', $duplicateRelationship); } else { // resetting the session variables if many records are found $this->set('searchRows', null); $this->set('duplicateRelationship', null); } }
/** * Check if the relationship type selected between two contacts is correct. * * @param int $contact_a * 1st contact id. * @param int $contact_b * 2nd contact id. * @param int $relationshipTypeId * Relationship type id. * * @return bool * true if it is valid relationship else false */ public static function checkRelationshipType($contact_a, $contact_b, $relationshipTypeId) { $relationshipType = new CRM_Contact_DAO_RelationshipType(); $relationshipType->id = $relationshipTypeId; $relationshipType->selectAdd(); $relationshipType->selectAdd('contact_type_a, contact_type_b, contact_sub_type_a, contact_sub_type_b'); if ($relationshipType->find(TRUE)) { $contact_type_a = CRM_Contact_BAO_Contact::getContactType($contact_a); $contact_type_b = CRM_Contact_BAO_Contact::getContactType($contact_b); $contact_sub_type_a = CRM_Contact_BAO_Contact::getContactSubType($contact_a); $contact_sub_type_b = CRM_Contact_BAO_Contact::getContactSubType($contact_b); if ((!$relationshipType->contact_type_a || $relationshipType->contact_type_a == $contact_type_a) && (!$relationshipType->contact_type_b || $relationshipType->contact_type_b == $contact_type_b) && (!$relationshipType->contact_sub_type_a || in_array($relationshipType->contact_sub_type_a, $contact_sub_type_a)) && (!$relationshipType->contact_sub_type_b || in_array($relationshipType->contact_sub_type_b, $contact_sub_type_b))) { return TRUE; } else { return FALSE; } } return FALSE; }
/** * 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 * * @return boolean the result of this processing * @access public */ function import($onDuplicate, &$values) { // first make sure this is a valid line //$this->_updateWithId = false; $response = $this->summary($values); if ($response != CRM_IMPORT_PARSER_VALID) { return $response; } $params =& $this->getActiveFieldParams(); $formatted = array('contact_type' => $this->_contactType); //for date-Formats $session =& CRM_Core_Session::singleton(); $dateType = $session->get("dateType"); $customFields = CRM_Core_BAO_CustomField::getFields($params['contact_type']); foreach ($params as $key => $val) { if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) { if ($customFields[$customFieldID][2] == 'Date') { CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key); } } if ($key == 'birth_date') { if ($val) { CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key); } } } //date-Format part ends if ($GLOBALS['_CRM_IMPORT_PARSER_CONTACT']['indieFields'] == null) { require_once str_replace('_', DIRECTORY_SEPARATOR, "CRM_Contact_DAO_" . $this->_contactType) . ".php"; eval('$tempIndieFields =& CRM_Contact_DAO_' . $this->_contactType . '::import();'); //modified for PHP4 issue $GLOBALS['_CRM_IMPORT_PARSER_CONTACT']['indieFields'] = $tempIndieFields; } foreach ($params as $key => $field) { if ($field == null || $field === '') { continue; } if (is_array($field)) { foreach ($field as $value) { $break = false; if (is_array($value)) { foreach ($value as $name => $testForEmpty) { if ($name !== 'phone_type' && ($testForEmpty === '' || $testForEmpty == null)) { $break = true; break; } } } else { $break = true; } if (!$break) { _crm_add_formatted_param($value, $formatted); } } continue; } $value = array($key => $field); if (array_key_exists($key, $GLOBALS['_CRM_IMPORT_PARSER_CONTACT']['indieFields'])) { $value['contact_type'] = $this->_contactType; } _crm_add_formatted_param($value, $formatted); } /*if (in_array('id',$this->_mapperKeys)) { $this->_updateWithId = true; }*/ $relationship = false; // Support Match and Update Via Contact ID if ($this->_updateWithId) { $error = _crm_duplicate_formatted_contact($formatted); if (CRM_Import_Parser_Contact::isDuplicate($error)) { $matchedIDs = explode(',', $error->_errors[0]['params'][0]); if (count($matchedIDs) >= 1) { $updateflag = true; foreach ($matchedIDs as $contactId) { if ($params['id'] == $contactId) { $paramsValues = array('contact_id' => $contactId); $contactExits = crm_get_contact($paramsValues); if ($formatted['contact_type'] == $contactExits->contact_type) { $newContact = crm_update_contact_formatted($contactId, $formatted, true); $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 { $paramsValues = array('contact_id' => $params['id']); $contact = crm_get_contact($paramsValues); if (is_a($contact, CRM_Contact_BAO_Contact)) { if ($formatted['contact_type'] == $contact->contact_type) { $newContact = crm_update_contact_formatted($contact->id, $formatted, true); $this->_retCode = CRM_IMPORT_PARSER_VALID; } else { $message = "Mismatched contact Types :"; array_unshift($values, $message); $this->_retCode = CRM_IMPORT_PARSER_NO_MATCH; } } else { $message = "No contact found for this contact ID:" . $params['id']; array_unshift($values, $message); $this->_retCode = CRM_IMPORT_PARSER_NO_MATCH; } } if (is_a($newContact, CRM_Contact_BAO_Contact)) { $relationship = true; } else { if (is_a($error, CRM_Core_Error)) { $newContact = $error; $relationship = true; } } if ($newContact && !is_a($newContact, CRM_Core_Error)) { $this->_newContacts[] = $newContact->id; } } else { $newContact = crm_create_contact_formatted($formatted, $onDuplicate); $relationship = true; } if ($relationship) { if (CRM_Import_Parser_Contact::isDuplicate($newContact)) { foreach ($newContact->_errors[0]['params'] as $cid) { $primaryContactId = $cid; } } else { $primaryContactId = $newContact->id; } if (CRM_Import_Parser_Contact::isDuplicate($newContact) || is_a($newContact, CRM_Contact_BAO_Contact)) { //relationship contact insert foreach ($params as $key => $field) { list($id, $first, $second) = explode('_', $key); if (!($first == 'a' && $second == 'b') && !($first == 'b' && $second == 'a')) { continue; } $relationType = new CRM_Contact_DAO_RelationshipType(); $relationType->id = $id; $relationType->find(true); $name_a_b = $relationType->name_a_b; if ($params[$key]['contact_type']) { $formatting = array('contact_type' => $params[$key]['contact_type']); } else { $fld = array_keys($params[$key]); foreach (CRM_Core_SelectValues::contactType() as $cType => $val) { if ($cType) { $contactFields =& CRM_Contact_BAO_Contact::importableFields($cType); if (array_key_exists($fld[0], $contactFields)) { $formatting['contact_type'] = $cType; $params[$key]['contact_type'] = $cType; $field['contact_type'] = $cType; break; } } } } $contactFields = null; if ($contactFields == null) { require_once str_replace('_', DIRECTORY_SEPARATOR, "CRM_Contact_DAO_" . $params[$key]['contact_type']) . ".php"; eval('$contactFields =& CRM_Contact_DAO_' . $params[$key]['contact_type'] . '::import();'); } foreach ($field as $k => $v) { if ($v == null || $v === '') { continue; } if (is_array($v)) { foreach ($v as $value) { $break = false; foreach ($value as $testForEmpty) { if ($testForEmpty === '' || $testForEmpty == null) { $break = true; break; } } if (!$break) { _crm_add_formatted_param($value, $formatting); } } continue; } $value = array($k => $v); if (array_key_exists($k, $contactFields)) { $value['contact_type'] = $params[$key]['contact_type']; } _crm_add_formatted_param($value, $formatting); } $relatedNewContact = crm_create_contact_formatted($formatting, $onDuplicate); if (CRM_Import_Parser_Contact::isDuplicate($relatedNewContact)) { foreach ($relatedNewContact->_errors[0]['params'] as $cid) { $relContactId = $cid; } } else { $relContactId = $relatedNewContact->id; $this->_newRelatedContacts[] = $relContactId; } if (CRM_Import_Parser_Contact::isDuplicate($relatedNewContact) || is_a($relatedNewContact, CRM_Contact_BAO_Contact)) { //store the related contact id for groups //$this->_newRelatedContacts[] = $relContactId; // now create the relationship record $relationParams = array(); $relationParams = array('relationship_type_id' => $key, 'contact_check' => array($relContactId => 1)); $relationIds = array('contact' => $primaryContactId); CRM_Contact_BAO_Relationship::create($relationParams, $relationIds); //check if the two contacts are related and of type individual if ($params[$key]['contact_type'] == 'Individual' && $this->_contactType == 'Individual') { if ($name_a_b == 'Spouse of' || $name_a_b == 'Child of' || $name_a_b == 'Sibling of') { $householdName = "The " . $formatting['last_name'] . " household"; $householdFormatting = array('contact_type' => 'Household', 'household_name' => $householdName); $householdContact = crm_create_contact_formatted($householdFormatting, $onDuplicate); if (CRM_Import_Parser_Contact::isDuplicate($householdContact)) { foreach ($householdContact->_errors[0]['params'] as $cid) { $householdId = $cid; } } else { $householdId = $householdContact->id; $this->_newRelatedContacts[] = $householdId; } //Household contact is created //for two related individual contacts waiting confirmation whether //to add it in a group //$this->_newRelatedContacts[] = $householdId; $relationParams = array(); // adding household relationship $relType = '7_' . $second . '_' . $first; $relationParams = array('relationship_type_id' => $relType, 'contact_check' => array($relContactId => 1, $primaryContactId => 1)); $relationIds = array('contact' => $householdId); CRM_Contact_BAO_Relationship::create($relationParams, $relationIds); } } } } } } if ($this->_updateWithId) { return $this->_retCode; } //dupe checking if (is_a($newContact, CRM_Core_Error)) { $code = $newContact->_errors[0]['code']; if ($code == CRM_CORE_ERROR_DUPLICATE_CONTACT) { $urls = array(); foreach ($newContact->_errors[0]['params'] as $cid) { $urls[] = CRM_Utils_System::url('civicrm/contact/view', 'reset=1&cid=' . $cid, true); } $url_string = implode("\n", $urls); array_unshift($values, $url_string); /* If we duplicate more than one record, skip no matter what */ if (count($newContact->_errors[0]['params']) > 1) { array_unshift($values, ts('Record duplicates multiple contacts')); return CRM_IMPORT_PARSER_ERROR; } /* Params only had one id, so shift it out */ $contactId = array_shift($newContact->_errors[0]['params']); if ($onDuplicate == CRM_IMPORT_PARSER_DUPLICATE_REPLACE) { $newContact = crm_replace_contact_formatted($contactId, $formatted); } else { if ($onDuplicate == CRM_IMPORT_PARSER_DUPLICATE_UPDATE) { $newContact = crm_update_contact_formatted($contactId, $formatted, true); } else { if ($onDuplicate == CRM_IMPORT_PARSER_DUPLICATE_FILL) { $newContact = crm_update_contact_formatted($contactId, $formatted, false); } } } // else skip does nothing and just returns an error code. if ($newContact && !is_a($newContact, CRM_Core_Error)) { $this->_newContacts[] = $newContact->id; } //CRM-262 No Duplicate Checking if ($onDuplicate == CRM_IMPORT_PARSER_DUPLICATE_SKIP) { return CRM_IMPORT_PARSER_DUPLICATE; } return CRM_IMPORT_PARSER_VALID; } else { /* Not a dupe, so we had an error */ array_unshift($values, $newContact->_errors[0]['message']); return CRM_IMPORT_PARSER_ERROR; } } if ($newContact && !is_a($newContact, CRM_Core_Error)) { $this->_newContacts[] = $newContact->id; } return CRM_IMPORT_PARSER_VALID; }
/** * Get the result of the search for Add to * forms. * * @param CRM_Core_Form $form * @param array $params * This contains elements for search criteria. */ public function search(&$form, &$params) { //max records that will be listed $searchValues = array(); if (!empty($params['rel_contact'])) { if (isset($params['rel_contact_id']) && is_numeric($params['rel_contact_id'])) { $searchValues[] = array('contact_id', '=', $params['rel_contact_id'], 0, 1); } else { $searchValues[] = array('sort_name', 'LIKE', $params['rel_contact'], 0, 1); } } $contactTypeAdded = FALSE; $excludedContactIds = array(); if (isset($form->_contactId)) { $excludedContactIds[] = $form->_contactId; } if (!empty($params['relationship_type_id'])) { $relationshipType = new CRM_Contact_DAO_RelationshipType(); list($rid, $direction) = explode('_', $params['relationship_type_id'], 2); $relationshipType->id = $rid; if ($relationshipType->find(TRUE)) { if ($direction == 'a_b') { $type = $relationshipType->contact_type_b; $subType = $relationshipType->contact_sub_type_b; } else { $type = $relationshipType->contact_type_a; $subType = $relationshipType->contact_sub_type_a; } $form->set('contact_type', $type); $form->set('contact_sub_type', $subType); if ($type == 'Individual' || $type == 'Organization' || $type == 'Household') { $searchValues[] = array('contact_type', '=', $type, 0, 0); $contactTypeAdded = TRUE; } if ($subType) { $searchValues[] = array('contact_sub_type', '=', $subType, 0, 0); } } } if (!$contactTypeAdded && !empty($params['contact_type'])) { $searchValues[] = array('contact_type', '=', $params['contact_type'], 0, 0); } // get the count of contact $contactBAO = new CRM_Contact_BAO_Contact(); $query = new CRM_Contact_BAO_Query($searchValues); $searchCount = $query->searchQuery(0, 0, NULL, TRUE); $form->set('searchCount', $searchCount); if ($searchCount <= 50) { // get the result of the search $result = $query->searchQuery(0, 50, NULL); $config = CRM_Core_Config::singleton(); $searchRows = array(); //variable is set if only one record is foun and that record already has relationship with the contact $duplicateRelationship = 0; while ($result->fetch()) { $query->convertToPseudoNames($result); $contactID = $result->contact_id; if (in_array($contactID, $excludedContactIds)) { $duplicateRelationship++; continue; } $duplicateRelationship = 0; $searchRows[$contactID]['id'] = $contactID; $searchRows[$contactID]['name'] = $result->sort_name; $searchRows[$contactID]['city'] = $result->city; $searchRows[$contactID]['state'] = $result->state_province; $searchRows[$contactID]['email'] = $result->email; $searchRows[$contactID]['phone'] = $result->phone; $contact_type = '<img src="' . $config->resourceBase . 'i/contact_'; $searchRows[$contactID]['type'] = CRM_Contact_BAO_Contact_Utils::getImage($result->contact_sub_type ? $result->contact_sub_type : $result->contact_type); } $form->set('searchRows', $searchRows); $form->set('duplicateRelationship', $duplicateRelationship); } else { // resetting the session variables if many records are found $form->set('searchRows', NULL); $form->set('duplicateRelationship', NULL); } }
/** * Function to delete Relationship Types * * @param int $relationshipTypeId * @static */ static function del($relationshipTypeId) { // make sure relationshipTypeId is an integer if (!CRM_Utils_Rule::positiveInteger($relationshipTypeId)) { CRM_Core_Error::fatal(ts('Invalid relationship type')); } //check dependencies // delete all relationships $relationship = new CRM_Contact_DAO_Relationship(); $relationship->relationship_type_id = $relationshipTypeId; $relationship->delete(); // set all membership_type to null $query = "\nUPDATE civicrm_membership_type\n SET relationship_type_id = NULL\n WHERE relationship_type_id = %1\n"; $params = array(1 => array($relationshipTypeId, 'Integer')); CRM_Core_DAO::executeQuery($query, $params); //fixed for CRM-3323 $mappingField = new CRM_Core_DAO_MappingField(); $mappingField->relationship_type_id = $relationshipTypeId; $mappingField->find(); while ($mappingField->fetch()) { $mappingField->delete(); } $relationshipType = new CRM_Contact_DAO_RelationshipType(); $relationshipType->id = $relationshipTypeId; return $relationshipType->delete(); }
/** * browse all entities. * * @param int $action * * @return void * @access public */ function browse() { $n = func_num_args(); $action = $n > 0 ? func_get_arg(0) : NULL; $sort = $n > 0 ? func_get_arg(1) : NULL; $links =& $this->links(); if ($action == NULL) { if (!empty($links)) { $action = array_sum(array_keys($links)); } } if ($action & CRM_Core_Action::DISABLE) { $action -= CRM_Core_Action::DISABLE; } if ($action & CRM_Core_Action::ENABLE) { $action -= CRM_Core_Action::ENABLE; } $baoString = $this->getBAOName(); $object = new $baoString(); $values = array(); /* * lets make sure we get the stuff sorted by name if it exists */ $fields =& $object->fields(); $key = ''; if (CRM_Utils_Array::value('title', $fields)) { $key = 'title'; } elseif (CRM_Utils_Array::value('label', $fields)) { $key = 'label'; } elseif (CRM_Utils_Array::value('name', $fields)) { $key = 'name'; } if (trim($sort)) { $object->orderBy($sort); } elseif ($key) { $object->orderBy($key . ' asc'); } // find all objects $object->find(); while ($object->fetch()) { if (!isset($object->mapping_type_id) || $object->mapping_type_id != 1) { $permission = CRM_Core_Permission::EDIT; if ($key) { $permission = $this->checkPermission($object->id, $object->{$key}); } if ($permission) { $values[$object->id] = array(); CRM_Core_DAO::storeValues($object, $values[$object->id]); CRM_Contact_DAO_RelationshipType::addDisplayEnums($values[$object->id]); // populate action links $this->action($object, $action, $values[$object->id], $links, $permission); if (isset($object->mapping_type_id)) { $mappintTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Mapping', 'mapping_type_id'); $values[$object->id]['mapping_type'] = $mappintTypes[$object->mapping_type_id]; } } } } $this->assign('rows', $values); }
/** * class constructor */ function CRM_Contact_BAO_RelationshipType() { parent::CRM_Contact_DAO_RelationshipType(); }
/** * class constructor */ function __construct() { parent::__construct(); }
/** * browse all entities. * * @param int $action * * @return void * @access public */ function browse($action = null) { $links =& $this->links(); if ($action == null) { $action = array_sum(array_keys($links)); } if ($action & CRM_CORE_ACTION_DISABLE) { $action -= CRM_CORE_ACTION_DISABLE; } if ($action & CRM_CORE_ACTION_ENABLE) { $action -= CRM_CORE_ACTION_ENABLE; } eval('$object =& new ' . $this->getBAOName() . '( );'); $values = array(); /* * lets make sure we get the stuff sorted by name if it exists */ $fields =& $object->fields(); $key = ''; if (CRM_Utils_Array::value('title', $fields)) { $key = 'title'; } else { if (CRM_Utils_Array::value('label', $fields)) { $key = 'label'; } else { if (CRM_Utils_Array::value('name', $fields)) { $key = 'name'; } } } if ($key) { $object->orderBy($key . ' asc'); } // set the domain_id parameter $config =& CRM_Core_Config::singleton(); $object->domain_id = $config->domainID(); // find all objects $object->find(); while ($object->fetch()) { $permission = CRM_CORE_PERMISSION_EDIT; if ($key) { $permission = $this->checkPermission($object->id, $object->{$key}); } if ($permission) { $values[$object->id] = array(); CRM_Core_DAO::storeValues($object, $values[$object->id]); CRM_Contact_DAO_RelationshipType::addDisplayEnums($values[$object->id]); // populate action links CRM_Core_Page_Basic::action($object, $action, $values[$object->id], $links, $permission); } } $this->assign('rows', $values); }
/** * Get all Relationship Types from database. * * The static array group is returned, and if it's * called the first time, the <b>RelationshipType DAO</b> is used * to get all the relationship types. * * Note: any database errors will be trapped by the DAO. * * @param string $valueColumnName db column name/label. * @param boolean $reset reset relationship types if true * * @access public * @static * * @return array - array reference of all relationship types. */ public static function &relationshipType($valueColumnName = 'label', $reset = FALSE) { if (!CRM_Utils_Array::value($valueColumnName, self::$relationshipType) || $reset) { self::$relationshipType[$valueColumnName] = array(); //now we have name/label columns CRM-3336 $column_a_b = "{$valueColumnName}_a_b"; $column_b_a = "{$valueColumnName}_b_a"; $relationshipTypeDAO = new CRM_Contact_DAO_RelationshipType(); $relationshipTypeDAO->selectAdd(); $relationshipTypeDAO->selectAdd("id, {$column_a_b}, {$column_b_a}, contact_type_a, contact_type_b, contact_sub_type_a, contact_sub_type_b"); $relationshipTypeDAO->is_active = 1; $relationshipTypeDAO->find(); while ($relationshipTypeDAO->fetch()) { self::$relationshipType[$valueColumnName][$relationshipTypeDAO->id] = array('id' => $relationshipTypeDAO->id, $column_a_b => $relationshipTypeDAO->{$column_a_b}, $column_b_a => $relationshipTypeDAO->{$column_b_a}, 'contact_type_a' => "{$relationshipTypeDAO->contact_type_a}", 'contact_type_b' => "{$relationshipTypeDAO->contact_type_b}", 'contact_sub_type_a' => "{$relationshipTypeDAO->contact_sub_type_a}", 'contact_sub_type_b' => "{$relationshipTypeDAO->contact_sub_type_b}"); } } return self::$relationshipType[$valueColumnName]; }
/** * browse all entities. * * @param int $action * * @return void * @access public */ function browse($action = null, $sort) { $links =& $this->links(); if ($action == null) { if (!empty($links)) { $action = array_sum(array_keys($links)); } } if ($action & CRM_Core_Action::DISABLE) { $action -= CRM_Core_Action::DISABLE; } if ($action & CRM_Core_Action::ENABLE) { $action -= CRM_Core_Action::ENABLE; } eval('$object =& new ' . $this->getBAOName() . '( );'); $values = array(); /* * lets make sure we get the stuff sorted by name if it exists */ $fields =& $object->fields(); $key = ''; if (CRM_Utils_Array::value('title', $fields)) { $key = 'title'; } else { if (CRM_Utils_Array::value('label', $fields)) { $key = 'label'; } else { if (CRM_Utils_Array::value('name', $fields)) { $key = 'name'; } } } if (trim($sort)) { $object->orderBy($sort); } else { if ($key) { $object->orderBy($key . ' asc'); } } // find all objects $object->find(); while ($object->fetch()) { if (!isset($object->mapping_type_id) || $object->mapping_type_id != 1) { // "1 for Search Builder" $permission = CRM_Core_Permission::EDIT; if ($key) { $permission = $this->checkPermission($object->id, $object->{$key}); } if ($permission) { $values[$object->id] = array(); CRM_Core_DAO::storeValues($object, $values[$object->id]); require_once 'CRM/Contact/DAO/RelationshipType.php'; CRM_Contact_DAO_RelationshipType::addDisplayEnums($values[$object->id]); // populate action links $this->action($object, $action, $values[$object->id], $links, $permission); if (isset($object->mapping_type_id)) { require_once 'CRM/Core/PseudoConstant.php'; $mappintTypes = CRM_Core_PseudoConstant::mappingTypes(); $values[$object->id]['mapping_type'] = $mappintTypes[$object->mapping_type_id]; } } $this->assign('rows', $values); } } }
/** * Function to get all relationship type * retruns An array of Relationship_type * * @access public */ function civicrm_relationship_types_get($params = null) { _civicrm_initialize(); require_once 'CRM/Contact/DAO/RelationshipType.php'; $relationshipTypes = array(); $relationshipType = array(); $relationType = new CRM_Contact_DAO_RelationshipType(); if (!empty($params) && is_array($params)) { $properties = array_keys($relationType->fields()); foreach ($properties as $name) { if (array_key_exists($name, $params)) { $relationType->{$name} = $params[$name]; } } } $relationType->find(); while ($relationType->fetch()) { _civicrm_object_to_array(clone $relationType, $relationshipType); $relationshipTypes[] = $relationshipType; } return $relationshipTypes; }
/** * 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, // prioritising a dedupe rule check over an external_identifier check, but falling back on ext id. if ($this->_updateWithId && empty($params['id'])) { $possibleMatches = $this->getPossibleContactMatches($params); foreach ($possibleMatches as $possibleID) { $params['id'] = $formatted['id'] = $possibleID; } } //format common data, CRM-4062 $this->formatCommonData($params, $formatted, $contactFields); $relationship = FALSE; $createNewContact = TRUE; // Support Match and Update Via Contact ID if ($this->_updateWithId && isset($params['id'])) { $createNewContact = FALSE; // @todo - it feels like all the rows from here to the end of the IF // could be removed in favour of a simple check for whether the contact_type & id match // the call to the deprecated function seems to add no value other that to do an additional // check for the contact_id & type. $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); }
/** * Function to add on behalf of organization and it's location * * @param $behalfOrganization array array of organization info * @param $contactID int individual contact id. One * who is doing the process of signup / contribution. * * @param $values array form values array * @param $params * @param null $fields * * @return void * @access public */ static function processOnBehalfOrganization(&$behalfOrganization, &$contactID, &$values, &$params, $fields = NULL) { $isCurrentEmployer = FALSE; $orgID = NULL; if (!empty($behalfOrganization['organization_id']) && !empty($behalfOrganization['org_option'])) { $orgID = $behalfOrganization['organization_id']; unset($behalfOrganization['organization_id']); $isCurrentEmployer = TRUE; } // formalities for creating / editing organization. $behalfOrganization['contact_type'] = 'Organization'; // get the relationship type id $relType = new CRM_Contact_DAO_RelationshipType(); $relType->name_a_b = 'Employee of'; $relType->find(TRUE); $relTypeId = $relType->id; // keep relationship params ready $relParams['relationship_type_id'] = $relTypeId . '_a_b'; $relParams['is_permission_a_b'] = 1; $relParams['is_active'] = 1; 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'] = $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 $relParams['contact_check'][$orgID] = 1; $cid = array('contact' => $contactID); CRM_Contact_BAO_Relationship::create($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; // required for IPN $params['related_contact'] = $contactID; //make this employee of relationship as current //employer / employee relationship, CRM-3532 if ($isCurrentEmployer && $orgID != CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'employer_id')) { $isCurrentEmployer = FALSE; } if (!$isCurrentEmployer && $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; } }
/** * Returns the list of fields that can be exported * * @param bool $prefix * * @return array */ static function &export($prefix = false) { if (!self::$_export) { self::$_export = array(); $fields = self::fields(); foreach ($fields as $name => $field) { if (CRM_Utils_Array::value('export', $field)) { if ($prefix) { self::$_export['relationship_type'] =& $fields[$name]; } else { self::$_export[$name] =& $fields[$name]; } } } } return self::$_export; }
/** * Process the mapped fields and map it into the uploaded file. */ public function postProcess() { $params = $this->controller->exportValues('MapField'); //reload the mapfield if load mapping is pressed if (!empty($params['savedMapping'])) { $this->set('savedMapping', $params['savedMapping']); $this->controller->resetPage($this->_name); return; } $mapper = array(); $mapperKeys = array(); $mapperKeys = $this->controller->exportValue($this->_name, 'mapper'); $mapperKeysMain = array(); $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'); $websiteTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Website', 'website_type_id'); $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); //these mapper params need to set key as array and val as null. $mapperParams = array('related' => 'relatedVal', 'locations' => 'locationsVal', 'mapperLocType' => 'mapperLocTypeVal', 'mapperPhoneType' => 'mapperPhoneTypeVal', 'mapperImProvider' => 'mapperImProviderVal', 'mapperWebsiteType' => 'mapperWebsiteTypeVal', 'relatedContactType' => 'relatedContactTypeVal', 'relatedContactDetails' => 'relatedContactDetailsVal', 'relatedContactLocType' => 'relatedContactLocTypeVal', 'relatedContactPhoneType' => 'relatedContactPhoneTypeVal', 'relatedContactImProvider' => 'relatedContactImProviderVal', 'relatedContactWebsiteType' => 'relatedContactWebsiteTypeVal'); //set respective mapper params to array. foreach (array_keys($mapperParams) as $mapperParam) { ${$mapperParam} = array(); } for ($i = 0; $i < $this->_columnCount; $i++) { //set respective mapper value to null foreach (array_values($mapperParams) as $mapperParam) { ${$mapperParam} = NULL; } $fldName = CRM_Utils_Array::value(0, $mapperKeys[$i]); $selOne = CRM_Utils_Array::value(1, $mapperKeys[$i]); $selTwo = CRM_Utils_Array::value(2, $mapperKeys[$i]); $selThree = CRM_Utils_Array::value(3, $mapperKeys[$i]); $mapper[$i] = $this->_mapperFields[$mapperKeys[$i][0]]; $mapperKeysMain[$i] = $fldName; //need to differentiate non location elements. if ($selOne && is_numeric($selOne)) { if ($fldName == 'url') { $mapperWebsiteTypeVal = $websiteTypes[$selOne]; } else { $locationsVal = $locationTypes[$selOne]; $mapperLocTypeVal = $selOne; if ($selTwo && is_numeric($selTwo)) { if ($fldName == 'phone') { $mapperPhoneTypeVal = $phoneTypes[$selTwo]; } elseif ($fldName == 'im') { $mapperImProviderVal = $imProviders[$selTwo]; } } } } //relationship contact mapper info. list($id, $first, $second) = CRM_Utils_System::explode('_', $fldName, 3); if ($first == 'a' && $second == 'b' || $first == 'b' && $second == 'a') { $relatedVal = $this->_mapperFields[$fldName]; if ($selOne) { if ($selOne == 'url') { $relatedContactWebsiteTypeVal = $websiteTypes[$selTwo]; } else { $relatedContactLocTypeVal = CRM_Utils_Array::value($selTwo, $locationTypes); if ($selThree) { if ($selOne == 'phone') { $relatedContactPhoneTypeVal = $phoneTypes[$selThree]; } elseif ($selOne == 'im') { $relatedContactImProviderVal = $imProviders[$selThree]; } } } //get the related contact type. $relationType = new CRM_Contact_DAO_RelationshipType(); $relationType->id = $id; $relationType->find(TRUE); $relatedContactTypeVal = $relationType->{"contact_type_{$second}"}; $relatedContactDetailsVal = $this->_formattedFieldNames[$relatedContactTypeVal][$selOne]; } } //set the respective mapper param array values. foreach ($mapperParams as $mapperParamKey => $mapperParamVal) { ${$mapperParamKey}[$i] = ${$mapperParamVal}; } } $this->set('columnNames', $this->_columnNames); //set main contact properties. $properties = array('ims' => 'mapperImProvider', 'mapper' => 'mapper', 'phones' => 'mapperPhoneType', 'websites' => 'mapperWebsiteType', 'locations' => 'locations'); foreach ($properties as $propertyName => $propertyVal) { $this->set($propertyName, ${$propertyVal}); } //set related contact propeties. $relProperties = array('related', 'relatedContactType', 'relatedContactDetails', 'relatedContactLocType', 'relatedContactPhoneType', 'relatedContactImProvider', 'relatedContactWebsiteType'); foreach ($relProperties as $relProperty) { $this->set($relProperty, ${$relProperty}); } // store mapping Id to display it in the preview page $this->set('loadMappingId', CRM_Utils_Array::value('mappingId', $params)); //Updating Mapping Records if (!empty($params['updateMapping'])) { $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); $mappingFields = new CRM_Core_DAO_MappingField(); $mappingFields->mapping_id = $params['mappingId']; $mappingFields->find(); $mappingFieldsId = array(); while ($mappingFields->fetch()) { if ($mappingFields->id) { $mappingFieldsId[$mappingFields->column_number] = $mappingFields->id; } } for ($i = 0; $i < $this->_columnCount; $i++) { $updateMappingFields = new CRM_Core_DAO_MappingField(); $updateMappingFields->id = CRM_Utils_Array::value($i, $mappingFieldsId); $updateMappingFields->mapping_id = $params['mappingId']; $updateMappingFields->column_number = $i; $mapperKeyParts = explode('_', $mapperKeys[$i][0], 3); $id = isset($mapperKeyParts[0]) ? $mapperKeyParts[0] : NULL; $first = isset($mapperKeyParts[1]) ? $mapperKeyParts[1] : NULL; $second = isset($mapperKeyParts[2]) ? $mapperKeyParts[2] : NULL; if ($first == 'a' && $second == 'b' || $first == 'b' && $second == 'a') { $updateMappingFields->relationship_type_id = $id; $updateMappingFields->relationship_direction = "{$first}_{$second}"; $updateMappingFields->name = ucwords(str_replace("_", " ", $mapperKeys[$i][1])); // get phoneType id and provider id separately // before updating mappingFields of phone and IM for related contact, CRM-3140 if (CRM_Utils_Array::value('1', $mapperKeys[$i]) == 'url') { $updateMappingFields->website_type_id = isset($mapperKeys[$i][2]) ? $mapperKeys[$i][2] : NULL; } else { if (CRM_Utils_Array::value('1', $mapperKeys[$i]) == 'phone') { $updateMappingFields->phone_type_id = isset($mapperKeys[$i][3]) ? $mapperKeys[$i][3] : NULL; } elseif (CRM_Utils_Array::value('1', $mapperKeys[$i]) == 'im') { $updateMappingFields->im_provider_id = isset($mapperKeys[$i][3]) ? $mapperKeys[$i][3] : NULL; } $updateMappingFields->location_type_id = isset($mapperKeys[$i][2]) ? $mapperKeys[$i][2] : NULL; } } else { $updateMappingFields->name = $mapper[$i]; $updateMappingFields->relationship_type_id = 'NULL'; $updateMappingFields->relationship_type_direction = 'NULL'; // to store phoneType id and provider id separately // before updating mappingFields for phone and IM, CRM-3140 if (CRM_Utils_Array::value('0', $mapperKeys[$i]) == 'url') { $updateMappingFields->website_type_id = isset($mapperKeys[$i][1]) ? $mapperKeys[$i][1] : NULL; } else { if (CRM_Utils_Array::value('0', $mapperKeys[$i]) == 'phone') { $updateMappingFields->phone_type_id = isset($mapperKeys[$i][2]) ? $mapperKeys[$i][2] : NULL; } elseif (CRM_Utils_Array::value('0', $mapperKeys[$i]) == 'im') { $updateMappingFields->im_provider_id = isset($mapperKeys[$i][2]) ? $mapperKeys[$i][2] : NULL; } $location = array_keys($locationTypes, $locations[$i]); $updateMappingFields->location_type_id = isset($location) && isset($location[0]) ? $location[0] : NULL; } } $updateMappingFields->save(); } } //Saving Mapping Details and Records if (!empty($params['saveMapping'])) { $mappingParams = array('name' => $params['saveMappingName'], 'description' => $params['saveMappingDesc'], 'mapping_type_id' => CRM_Core_OptionGroup::getValue('mapping_type', 'Import Contact', 'name')); $saveMapping = CRM_Core_BAO_Mapping::add($mappingParams); $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); $contactType = $this->get('contactType'); switch ($contactType) { case CRM_Import_Parser::CONTACT_INDIVIDUAL: $cType = 'Individual'; break; case CRM_Import_Parser::CONTACT_HOUSEHOLD: $cType = 'Household'; break; case CRM_Import_Parser::CONTACT_ORGANIZATION: $cType = 'Organization'; } for ($i = 0; $i < $this->_columnCount; $i++) { $saveMappingFields = new CRM_Core_DAO_MappingField(); $saveMappingFields->mapping_id = $saveMapping->id; $saveMappingFields->contact_type = $cType; $saveMappingFields->column_number = $i; $mapperKeyParts = explode('_', $mapperKeys[$i][0], 3); $id = isset($mapperKeyParts[0]) ? $mapperKeyParts[0] : NULL; $first = isset($mapperKeyParts[1]) ? $mapperKeyParts[1] : NULL; $second = isset($mapperKeyParts[2]) ? $mapperKeyParts[2] : NULL; if ($first == 'a' && $second == 'b' || $first == 'b' && $second == 'a') { $saveMappingFields->name = ucwords(str_replace("_", " ", $mapperKeys[$i][1])); $saveMappingFields->relationship_type_id = $id; $saveMappingFields->relationship_direction = "{$first}_{$second}"; // to get phoneType id and provider id separately // before saving mappingFields of phone and IM for related contact, CRM-3140 if (CRM_Utils_Array::value('1', $mapperKeys[$i]) == 'url') { $saveMappingFields->website_type_id = isset($mapperKeys[$i][2]) ? $mapperKeys[$i][2] : NULL; } else { if (CRM_Utils_Array::value('1', $mapperKeys[$i]) == 'phone') { $saveMappingFields->phone_type_id = isset($mapperKeys[$i][3]) ? $mapperKeys[$i][3] : NULL; } elseif (CRM_Utils_Array::value('1', $mapperKeys[$i]) == 'im') { $saveMappingFields->im_provider_id = isset($mapperKeys[$i][3]) ? $mapperKeys[$i][3] : NULL; } $saveMappingFields->location_type_id = isset($mapperKeys[$i][2]) ? $mapperKeys[$i][2] : NULL; } } else { $saveMappingFields->name = $mapper[$i]; $location_id = array_keys($locationTypes, $locations[$i]); // to get phoneType id and provider id separately // before saving mappingFields of phone and IM, CRM-3140 if (CRM_Utils_Array::value('0', $mapperKeys[$i]) == 'url') { $saveMappingFields->website_type_id = isset($mapperKeys[$i][1]) ? $mapperKeys[$i][1] : NULL; } else { if (CRM_Utils_Array::value('0', $mapperKeys[$i]) == 'phone') { $saveMappingFields->phone_type_id = isset($mapperKeys[$i][2]) ? $mapperKeys[$i][2] : NULL; } elseif (CRM_Utils_Array::value('0', $mapperKeys[$i]) == 'im') { $saveMappingFields->im_provider_id = isset($mapperKeys[$i][2]) ? $mapperKeys[$i][2] : NULL; } $saveMappingFields->location_type_id = isset($location_id[0]) ? $location_id[0] : NULL; } $saveMappingFields->relationship_type_id = NULL; } $saveMappingFields->save(); } $this->set('savedMapping', $saveMappingFields->mapping_id); } $parser = new CRM_Contact_Import_Parser_Contact($mapperKeysMain, $mapperLocType, $mapperPhoneType, $mapperImProvider, $related, $relatedContactType, $relatedContactDetails, $relatedContactLocType, $relatedContactPhoneType, $relatedContactImProvider, $mapperWebsiteType, $relatedContactWebsiteType); $primaryKeyName = $this->get('primaryKeyName'); $statusFieldName = $this->get('statusFieldName'); $parser->run($this->_importTableName, $mapper, CRM_Import_Parser::MODE_PREVIEW, $this->get('contactType'), $primaryKeyName, $statusFieldName, $this->_onDuplicate, NULL, NULL, FALSE, CRM_Contact_Import_Parser::DEFAULT_TIMEOUT, $this->get('contactSubType'), $this->get('dedupe')); // add all the necessary variables to the form $parser->set($this); }
/** * Function to delete Relationship Types * * @param int $relationshipTypeId * @static */ static function del($relationshipTypeId) { // make sure relationshipTypeId is an integer // @todo review this as most delete functions rely on the api & form layer for this // or do a find first & throw error if no find if (!CRM_Utils_Rule::positiveInteger($relationshipTypeId)) { throw new CRM_Core_Exception(ts('Invalid relationship type')); } //check dependencies // delete all relationships $relationship = new CRM_Contact_DAO_Relationship(); $relationship->relationship_type_id = $relationshipTypeId; $relationship->delete(); // set all membership_type to null $query = "\nUPDATE civicrm_membership_type\n SET relationship_type_id = NULL\n WHERE relationship_type_id = %1\n"; $params = array(1 => array(CRM_Core_DAO::VALUE_SEPARATOR . $relationshipTypeId . CRM_Core_DAO::VALUE_SEPARATOR, 'String')); CRM_Core_DAO::executeQuery($query, $params); //fixed for CRM-3323 $mappingField = new CRM_Core_DAO_MappingField(); $mappingField->relationship_type_id = $relationshipTypeId; $mappingField->find(); while ($mappingField->fetch()) { $mappingField->delete(); } $relationshipType = new CRM_Contact_DAO_RelationshipType(); $relationshipType->id = $relationshipTypeId; return $relationshipType->delete(); }
/** * Process the mapped fields and map it into the uploaded file * preview the file and extract some summary statistics * * @return void * @access public */ public function postProcessOld() { $doGeocodeAddress = $this->controller->exportValue('DataSource', 'doGeocodeAddress'); $invalidRowCount = $this->get('invalidRowCount'); $conflictRowCount = $this->get('conflictRowCount'); $onDuplicate = $this->get('onDuplicate'); $newGroupName = $this->controller->exportValue($this->_name, 'newGroupName'); $newGroupDesc = $this->controller->exportValue($this->_name, 'newGroupDesc'); $groups = $this->controller->exportValue($this->_name, 'groups'); $allGroups = $this->get('groups'); $newTagName = $this->controller->exportValue($this->_name, 'newTagName'); $newTagDesc = $this->controller->exportValue($this->_name, 'newTagDesc'); $tag = $this->controller->exportValue($this->_name, 'tag'); $allTags = $this->get('tag'); $mapper = $this->controller->exportValue('MapField', 'mapper'); $mapperKeys = array(); $mapperLocTypes = array(); $mapperPhoneTypes = array(); $mapperRelated = array(); $mapperRelatedContactType = array(); $mapperRelatedContactDetails = array(); $mapperRelatedContactLocType = array(); $mapperRelatedContactPhoneType = array(); foreach ($mapper as $key => $value) { $mapperKeys[$key] = $mapper[$key][0]; if (is_numeric($mapper[$key][1])) { $mapperLocTypes[$key] = $mapper[$key][1]; } else { $mapperLocTypes[$key] = NULL; } if (CRM_Utils_Array::value($key, $mapperKeys) == 'phone') { $mapperPhoneTypes[$key] = $mapper[$key][2]; } else { $mapperPhoneTypes[$key] = NULL; } list($id, $first, $second) = explode('_', $mapper[$key][0]); if ($first == 'a' && $second == 'b' || $first == 'b' && $second == 'a') { $relationType = new CRM_Contact_DAO_RelationshipType(); $relationType->id = $id; $relationType->find(TRUE); $fieldName = "contact_type_{$second}"; $mapperRelatedContactType[$key] = $relationType->{$fieldName}; $mapperRelated[$key] = $mapper[$key][0]; $mapperRelatedContactDetails[$key] = $mapper[$key][1]; $mapperRelatedContactLocType[$key] = $mapper[$key][2]; $mapperRelatedContactPhoneType[$key] = $mapper[$key][3]; } else { $mapperRelated[$key] = NULL; $mapperRelatedContactType[$key] = NULL; $mapperRelatedContactDetails[$key] = NULL; $mapperRelatedContactLocType[$key] = NULL; $mapperRelatedContactPhoneType[$key] = NULL; } } $parser = new CRM_Contact_Import_Parser_Contact($mapperKeys, $mapperLocTypes, $mapperPhoneTypes, $mapperRelated, $mapperRelatedContactType, $mapperRelatedContactDetails, $mapperRelatedContactLocType, $mapperRelatedContactPhoneType); $mapFields = $this->get('fields'); $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); foreach ($mapper as $key => $value) { $header = array(); list($id, $first, $second) = explode('_', $mapper[$key][0]); if ($first == 'a' && $second == 'b' || $first == 'b' && $second == 'a') { $relationType = new CRM_Contact_DAO_RelationshipType(); $relationType->id = $id; $relationType->find(TRUE); $header[] = $relationType->name_a_b; $header[] = ucwords(str_replace("_", " ", $mapper[$key][1])); if (isset($mapper[$key][2])) { $header[] = $locationTypes[$mapper[$key][2]]; } if (isset($mapper[$key][3])) { $header[] = $phoneTypes[$mapper[$key][3]]; } } else { if (isset($mapFields[$mapper[$key][0]])) { $header[] = $mapFields[$mapper[$key][0]]; if (isset($mapper[$key][1])) { $header[] = $locationTypes[$mapper[$key][1]]; } if (isset($mapper[$key][2])) { $header[] = $phoneTypes[$mapper[$key][2]]; } } } $mapperFields[] = implode(' - ', $header); } $tableName = $this->get('importTableName'); //print "Running parser on table: $tableName<br/>"; $parser->run($tableName, $mapperFields, CRM_Import_Parser::MODE_IMPORT, $this->get('contactType'), $this->get('primaryKeyName'), $this->get('statusFieldName'), $onDuplicate, $this->get('statusID'), $this->get('totalRowCount'), $doGeocodeAddress, CRM_Contact_Import_Parser::DEFAULT_TIMEOUT, $this->get('contactSubType'), $this->get('dedupe')); // add the new contacts to selected groups $contactIds =& $parser->getImportedContacts(); // add the new related contacts to selected groups $relatedContactIds =& $parser->getRelatedImportedContacts(); $this->set('relatedCount', count($relatedContactIds)); $newGroupId = NULL; //changed below if-statement "if ($newGroup) {" to "if ($newGroupName) {" if ($newGroupName) { /* Create a new group */ $gParams = array('name' => $newGroupName, 'title' => $newGroupName, 'description' => $newGroupDesc, 'is_active' => TRUE); $group = CRM_Contact_BAO_Group::create($gParams); $groups[] = $newGroupId = $group->id; } if (is_array($groups)) { $groupAdditions = array(); foreach ($groups as $groupId) { $addCount = CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIds, $groupId); if (!empty($relatedContactIds)) { $addRelCount = CRM_Contact_BAO_GroupContact::addContactsToGroup($relatedContactIds, $groupId); } $totalCount = $addCount[1] + $addRelCount[1]; if ($groupId == $newGroupId) { $name = $newGroupName; $new = TRUE; } else { $name = $allGroups[$groupId]; $new = FALSE; } $groupAdditions[] = array('url' => CRM_Utils_System::url('civicrm/group/search', 'reset=1&force=1&context=smog&gid=' . $groupId), 'name' => $name, 'added' => $totalCount, 'notAdded' => $addCount[2] + $addRelCount[2], 'new' => $new); } $this->set('groupAdditions', $groupAdditions); } $newTagId = NULL; if ($newTagName) { /* Create a new Tag */ $tagParams = array('name' => $newTagName, 'title' => $newTagName, 'description' => $newTagDesc, 'is_active' => TRUE); $id = array(); $addedTag = CRM_Core_BAO_Tag::add($tagParams, $id); $tag[$addedTag->id] = 1; } //add Tag to Import if (is_array($tag)) { $tagAdditions = array(); foreach ($tag as $tagId => $val) { $addTagCount = CRM_Core_BAO_EntityTag::addContactsToTag($contactIds, $tagId); if (!empty($relatedContactIds)) { $addRelTagCount = CRM_Core_BAO_EntityTag::addContactsToTag($relatedContactIds, $tagId); } $totalTagCount = $addTagCount[1] + $addRelTagCount[1]; if ($tagId == $addedTag->id) { $tagName = $newTagName; $new = TRUE; } else { $tagName = $allTags[$tagId]; $new = FALSE; } $tagAdditions[] = array('url' => CRM_Utils_System::url('civicrm/contact/search', 'reset=1&force=1&context=smog&id=' . $tagId), 'name' => $tagName, 'added' => $totalTagCount, 'notAdded' => $addTagCount[2] + $addRelTagCount[2], 'new' => $new); } $this->set('tagAdditions', $tagAdditions); } // add all the necessary variables to the form $parser->set($this, CRM_Import_Parser::MODE_IMPORT); // check if there is any error occured $errorStack = CRM_Core_Error::singleton(); $errors = $errorStack->getErrors(); $errorMessage = array(); if (is_array($errors)) { foreach ($errors as $key => $value) { $errorMessage[] = $value['message']; } // there is no fileName since this is a sql import // so fudge it $config = CRM_Core_Config::singleton(); $errorFile = $config->uploadDir . "sqlImport.error.log"; if ($fd = fopen($errorFile, 'w')) { fwrite($fd, implode('\\n', $errorMessage)); } fclose($fd); $this->set('errorFile', $errorFile); $urlParams = 'type=' . CRM_Import_Parser::ERROR . '&parser=CRM_Contact_Import_Parser'; $this->set('downloadErrorRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlparams)); $urlParams = 'type=' . CRM_Import_Parser::CONFLICT . '&parser=CRM_Contact_Import_Parser'; $this->set('downloadConflictRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams)); $urlParams = 'type=' . CRM_Import_Parser::NO_MATCH . '&parser=CRM_Contact_Import_Parser'; $this->set('downloadMismatchRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams)); } }
static function relationshipContacts() { $data = $searchValues = $searchRows = array(); $addCount = 0; $relType = CRM_Utils_Type::escape($_REQUEST['relType'], 'String'); $typeName = isset($_REQUEST['typeName']) ? CRM_Utils_Type::escape($_REQUEST['typeName'], 'String') : ''; $relContact = CRM_Utils_Type::escape($_REQUEST['relContact'], 'String'); $currentContactId = CRM_Utils_Type::escape($_REQUEST['cid'], 'Integer'); if (in_array($typeName, array('Employee of', 'Employer of'))) { $addCount = 1; } $sortMapper = array(1 => 'sort_name', 2 + $addCount => 'city', 3 + $addCount => 'state_province', 4 + $addCount => 'email', 5 + $addCount => 'phone'); $sEcho = CRM_Utils_Type::escape($_REQUEST['sEcho'], 'Integer'); $offset = isset($_REQUEST['iDisplayStart']) ? CRM_Utils_Type::escape($_REQUEST['iDisplayStart'], 'Integer') : 0; $rowCount = isset($_REQUEST['iDisplayLength']) ? CRM_Utils_Type::escape($_REQUEST['iDisplayLength'], 'Integer') : 25; $sort = isset($_REQUEST['iSortCol_0']) ? $sortMapper[CRM_Utils_Type::escape($_REQUEST['iSortCol_0'], 'Integer')] : 'sort_name'; $sortOrder = isset($_REQUEST['sSortDir_0']) ? CRM_Utils_Type::escape($_REQUEST['sSortDir_0'], 'String') : 'asc'; $searchValues[] = array('sort_name', 'LIKE', $relContact, 0, 1); list($rid, $direction) = explode('_', $relType, 2); $relationshipType = new CRM_Contact_DAO_RelationshipType(); $relationshipType->id = $rid; if ($relationshipType->find(TRUE)) { if ($direction == 'a_b') { $type = $relationshipType->contact_type_b; $subType = $relationshipType->contact_sub_type_b; } else { $type = $relationshipType->contact_type_a; $subType = $relationshipType->contact_sub_type_a; } if ($type == 'Individual' || $type == 'Organization' || $type == 'Household') { $searchValues[] = array('contact_type', '=', $type, 0, 0); $contactTypeAdded = TRUE; } if ($subType) { $searchValues[] = array('contact_sub_type', '=', $subType, 0, 0); } } // exclude current contact $searchValues[] = array('contact_id', '!=', $currentContactId, 0, 0); $contactBAO = new CRM_Contact_BAO_Contact(); $query = new CRM_Contact_BAO_Query($searchValues); $searchCount = $query->searchQuery(0, 0, NULL, TRUE); $iTotal = $searchCount; if ($searchCount > 0) { // get the result of the search $result = $query->searchQuery($offset, $rowCount, $sort, FALSE, FALSE, FALSE, FALSE, FALSE, NULL, $sortOrder); $config = CRM_Core_Config::singleton(); //variable is set if only one record is foun and that record already has relationship with the contact $duplicateRelationship = 0; while ($result->fetch()) { $contactID = $result->contact_id; $duplicateRelationship = 0; $contact_type = '<img src="' . $config->resourceBase . 'i/contact_'; $typeImage = CRM_Contact_BAO_Contact_Utils::getImage($result->contact_sub_type ? $result->contact_sub_type : $result->contact_type, FALSE, $contactID); $searchRows[$contactID]['id'] = $contactID; $searchRows[$contactID]['name'] = $typeImage . ' ' . $result->sort_name; $searchRows[$contactID]['city'] = $result->city; $searchRows[$contactID]['state'] = $result->state_province; $searchRows[$contactID]['email'] = $result->email; $searchRows[$contactID]['phone'] = $result->phone; } } foreach ($searchRows as $cid => $row) { $searchRows[$cid]['check'] = '<input type="checkbox" id="contact_check[' . $cid . ']" name="contact_check[' . $cid . ']" value=' . $cid . ' />'; if ($typeName == 'Employee of') { $searchRows[$cid]['employee_of'] = '<input type="radio" name="employee_of" value=' . $cid . ' >'; } elseif ($typeName == 'Employer of') { $searchRows[$cid]['employer_of'] = '<input type="checkbox" name="employer_of[' . $cid . ']" value=' . $cid . ' />'; } } $selectorElements = array('check', 'name'); if ($typeName == 'Employee of') { $selectorElements[] = 'employee_of'; } elseif ($typeName == 'Employer of') { $selectorElements[] = 'employer_of'; } $selectorElements = array_merge($selectorElements, array('city', 'state', 'email', 'phone')); $iFilteredTotal = $iTotal; echo CRM_Utils_JSON::encodeDataTableSelector($searchRows, $sEcho, $iTotal, $iFilteredTotal, $selectorElements); CRM_Utils_System::civiExit(); }
/** * 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 * * @return boolean the result of this processing * @access 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) { require_once "CRM/Contact/DAO/Contact.php"; $contactFields =& CRM_Contact_DAO_Contact::import(); } //check if external identifier exists in database if (CRM_Utils_Array::value('external_identifier', $params) && (CRM_Utils_Array::value('id', $params) || in_array($onDuplicate, array(CRM_Import_Parser::DUPLICATE_SKIP, CRM_Import_Parser::DUPLICATE_NOCHECK)))) { require_once "CRM/Contact/BAO/Contact.php"; 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 Identifier 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::ERROR; } } } 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 && !CRM_Utils_Array::value('id', $params) && CRM_Utils_Array::value('external_identifier', $params)) { 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 (!CRM_Utils_Array::value('id', $params) && CRM_Utils_Array::value('external_identifier', $params)) { if ($cid) { $params['id'] = $cid; } else { //update contact if dedupe found contact id, CRM-4148 $dedupeParams = $formatted; //special case to check dedupe if external id present. //if we send external id dedupe will stop. unset($dedupeParams['external_identifier']); $checkDedupe = _civicrm_duplicate_formatted_contact($dedupeParams); if (civicrm_duplicate($checkDedupe)) { $matchingContactIds = explode(',', $checkDedupe['error_message']['params'][0]); if (count($matchingContactIds) == 1) { $params['id'] = array_pop($matchingContactIds); } else { $message = "More than one matching contact found for given criteria."; array_unshift($values, $message); $this->_retCode = CRM_Import_Parser::NO_MATCH; } } else { $createNewContact = true; } } } $error = _civicrm_duplicate_formatted_contact($formatted); if (civicrm_duplicate($error)) { $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 (CRM_Utils_Array::value('contact_sub_type', $params)) { $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 { $newContact = $this->createContact($formatted, $contactFields, $onDuplicate, $contactId, false); $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 (CRM_Utils_Array::value('id', $params)) { $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 (CRM_Utils_Array::value('contact_sub_type', $params)) { $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->_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 (is_a($newContact, 'CRM_Contact_BAO_Contact')) { $relationship = true; } else { if (is_a($error, 'CRM_Core_Error')) { $newContact = $error; $relationship = true; } } } //fixed CRM-4148 //now we create new contact in update/fill mode also. if ($createNewContact) { //CRM-4430, don't carry if not submitted. foreach (array('prefix', 'suffix', 'gender') as $name) { if (array_key_exists($name, $formatted)) { if (in_array($name, array('prefix', 'suffix'))) { $formattedName = "individual_{$name}"; $formatted[$formattedName] = CRM_Core_OptionGroup::getValue($formattedName, (string) $formatted[$name]); } else { $formatted[$name] = CRM_Core_OptionGroup::getValue($name, (string) $formatted[$name]); } } } $newContact = $this->createContact($formatted, $contactFields, $onDuplicate); } if (is_object($newContact) || $newContact instanceof CRM_Contact_BAO_Contact) { $relationship = true; $newContact = clone $newContact; $this->_newContacts[] = $newContact->id; //get return code if we create new contact in update mode, CRM-4148 if ($this->_updateWithId) { $this->_retCode = CRM_Import_Parser::VALID; } } else { if (civicrm_duplicate($newContact)) { $relationship = true; $contactID = $newContact['error_message']['params'][0]; if (!in_array($contactID, $this->_newContacts)) { $this->_newContacts[] = $contactID; } } } if ($relationship) { $primaryContactId = null; if (civicrm_duplicate($newContact)) { if (CRM_Utils_Rule::integer($newContact['error_message']['params'][0])) { $primaryContactId = $newContact['error_message']['params'][0]; } } else { $primaryContactId = $newContact->id; } if ((civicrm_duplicate($newContact) || 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 (!CRM_Utils_Array::value('id', $params[$key]) && isset($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)) && CRM_Utils_Array::value('id', $params[$key])) { $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 (CRM_Utils_Array::value('contact_sub_type', $formatting)) { $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 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); //fixed for CRM-4148 if ($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 (civicrm_duplicate($relatedNewContact)) { $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 (CRM_Utils_Array::value('contact_sub_type', $formatting)) { $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 (civicrm_duplicate($relatedNewContact)) { 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 (civicrm_duplicate($relatedNewContact) || $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::create($relationParams, $relationIds); CRM_Contact_BAO_Relationship::relatedMemberships($primaryContactId, $relationParams, $relationIds); //handle current employer, CRM-3532 if ($valid) { require_once 'CRM/Core/PseudoConstant.php'; $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; } else { if ($allRelationships[$relationshipTypeId]["name_{$relationshipType}"] == 'Employer of') { $orgId = $primaryContactId; $individualId = $relContactId; } } if ($orgId && $individualId) { $currentEmpParams[$individualId] = $orgId; require_once 'CRM/Contact/BAO/Contact/Utils.php'; 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) { $result = civicrm_replace_contact_formatted($contactId, $formatted, $contactFields); $cid = $result['result']; } else { if ($onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE) { $newContact = $this->createContact($formatted, $contactFields, $onDuplicate, $contactId); } else { if ($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)) { $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); }
/** * Function to add on behalf of organization and it's location * * @param $behalfOrganization array array of organization info * @param $values array form values array * @param $contactID int individual contact id. One * who is doing the process of signup / contribution. * * @return void * @access public */ static function processOnBehalfOrganization(&$behalfOrganization, &$contactID, &$values, &$params) { $isCurrentEmployer = false; if ($behalfOrganization['organization_id'] && $behalfOrganization['org_option']) { $orgID = $behalfOrganization['organization_id']; unset($behalfOrganization['organization_id']); $isCurrentEmployer = true; } // formalities for creating / editing organization. require_once 'CRM/Core/BAO/LocationType.php'; $locType = CRM_Core_BAO_LocationType::getDefault(); $behalfOrganization['contact_type'] = 'Organization'; foreach (array('phone', 'email', 'address') as $locFld) { $behalfOrganization[$locFld][1]['is_primary'] = 1; $behalfOrganization[$locFld][1]['location_type_id'] = $locType->id; } // get the relationship type id require_once 'CRM/Contact/DAO/RelationshipType.php'; $relType = new CRM_Contact_DAO_RelationshipType(); $relType->name_a_b = 'Employee of'; $relType->find(true); $relTypeId = $relType->id; // keep relationship params ready $relParams['relationship_type_id'] = $relTypeId . '_a_b'; $relParams['is_permission_a_b'] = 1; $relParams['is_active'] = 1; if (!$orgID) { // check if matching organization contact exists require_once 'CRM/Dedupe/Finder.php'; $dedupeParams = CRM_Dedupe_Finder::formatParams($behalfOrganization, 'Organization'); $dedupeParams['check_permission'] = false; $dupeIDs = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Organization', 'Strict'); // CRM-6243 says to pick the first org even if more than one match if (count($dupeIDs) >= 1) { $behalfOrganization['contact_id'] = $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']); } // create organization, add location $org = CRM_Contact_BAO_Contact::create($behalfOrganization); // create relationship $relParams['contact_check'][$org->id] = 1; $cid = array('contact' => $contactID); $relationship = CRM_Contact_BAO_Relationship::create($relParams, $cid); // take a note of new/updated organiation contact-id. $orgID = $org->id; // 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; // required for IPN $params['related_contact'] = $contactID; //make this employee of relationship as current //employer / employee relationship, CRM-3532 if ($isCurrentEmployer && $orgID != CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'employer_id')) { $isCurrentEmployer = false; } if (!$isCurrentEmployer && $orgID) { //build current employer params $currentEmpParams[$contactID] = $orgID; require_once 'CRM/Contact/BAO/Contact/Utils.php'; CRM_Contact_BAO_Contact_Utils::setCurrentEmployer($currentEmpParams); } // contribution / signup will be done using this // organization id. $contactID = $orgID; } }