function setUp() { parent::setUp(); // Create Group For Individual Contact Type $groupIndividual = array('title' => 'TestGroup For Indivi' . substr(sha1(rand()), 0, 5), 'extends' => array('Individual'), 'style' => 'Inline', 'is_active' => 1); $this->CustomGroupIndividual = $this->customGroupCreate($groupIndividual); $this->IndividualField = $this->customFieldCreate(array('custom_group_id' => $this->CustomGroupIndividual['id'])); // Create Group For Individual-Student Contact Sub Type $groupIndiStudent = array('title' => 'Student Test' . substr(sha1(rand()), 0, 5), 'extends' => array('Individual', array('Student')), 'style' => 'Inline', 'is_active' => 1); $this->CustomGroupIndiStudent = $this->customGroupCreate($groupIndiStudent); $this->IndiStudentField = $this->customFieldCreate(array('custom_group_id' => $this->CustomGroupIndiStudent['id'])); $params = array('first_name' => 'Mathev', 'last_name' => 'Adison', 'contact_type' => 'Individual'); $this->individual = $this->individualCreate($params); $params = array('first_name' => 'Steve', 'last_name' => 'Tosun', 'contact_type' => 'Individual', 'contact_sub_type' => 'Student'); $this->individualStudent = $this->individualCreate($params); $params = array('first_name' => 'Mark', 'last_name' => 'Dawson', 'contact_type' => 'Individual', 'contact_sub_type' => 'Parent'); $this->individualParent = $this->individualCreate($params); $params = array('organization_name' => 'Wellspring', 'contact_type' => 'Organization'); $this->organization = $this->organizationCreate($params); $params = array('organization_name' => 'SubUrban', 'contact_type' => 'Organization', 'contact_sub_type' => 'Sponsor'); $this->organizationSponsor = $this->organizationCreate($params); //refresh php cached variables CRM_Core_PseudoConstant::flush(); CRM_Core_BAO_CustomField::getTableColumnGroup($this->IndividualField['id'], True); CRM_Core_BAO_CustomField::getTableColumnGroup($this->IndiStudentField['id'], True); }
/** * File for the CiviCRM APIv3 group functions * * @package CiviCRM_APIv3 * @subpackage API_pcpteams * @copyright CiviCRM LLC (c) 2004-2014 */ function civicrm_api3_pcpteams_create($params) { // since we are allowing html input from the user // we also need to purify it, so lets clean it up // $params['pcp_title'] = $pcp['title']; // $params['pcp_contact_id'] = $pcp['contact_id']; $htmlFields = array('intro_text', 'page_text', 'title'); foreach ($htmlFields as $field) { if (!empty($params[$field])) { $params[$field] = CRM_Utils_String::purifyHTML($params[$field]); } } $entity_table = CRM_PCP_BAO_PCP::getPcpEntityTable($params['page_type']); $pcpBlock = new CRM_PCP_DAO_PCPBlock(); $pcpBlock->entity_table = $entity_table; $pcpBlock->entity_id = $params['page_id']; $pcpBlock->find(TRUE); $params['pcp_block_id'] = $pcpBlock->id; $params['goal_amount'] = CRM_Utils_Rule::cleanMoney($params['goal_amount']); // 1 -> waiting review // 2 -> active / approved (default for now) $params['status_id'] = CRM_Utils_Array::value('status_id', $params, 2); // active by default for now $params['is_active'] = CRM_Utils_Array::value('is_active', $params, 1); $pcp = CRM_Pcpteams_BAO_PCP::create($params, FALSE); //Custom Set $customFields = CRM_Core_BAO_CustomField::getFields('PCP', FALSE, FALSE, NULL, NULL, TRUE); $isCustomValueSet = FALSE; foreach ($customFields as $fieldID => $fieldValue) { list($tableName, $columnName, $cgId) = CRM_Core_BAO_CustomField::getTableColumnGroup($fieldID); if (!empty($params[$columnName]) || !empty($params["custom_{$fieldID}"])) { $isCustomValueSet = TRUE; //FIXME: to find out the custom value exists, set -1 as default now $params["custom_{$fieldID}_-1"] = !empty($params[$columnName]) ? $params[$columnName] : $params["custom_{$fieldID}"]; } } if ($isCustomValueSet) { $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params, $customFields, $pcp->id, 'PCP'); CRM_Core_BAO_CustomValueTable::store($params['custom'], 'civicrm_pcp', $pcp->id); } //end custom set $values = array(); @_civicrm_api3_object_to_array_unique_fields($pcp, $values[$pcp->id]); return civicrm_api3_create_success($values, $params, 'Pcpteams', 'create'); }
/** * A static function wrapper that deletes the various objects that are * connected to a file object (i.e. file, entityFile and customValue */ public static function deleteFileReferences($fileID, $entityID, $fieldID) { $fileDAO = new CRM_Core_DAO_File(); $fileDAO->id = $fileID; if (!$fileDAO->find(TRUE)) { CRM_Core_Error::fatal(); } // lets call a pre hook before the delete, so attachments hooks can get the info before things // disappear CRM_Utils_Hook::pre('delete', 'File', $fileID, $fileDAO); // get the table and column name list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($fieldID); $entityFileDAO = new CRM_Core_DAO_EntityFile(); $entityFileDAO->file_id = $fileID; $entityFileDAO->entity_id = $entityID; $entityFileDAO->entity_table = $tableName; if (!$entityFileDAO->find(TRUE)) { CRM_Core_Error::fatal(); } $entityFileDAO->delete(); $fileDAO->delete(); // also set the value to null of the table and column $query = "UPDATE {$tableName} SET {$columnName} = null WHERE {$columnName} = %1"; $params = array(1 => array($fileID, 'Integer')); CRM_Core_DAO::executeQuery($query, $params); }
/** * Run the page. * * This method is called after the page is created. It checks for the * type of action and executes that action. * * @return void */ public function run() { $template = CRM_Core_Smarty::singleton(); if ($this->_id && $this->_gid) { // first check that id is part of the limit group id, CRM-4822 $limitListingsGroupsID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $this->_gid, 'limit_listings_group_id'); $config = CRM_Core_Config::singleton(); if ($limitListingsGroupsID) { if (!CRM_Contact_BAO_GroupContact::isContactInGroup($this->_id, $limitListingsGroupsID)) { CRM_Utils_System::setTitle(ts('Profile View - Permission Denied')); return CRM_Core_Session::setStatus(ts('You do not have permission to view this contact record. Contact the site administrator if you need assistance.'), ts('Permission Denied'), 'error'); } } $session = CRM_Core_Session::singleton(); $userID = $session->get('userID'); $this->_isPermissionedChecksum = $allowPermission = FALSE; $permissionType = CRM_Core_Permission::VIEW; if (CRM_Core_Permission::check('administer users') || CRM_Core_Permission::check('view all contacts') || CRM_Contact_BAO_Contact_Permission::allow($this->_id)) { $allowPermission = TRUE; } if ($this->_id != $userID) { // do not allow edit for anon users in joomla frontend, CRM-4668, unless u have checksum CRM-5228 if ($config->userFrameworkFrontend) { $this->_isPermissionedChecksum = CRM_Contact_BAO_Contact_Permission::validateOnlyChecksum($this->_id, $this, FALSE); if (!$this->_isPermissionedChecksum) { $this->_isPermissionedChecksum = $allowPermission; } } else { $this->_isPermissionedChecksum = CRM_Contact_BAO_Contact_Permission::validateChecksumContact($this->_id, $this, FALSE); } } // CRM-10853 // Users with create or edit permission should be allowed to view their own profile if ($this->_id == $userID || $this->_isPermissionedChecksum) { if (!CRM_Core_Permission::check('profile view')) { if (CRM_Core_Permission::check('profile create') || CRM_Core_Permission::check('profile edit')) { $this->_skipPermission = TRUE; } } } // make sure we dont expose all fields based on permission $admin = FALSE; if (!$config->userFrameworkFrontend && $allowPermission || $this->_id == $userID || $this->_isPermissionedChecksum) { $admin = TRUE; } $values = array(); $fields = CRM_Core_BAO_UFGroup::getFields($this->_profileIds, FALSE, CRM_Core_Action::VIEW, NULL, NULL, FALSE, $this->_restrict, $this->_skipPermission, NULL, $permissionType); if ($this->_multiRecord & CRM_Core_Action::VIEW && $this->_recordId && !$this->_allFields) { CRM_Core_BAO_UFGroup::shiftMultiRecordFields($fields, $multiRecordFields); $fields = $multiRecordFields; } if ($this->_isContactActivityProfile && $this->_gid) { $errors = CRM_Profile_Form::validateContactActivityProfile($this->_activityId, $this->_id, $this->_gid); if (!empty($errors)) { CRM_Core_Error::fatal(array_pop($errors)); } } //reformat fields array foreach ($fields as $name => $field) { // also eliminate all formatting fields if (CRM_Utils_Array::value('field_type', $field) == 'Formatting') { unset($fields[$name]); } // make sure that there is enough permission to expose this field if (!$admin && $field['visibility'] == 'User and User Admin Only') { unset($fields[$name]); } } if ($this->_isContactActivityProfile) { $contactFields = $activityFields = array(); foreach ($fields as $fieldName => $field) { if (CRM_Utils_Array::value('field_type', $field) == 'Activity') { $activityFields[$fieldName] = $field; } else { $contactFields[$fieldName] = $field; } } CRM_Core_BAO_UFGroup::getValues($this->_id, $contactFields, $values); if ($this->_activityId) { CRM_Core_BAO_UFGroup::getValues(NULL, $activityFields, $values, TRUE, array(array('activity_id', '=', $this->_activityId, 0, 0))); } } else { $customWhereClause = NULL; if ($this->_multiRecord & CRM_Core_Action::VIEW && $this->_recordId) { if ($this->_allFields) { $copyFields = $fields; CRM_Core_BAO_UFGroup::shiftMultiRecordFields($copyFields, $multiRecordFields); $fieldKey = key($multiRecordFields); } else { $fieldKey = key($fields); } if ($fieldID = CRM_Core_BAO_CustomField::getKeyID($fieldKey)) { $tableColumnGroup = CRM_Core_BAO_CustomField::getTableColumnGroup($fieldID); $columnName = "{$tableColumnGroup[0]}.id"; $customWhereClause = $columnName . ' = ' . $this->_recordId; } } CRM_Core_BAO_UFGroup::getValues($this->_id, $fields, $values, TRUE, NULL, FALSE, $customWhereClause); } // $profileFields array can be used for customized display of field labels and values in Profile/View.tpl $profileFields = array(); $labels = array(); foreach ($fields as $name => $field) { //CRM-14338 // Create a unique, non-empty index for each field. $index = $field['title']; if ($index === '') { $index = ' '; } while (array_key_exists($index, $labels)) { $index .= ' '; } $labels[$index] = preg_replace('/\\s+|\\W+/', '_', $name); } foreach ($values as $title => $value) { $profileFields[$labels[$title]] = array('label' => $title, 'value' => $value); } $template->assign_by_ref('row', $values); $template->assign_by_ref('profileFields', $profileFields); } $name = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $this->_gid, 'name'); $this->assign('ufGroupName', $name); CRM_Utils_Hook::viewProfile($name); if (strtolower($name) == 'summary_overlay') { $template->assign('overlayProfile', TRUE); } if ($this->_multiRecord & CRM_Core_Action::VIEW && $this->_recordId && !$this->_allFields) { $fieldDetail = reset($fields); $fieldId = CRM_Core_BAO_CustomField::getKeyID($fieldDetail['name']); $customGroupDetails = CRM_Core_BAO_CustomGroup::getGroupTitles(array($fieldId)); $multiRecTitle = $customGroupDetails[$fieldId]['groupTitle']; } else { $title = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $this->_gid, 'title'); } //CRM-4131. $displayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_id, 'display_name'); if ($displayName) { $session = CRM_Core_Session::singleton(); $config = CRM_Core_Config::singleton(); if ($session->get('userID') && CRM_Core_Permission::check('access CiviCRM') && CRM_Contact_BAO_Contact_Permission::allow($session->get('userID'), CRM_Core_Permission::VIEW) && !$config->userFrameworkFrontend) { $contactViewUrl = CRM_Utils_System::url('civicrm/contact/view', "action=view&reset=1&cid={$this->_id}", TRUE); $this->assign('displayName', $displayName); $displayName = "<a href=\"{$contactViewUrl}\">{$displayName}</a>"; } $title .= ' - ' . $displayName; } $title = isset($multiRecTitle) ? ts('View %1 Record', array(1 => $multiRecTitle)) : $title; CRM_Utils_System::setTitle($title); // invoke the pagRun hook, CRM-3906 CRM_Utils_Hook::pageRun($this); return trim($template->fetch($this->getHookedTemplateFileName())); }
public function delete($useWhere = FALSE) { list($fileID, $entityID, $fieldID) = func_get_args(); // get the table and column name list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($fieldID); $entityFileDAO = new CRM_Core_DAO_EntityFile(); $entityFileDAO->file_id = $fileID; $entityFileDAO->entity_id = $entityID; $entityFileDAO->entity_table = $tableName; if ($entityFileDAO->find(TRUE)) { $entityFileDAO->delete(); } else { CRM_Core_Error::fatal(); } $fileDAO = new CRM_Core_DAO_File(); $fileDAO->id = $fileID; if ($fileDAO->find(TRUE)) { $fileDAO->delete(); } else { CRM_Core_Error::fatal(); } // also set the value to null of the table and column $query = "UPDATE {$tableName} SET {$columnName} = null WHERE {$columnName} = %1"; $params = array(1 => array($fileID, 'Integer')); CRM_Core_DAO::executeQuery($query, $params); }
function exportDAO($object, $objectName, $additional = null) { $dbFields =& $object->fields(); $xml = " <{$objectName}>"; foreach ($dbFields as $name => $dontCare) { // ignore all ids if ($name == 'id' || substr($name, -3, 3) == '_id') { continue; } if (isset($object->{$name}) && $object->{$name} !== null) { // hack for extends_entity_column_value if ($name == 'extends_entity_column_value') { if ($object->extends == 'Event' || $object->extends == 'Activity') { $key = $object->extends == 'Event' ? 'event_type' : 'activity_type'; $xml .= "\n <extends_entity_column_value_option_group>{$key}</extends_entity_column_value_option_group>"; $types = explode(CRM_Core_DAO::VALUE_SEPARATOR, substr($object->{$name}, 1, -1)); $value = array(); foreach ($types as $type) { $values[] = $this->_xml['optionValue']['map']["{$key}.{$type}"]; } $value = implode(',', $values); $xml .= "\n <extends_entity_column_value_option_value>{$value}</extends_entity_column_value_option_value>"; } else { echo "This extension: {$object->extends} is not yet handled"; exit; } } if ($name == 'field_name') { $value = $object->{$name}; if (substr($value, 0, 7) == 'custom_') { // hack for profile field_name $cfID = substr($value, 7); require_once 'CRM/Core/BAO/CustomField.php'; list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($cfID); $value = "custom.{$tableName}.{$columnName}"; } $xml .= "\n <{$name}>{$value}</{$name}>"; } else { $value = str_replace(CRM_Core_DAO::VALUE_SEPARATOR, ":;:;:;", $object->{$name}); $xml .= "\n <{$name}>{$value}</{$name}>"; } } } if ($additional) { $xml .= $additional; } $xml .= "\n </{$objectName}>\n"; return $xml; }
/** * Based on the provided two contact_ids and a set of tables, move the belongings of the * other contact to the main one - be it Location / CustomFields or Contact .. related info. * A superset of moveContactBelongings() function. * * @param int $mainId * Main contact with whom merge has to happen. * @param int $otherId * Duplicate contact which would be deleted after merge operation. * * @param $migrationInfo * * @return bool */ public static function moveAllBelongings($mainId, $otherId, $migrationInfo) { if (empty($migrationInfo)) { return FALSE; } $qfZeroBug = 'e8cddb72-a257-11dc-b9cc-0016d3330ee9'; $relTables = CRM_Dedupe_Merger::relTables(); $moveTables = $locBlocks = $tableOperations = array(); foreach ($migrationInfo as $key => $value) { if ($value == $qfZeroBug) { $value = '0'; } if ((in_array(substr($key, 5), CRM_Dedupe_Merger::getContactFields()) || substr($key, 0, 12) == 'move_custom_') && $value != NULL) { $submitted[substr($key, 5)] = $value; } elseif (substr($key, 0, 14) == 'move_location_' and $value != NULL) { $locField = explode('_', $key); $fieldName = $locField[2]; $fieldCount = $locField[3]; $operation = CRM_Utils_Array::value('operation', $migrationInfo['location'][$fieldName][$fieldCount]); // default operation is overwrite. if (!$operation) { $operation = 2; } $locBlocks[$fieldName][$fieldCount]['operation'] = $operation; $locBlocks[$fieldName][$fieldCount]['locTypeId'] = CRM_Utils_Array::value('locTypeId', $migrationInfo['location'][$fieldName][$fieldCount]); } elseif (substr($key, 0, 15) == 'move_rel_table_' and $value == '1') { $moveTables = array_merge($moveTables, $relTables[substr($key, 5)]['tables']); if (array_key_exists('operation', $migrationInfo)) { foreach ($relTables[substr($key, 5)]['tables'] as $table) { if (array_key_exists($key, $migrationInfo['operation'])) { $tableOperations[$table] = $migrationInfo['operation'][$key]; } } } } } // **** Do location related migration: if (!empty($locBlocks)) { $locComponent = array('email' => 'Email', 'phone' => 'Phone', 'im' => 'IM', 'openid' => 'OpenID', 'address' => 'Address'); $primaryBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($mainId, array('is_primary' => 1)); $billingBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($mainId, array('is_billing' => 1)); foreach ($locBlocks as $name => $block) { if (!is_array($block) || CRM_Utils_System::isNull($block)) { continue; } $daoName = 'CRM_Core_DAO_' . $locComponent[$name]; $primaryDAOId = array_key_exists($name, $primaryBlockIds) ? array_pop($primaryBlockIds[$name]) : NULL; $billingDAOId = array_key_exists($name, $billingBlockIds) ? array_pop($billingBlockIds[$name]) : NULL; foreach ($block as $blkCount => $values) { $locTypeId = CRM_Utils_Array::value('locTypeId', $values, 1); $operation = CRM_Utils_Array::value('operation', $values, 2); $otherBlockId = CRM_Utils_Array::value($blkCount, $migrationInfo['other_details']['loc_block_ids'][$name]); // keep 1-1 mapping for address - loc type. $idKey = $blkCount; if (array_key_exists($name, $locComponent)) { $idKey = $locTypeId; } if (isset($migrationInfo['main_details']['loc_block_ids'][$name])) { $mainBlockId = CRM_Utils_Array::value($idKey, $migrationInfo['main_details']['loc_block_ids'][$name]); } if (!$otherBlockId) { continue; } // for the block which belongs to other-contact, link the contact to main-contact $otherBlockDAO = new $daoName(); $otherBlockDAO->id = $otherBlockId; $otherBlockDAO->contact_id = $mainId; $otherBlockDAO->location_type_id = $locTypeId; // if main contact already has primary & billing, set the flags to 0. if ($primaryDAOId) { $otherBlockDAO->is_primary = 0; } if ($billingDAOId) { $otherBlockDAO->is_billing = 0; } // overwrite - need to delete block which belongs to main-contact. if (isset($mainBlockId) && $mainBlockId && $operation == 2) { $deleteDAO = new $daoName(); $deleteDAO->id = $mainBlockId; $deleteDAO->find(TRUE); // if we about to delete a primary / billing block, set the flags for new block // that we going to assign to main-contact if ($primaryDAOId && $primaryDAOId == $deleteDAO->id) { $otherBlockDAO->is_primary = 1; } if ($billingDAOId && $billingDAOId == $deleteDAO->id) { $otherBlockDAO->is_billing = 1; } $deleteDAO->delete(); $deleteDAO->free(); } $otherBlockDAO->update(); $otherBlockDAO->free(); } } } // **** Do tables related migrations if (!empty($moveTables)) { CRM_Dedupe_Merger::moveContactBelongings($mainId, $otherId, $moveTables, $tableOperations); unset($moveTables, $tableOperations); } // **** Do contact related migrations CRM_Dedupe_Merger::moveContactBelongings($mainId, $otherId); // FIXME: fix gender, prefix and postfix, so they're edible by createProfileContact() $names['gender'] = array('newName' => 'gender_id', 'groupName' => 'gender'); $names['individual_prefix'] = array('newName' => 'prefix_id', 'groupName' => 'individual_prefix'); $names['individual_suffix'] = array('newName' => 'suffix_id', 'groupName' => 'individual_suffix'); $names['communication_style'] = array('newName' => 'communication_style_id', 'groupName' => 'communication_style'); $names['addressee'] = array('newName' => 'addressee_id', 'groupName' => 'addressee'); $names['email_greeting'] = array('newName' => 'email_greeting_id', 'groupName' => 'email_greeting'); $names['postal_greeting'] = array('newName' => 'postal_greeting_id', 'groupName' => 'postal_greeting'); CRM_Core_OptionGroup::lookupValues($submitted, $names, TRUE); // fix custom fields so they're edible by createProfileContact() static $treeCache = array(); if (!array_key_exists($migrationInfo['main_details']['contact_type'], $treeCache)) { $treeCache[$migrationInfo['main_details']['contact_type']] = CRM_Core_BAO_CustomGroup::getTree($migrationInfo['main_details']['contact_type'], CRM_Core_DAO::$_nullObject, NULL, -1); } $cgTree =& $treeCache[$migrationInfo['main_details']['contact_type']]; $cFields = array(); foreach ($cgTree as $key => $group) { if (!isset($group['fields'])) { continue; } foreach ($group['fields'] as $fid => $field) { $cFields[$fid]['attributes'] = $field; } } if (!isset($submitted)) { $submitted = array(); } foreach ($submitted as $key => $value) { if (substr($key, 0, 7) == 'custom_') { $fid = (int) substr($key, 7); if (empty($cFields[$fid])) { continue; } $htmlType = $cFields[$fid]['attributes']['html_type']; switch ($htmlType) { case 'File': $customFiles[] = $fid; unset($submitted["custom_{$fid}"]); break; case 'Select Country': case 'Select State/Province': $submitted[$key] = CRM_Core_BAO_CustomField::getDisplayValue($value, $fid, $cFields); break; case 'CheckBox': case 'AdvMulti-Select': case 'Multi-Select': case 'Multi-Select Country': case 'Multi-Select State/Province': // Merge values from both contacts for multivalue fields, CRM-4385 // get the existing custom values from db. $customParams = array('entityID' => $mainId, $key => TRUE); $customfieldValues = CRM_Core_BAO_CustomValueTable::getValues($customParams); if (!empty($customfieldValues[$key])) { $existingValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $customfieldValues[$key]); if (is_array($existingValue) && !empty($existingValue)) { $mergeValue = $submmtedCustomValue = array(); if ($value) { $submmtedCustomValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); } //hack to remove null and duplicate values from array. foreach (array_merge($submmtedCustomValue, $existingValue) as $k => $v) { if ($v != '' && !in_array($v, $mergeValue)) { $mergeValue[] = $v; } } //keep state and country as array format. //for checkbox and m-select format w/ VALUE_SEPARATOR if (in_array($htmlType, array('CheckBox', 'Multi-Select', 'AdvMulti-Select'))) { $submitted[$key] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $mergeValue) . CRM_Core_DAO::VALUE_SEPARATOR; } else { $submitted[$key] = $mergeValue; } } } elseif (in_array($htmlType, array('Multi-Select Country', 'Multi-Select State/Province'))) { //we require submitted values should be in array format if ($value) { $mergeValueArray = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); //hack to remove null values from array. $mergeValue = array(); foreach ($mergeValueArray as $k => $v) { if ($v != '') { $mergeValue[] = $v; } } $submitted[$key] = $mergeValue; } } break; default: break; } } } // **** Do file custom fields related migrations // FIXME: move this someplace else (one of the BAOs) after discussing // where to, and whether CRM_Core_BAO_File::deleteFileReferences() shouldn't actually, // like, delete a file... if (!isset($customFiles)) { $customFiles = array(); } foreach ($customFiles as $customId) { list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($customId); // get the contact_id -> file_id mapping $fileIds = array(); $sql = "SELECT entity_id, {$columnName} AS file_id FROM {$tableName} WHERE entity_id IN ({$mainId}, {$otherId})"; $dao = CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray); while ($dao->fetch()) { $fileIds[$dao->entity_id] = $dao->file_id; } $dao->free(); // delete the main contact's file if (!empty($fileIds[$mainId])) { CRM_Core_BAO_File::deleteFileReferences($fileIds[$mainId], $mainId, $customId); } // move the other contact's file to main contact //NYSS need to INSERT or UPDATE depending on whether main contact has an existing record if (CRM_Core_DAO::singleValueQuery("SELECT id FROM {$tableName} WHERE entity_id = {$mainId}")) { $sql = "UPDATE {$tableName} SET {$columnName} = {$fileIds[$otherId]} WHERE entity_id = {$mainId}"; } else { $sql = "INSERT INTO {$tableName} ( entity_id, {$columnName} ) VALUES ( {$mainId}, {$fileIds[$otherId]} )"; } CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray); if (CRM_Core_DAO::singleValueQuery("\n SELECT id\n FROM civicrm_entity_file\n WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$otherId]}")) { $sql = "\n UPDATE civicrm_entity_file\n SET entity_id = {$mainId}\n WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$otherId]}"; } else { $sql = "\n INSERT INTO civicrm_entity_file ( entity_table, entity_id, file_id )\n VALUES ( '{$tableName}', {$mainId}, {$fileIds[$otherId]} )"; } CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray); } // move view only custom fields CRM-5362 $viewOnlyCustomFields = array(); foreach ($submitted as $key => $value) { $fid = (int) substr($key, 7); if (array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view'])) { $viewOnlyCustomFields[$key] = $value; } } // special case to set values for view only, CRM-5362 if (!empty($viewOnlyCustomFields)) { $viewOnlyCustomFields['entityID'] = $mainId; CRM_Core_BAO_CustomValueTable::setValues($viewOnlyCustomFields); } // **** Delete other contact & update prev-next caching $otherParams = array('contact_id' => $otherId, 'id' => $otherId, 'version' => 3); if (CRM_Core_Permission::check('merge duplicate contacts') && CRM_Core_Permission::check('delete contacts')) { // if ext id is submitted then set it null for contact to be deleted if (!empty($submitted['external_identifier'])) { $query = "UPDATE civicrm_contact SET external_identifier = null WHERE id = {$otherId}"; CRM_Core_DAO::executeQuery($query); } civicrm_api('contact', 'delete', $otherParams); CRM_Core_BAO_PrevNextCache::deleteItem($otherId); } // FIXME: else part /* else { */ /* CRM_Core_Session::setStatus( ts('Do not have sufficient permission to delete duplicate contact.') ); */ /* } */ // CRM-15681 merge sub_types if ($other_sub_types = CRM_Utils_array::value('contact_sub_type', $migrationInfo['other_details'])) { if ($main_sub_types = CRM_Utils_array::value('contact_sub_type', $migrationInfo['main_details'])) { $submitted['contact_sub_type'] = array_unique(array_merge($main_sub_types, $other_sub_types)); } else { $submitted['contact_sub_type'] = $other_sub_types; } } // **** Update contact related info for the main contact if (!empty($submitted)) { $submitted['contact_id'] = $mainId; //update current employer field if ($currentEmloyerId = CRM_Utils_Array::value('current_employer_id', $submitted)) { if (!CRM_Utils_System::isNull($currentEmloyerId)) { $submitted['current_employer'] = $submitted['current_employer_id']; } else { $submitted['current_employer'] = ''; } unset($submitted['current_employer_id']); } //CRM-14312 include prefix/suffix from mainId if not overridden for proper construction of display/sort name if (!isset($submitted['prefix_id']) && !empty($migrationInfo['main_details']['prefix_id'])) { $submitted['prefix_id'] = $migrationInfo['main_details']['prefix_id']; } if (!isset($submitted['suffix_id']) && !empty($migrationInfo['main_details']['suffix_id'])) { $submitted['suffix_id'] = $migrationInfo['main_details']['suffix_id']; } CRM_Contact_BAO_Contact::createProfileContact($submitted, CRM_Core_DAO::$_nullArray, $mainId); unset($submitted); } CRM_Utils_Hook::post('merge', 'Contact', $mainId, CRM_Core_DAO::$_nullObject); return TRUE; }
public function delete($fileID, $entityID, $fieldID) { // get the table and column name require_once 'CRM/Core/BAO/CustomField.php'; list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($fieldID); require_once "CRM/Core/DAO/EntityFile.php"; $entityFileDAO =& new CRM_Core_DAO_EntityFile(); $entityFileDAO->file_id = $fileID; $entityFileDAO->entity_id = $entityID; $entityFileDAO->entity_table = $tableName; if ($entityFileDAO->find(true)) { $entityFileDAO->delete(); } else { CRM_Core_Error::fatal(); } require_once "CRM/Core/DAO/File.php"; $fileDAO =& new CRM_Core_DAO_File(); $fileDAO->id = $fileID; if ($fileDAO->find(true)) { $fileDAO->delete(); } else { CRM_Core_Error::fatal(); } // also set the value to null of the table and column $query = "UPDATE {$tableName} SET {$columnName} = null WHERE {$columnName} = %1"; $params = array(1 => array($fileID, 'Integer')); CRM_Core_DAO::executeQuery($query, $params); }
/** * Create custom field. * * @param array $params * (custom_group_id) is required. * @return array */ public function customFieldCreate($params) { $params = array_merge(array('label' => 'Custom Field', 'data_type' => 'String', 'html_type' => 'Text', 'is_searchable' => 1, 'is_active' => 1, 'default_value' => 'defaultValue'), $params); $result = $this->callAPISuccess('custom_field', 'create', $params); // these 2 functions are called with force to flush static caches CRM_Core_BAO_CustomField::getTableColumnGroup($result['id'], 1); CRM_Core_Component::getEnabledComponents(1); return $result; }
/** * @param string $objectName * Business-entity/xml-tag name. * @param CRM_Core_DAO $object * @param $mappedFields * * @return array */ public function exportDAO($objectName, $object, $mappedFields) { $dbFields =& $object->fields(); // Filter the list of keys and values so that we only export interesting stuff $keyValues = array(); foreach ($dbFields as $name => $dontCare) { // ignore all ids if ($name == 'id' || substr($name, -3, 3) == '_id') { continue; } if (isset($object->{$name}) && $object->{$name} !== NULL) { // hack for extends_entity_column_value if ($name == 'extends_entity_column_value') { if (in_array($object->extends, array('Event', 'Activity', 'Relationship', 'Individual', 'Organization', 'Household', 'Case'))) { if ($object->extends == 'Event') { $key = 'event_type'; } elseif ($object->extends == 'Activity') { $key = 'activity_type'; } elseif ($object->extends == 'Relationship') { $key = 'relationship_type'; } elseif ($object->extends == 'Case') { $key = 'case_type'; } $types = explode(CRM_Core_DAO::VALUE_SEPARATOR, substr($object->{$name}, 1, -1)); $values = array(); if (in_array($object->extends, array('Individual', 'Organization', 'Household'))) { $key = 'contact_type'; $values = $types; } else { foreach ($types as $type) { if (in_array($key, array('activity_type', 'event_type', 'case_type'))) { $ogID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $key, 'id', 'name'); $ovParams = array('option_group_id' => $ogID, 'value' => $type); CRM_Core_BAO_OptionValue::retrieve($ovParams, $oValue); $values[] = $oValue['name']; } else { $relTypeName = CRM_Core_DAO::getFieldValue('CRM_Contact_BAO_RelationshipType', $type, 'name_a_b', 'id'); $values[] = $relTypeName; } } } $keyValues['extends_entity_column_value_option_group'] = $key; $value = implode(',', $values); $object->extends_entity_column_value = $value; } else { echo "This extension: {$object->extends} is not yet handled"; exit; } } $value = $object->{$name}; if ($name == 'field_name') { // hack for profile field_name if (substr($value, 0, 7) == 'custom_') { $cfID = substr($value, 7); list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($cfID); $value = "custom.{$tableName}.{$columnName}"; } } $keyValues[$name] = $value; } } $keyValues += $this->computeMappedFields($mappedFields, $object); return $keyValues; }
/** * Attachment parsing helper. * * @param array $params * * @return array * (0 => int $id, 1 => array $file, 2 => array $entityFile, 3 => string $name, 4 => string $content, * 5 => string $moveFile, 6 => $isTrusted, 7 => bool $returnContent) * - array $file: whitelisted fields that can pass through directly to civicrm_file * - array $entityFile: whitelisted fields that can pass through directly to civicrm_entity_file * - string $name: the printable name * - string $moveFile: the full path to a local file whose content should be loaded * - bool $isTrusted: whether we trust the requester to do sketchy things (like moving files or reassigning entities) * - bool $returnContent: whether we are expected to return the full content of the file * @throws API_Exception validation errors */ function _civicrm_api3_attachment_parse_params($params) { $id = CRM_Utils_Array::value('id', $params, NULL); if ($id && !is_numeric($id)) { throw new API_Exception("Malformed id"); } $file = array(); foreach (array('mime_type', 'description', 'upload_date') as $field) { if (array_key_exists($field, $params)) { $file[$field] = $params[$field]; } } $entityFile = array(); foreach (array('entity_table', 'entity_id') as $field) { if (array_key_exists($field, $params)) { $entityFile[$field] = $params[$field]; } } if (empty($params['entity_table']) && isset($params['field_name'])) { $tableInfo = CRM_Core_BAO_CustomField::getTableColumnGroup(intval(str_replace('custom_', '', $params['field_name']))); $entityFile['entity_table'] = $tableInfo[0]; } $name = NULL; if (array_key_exists('name', $params)) { if ($params['name'] != basename($params['name']) || preg_match(':[/\\\\]:', $params['name'])) { throw new API_Exception('Malformed name'); } $name = $params['name']; } $content = NULL; if (isset($params['content'])) { $content = $params['content']; } $moveFile = NULL; if (isset($params['options']['move-file'])) { $moveFile = $params['options']['move-file']; } elseif (isset($params['options.move-file'])) { $moveFile = $params['options.move-file']; } $isTrusted = empty($params['check_permissions']); $returns = isset($params['return']) ? $params['return'] : array(); $returns = is_array($returns) ? $returns : array($returns); $returnContent = in_array('content', $returns); return array($id, $file, $entityFile, $name, $content, $moveFile, $isTrusted, $returnContent); }
public function postProcess() { $formValues = $this->exportValues(); // user can't choose to move cases without activities (CRM-3778) if ($formValues['move_rel_table_cases'] == '1' && array_key_exists('move_rel_table_activities', $formValues)) { $formValues['move_rel_table_activities'] = '1'; } // reset all selected contact ids from session // when we came from search context, CRM-3526 $session =& CRM_Core_Session::singleton(); if ($session->get('selectedSearchContactIds')) { $session->resetScope('selectedSearchContactIds'); } $relTables =& CRM_Dedupe_Merger::relTables(); $moveTables = $locBlocks = array(); foreach ($formValues as $key => $value) { if ($value == $this->_qfZeroBug) { $value = '0'; } if ((in_array(substr($key, 5), CRM_Dedupe_Merger::$validFields) or substr($key, 0, 12) == 'move_custom_') and $value != null) { $submitted[substr($key, 5)] = $value; } elseif (substr($key, 0, 14) == 'move_location_' and $value != null) { $locField = explode('_', $key); $fieldName = $locField[2]; $fieldCount = $locField[3]; $operation = CRM_Utils_Array::value('operation', $formValues['location'][$fieldName][$fieldCount]); // default operation is overwrite. if (!$operation) { $operation = 2; } $locBlocks[$fieldName][$fieldCount]['operation'] = $operation; $locBlocks[$fieldName][$fieldCount]['locTypeId'] = CRM_Utils_Array::value('locTypeId', $formValues['location'][$fieldName][$fieldCount]); } elseif (substr($key, 0, 15) == 'move_rel_table_' and $value == '1') { $moveTables = array_merge($moveTables, $relTables[substr($key, 5)]['tables']); } } // process location blocks. if (!empty($locBlocks)) { $locComponent = array('email' => 'Email', 'phone' => 'Phone', 'im' => 'IM', 'openid' => 'OpenID', 'address' => 'Address'); require_once 'CRM/Contact/BAO/Contact.php'; $primaryBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($this->_cid, array('is_primary' => 1)); $billingBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($this->_cid, array('is_billing' => 1)); foreach ($locBlocks as $name => $block) { if (!is_array($block) || CRM_Utils_System::isNull($block)) { continue; } $daoName = $locComponent[$name]; $primaryDAOId = array_key_exists($name, $primaryBlockIds) ? array_pop($primaryBlockIds[$name]) : null; $billingDAOId = array_key_exists($name, $billingBlockIds) ? array_pop($billingBlockIds[$name]) : null; foreach ($block as $blkCount => $values) { $locTypeId = CRM_Utils_Array::value('locTypeId', $values, 1); $operation = CRM_Utils_Array::value('operation', $values, 2); $updateBlockId = CRM_Utils_Array::value($blkCount, $this->_locBlockIds['other'][$name]); // keep 1-1 mapping for address - loc type. $idKey = $blkCount; if ($name == 'address') { $idKey = $locTypeId; } $deleteBlockId = CRM_Utils_Array::value($idKey, $this->_locBlockIds['main'][$name]); if (!$updateBlockId) { continue; } require_once "CRM/Core/DAO/{$daoName}.php"; eval("\$updateDAO =& new CRM_Core_DAO_{$daoName}();"); $updateDAO->id = $updateBlockId; $updateDAO->contact_id = $this->_cid; $updateDAO->location_type_id = $locTypeId; // contact having primary block. if ($primaryDAOId) { $updateDAO->is_primary = 0; } if ($billingDAOId) { $updateDAO->is_billing = 0; } // overwrite - need to delete block from main contact. if ($deleteBlockId && $operation == 2) { eval("\$deleteDAO =& new CRM_Core_DAO_{$daoName}();"); $deleteDAO->id = $deleteBlockId; $deleteDAO->find(true); // since we overwrite primary block. if ($primaryDAOId && $primaryDAOId == $deleteDAO->id) { $updateDAO->is_primary = 1; } if ($billingDAOId && $billingDAOId == $deleteDAO->id) { $updateDAO->is_billing = 1; } $deleteDAO->delete(); $deleteDAO->free(); } $updateDAO->update(); $updateDAO->free(); } } } // FIXME: fix gender, prefix and postfix, so they're edible by createProfileContact() $names['gender'] = array('newName' => 'gender_id', 'groupName' => 'gender'); $names['individual_prefix'] = array('newName' => 'prefix_id', 'groupName' => 'individual_prefix'); $names['individual_suffix'] = array('newName' => 'suffix_id', 'groupName' => 'individual_suffix'); $names['addressee'] = array('newName' => 'addressee_id', 'groupName' => 'addressee'); $names['email_greeting'] = array('newName' => 'email_greeting_id', 'groupName' => 'email_greeting'); $names['postal_greeting'] = array('newName' => 'postal_greeting_id', 'groupName' => 'postal_greeting'); CRM_Core_OptionGroup::lookupValues($submitted, $names, true); // FIXME: fix custom fields so they're edible by createProfileContact() $cgTree =& CRM_Core_BAO_CustomGroup::getTree($this->_contactType, $this, null, -1); foreach ($cgTree as $key => $group) { if (!isset($group['fields'])) { continue; } foreach ($group['fields'] as $fid => $field) { $cFields[$fid]['attributes'] = $field; } } if (!isset($submitted)) { $submitted = array(); } foreach ($submitted as $key => $value) { if (substr($key, 0, 7) == 'custom_') { $fid = (int) substr($key, 7); $htmlType = $cFields[$fid]['attributes']['html_type']; switch ($htmlType) { case 'File': $customFiles[] = $fid; unset($submitted["custom_{$fid}"]); break; case 'Select Country': case 'Select State/Province': $submitted[$key] = CRM_Core_BAO_CustomField::getDisplayValue($value, $fid, $cFields); break; case 'CheckBox': case 'AdvMulti-Select': case 'Multi-Select': case 'Multi-Select Country': case 'Multi-Select State/Province': // Merge values from both contacts for multivalue fields, CRM-4385 // get the existing custom values from db. require_once 'CRM/Core/BAO/CustomValueTable.php'; $customParams = array('entityID' => $this->_cid, $key => true); $customfieldValues = CRM_Core_BAO_CustomValueTable::getValues($customParams); if (CRM_Utils_array::value($key, $customfieldValues)) { $existingValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $customfieldValues[$key]); if (is_array($existingValue) && !empty($existingValue)) { $mergeValue = $submmtedCustomValue = array(); if ($value) { $submmtedCustomValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); } //hack to remove null and duplicate values from array. foreach (array_merge($submmtedCustomValue, $existingValue) as $k => $v) { if ($v != '' && !in_array($v, $mergeValue)) { $mergeValue[] = $v; } } //keep state and country as array format. //for checkbox and m-select format w/ VALUE_SEPERATOR if (in_array($htmlType, array('CheckBox', 'Multi-Select', 'AdvMulti-Select'))) { $submitted[$key] = CRM_Core_BAO_CustomOption::VALUE_SEPERATOR . implode(CRM_Core_BAO_CustomOption::VALUE_SEPERATOR, $mergeValue) . CRM_Core_BAO_CustomOption::VALUE_SEPERATOR; } else { $submitted[$key] = $mergeValue; } } } else { if (in_array($htmlType, array('Multi-Select Country', 'Multi-Select State/Province'))) { //we require submitted values should be in array format if ($value) { $mergeValueArray = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); //hack to remove null values from array. $mergeValue = array(); foreach ($mergeValueArray as $k => $v) { if ($v != '') { $mergeValue[] = $v; } } $submitted[$key] = $mergeValue; } } } break; default: break; } } } // handle the related tables if (isset($moveTables)) { CRM_Dedupe_Merger::moveContactBelongings($this->_cid, $this->_oid, $moveTables); } // move file custom fields // FIXME: move this someplace else (one of the BAOs) after discussing // where to, and whether CRM_Core_BAO_File::delete() shouldn't actually, // like, delete a file... require_once 'CRM/Core/BAO/File.php'; require_once 'CRM/Core/DAO/CustomField.php'; require_once 'CRM/Core/DAO/CustomGroup.php'; require_once 'CRM/Core/DAO/EntityFile.php'; require_once 'CRM/Core/Config.php'; if (!isset($customFiles)) { $customFiles = array(); } foreach ($customFiles as $customId) { list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($customId); // get the contact_id -> file_id mapping $fileIds = array(); $sql = "SELECT entity_id, {$columnName} AS file_id FROM {$tableName} WHERE entity_id IN ({$this->_cid}, {$this->_oid})"; $dao =& CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray); while ($dao->fetch()) { $fileIds[$dao->entity_id] = $dao->file_id; } $dao->free(); // delete the main contact's file CRM_Core_BAO_File::delete($fileIds[$this->_cid], $this->_cid, $customId); // move the other contact's file to main contact $sql = "UPDATE {$tableName} SET {$columnName} = {$fileIds[$this->_oid]} WHERE entity_id = {$this->_cid}"; CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray); $sql = "UPDATE civicrm_entity_file SET entity_id = {$this->_cid} WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$this->_oid]}"; CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray); } // move other's belongings and delete the other contact CRM_Dedupe_Merger::moveContactBelongings($this->_cid, $this->_oid); $otherParams = array('contact_id' => $this->_oid); if (CRM_Core_Permission::check('delete contacts')) { civicrm_contact_delete($otherParams); } else { CRM_Core_Session::setStatus(ts('Do not have sufficient permission to delete duplicate contact.')); } if (isset($submitted)) { $submitted['contact_id'] = $this->_cid; CRM_Contact_BAO_Contact::createProfileContact($submitted, CRM_Core_DAO::$_nullArray, $this->_cid); } CRM_Core_Session::setStatus(ts('The contacts have been merged.')); $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_cid}"); CRM_Utils_System::redirect($url); }
/** * Function to create custom field * * @param array $params (custom_group_id) is required * @return array|int * @internal param string $name name of custom field * @internal param int $apiversion API version to use */ function customFieldCreate($params) { $params = array_merge(array('label' => 'Custom Field', 'data_type' => 'String', 'html_type' => 'Text', 'is_searchable' => 1, 'is_active' => 1, 'default_value' => 'defaultValue'), $params); $result = $this->callAPISuccess('custom_field', 'create', $params); if ($result['is_error'] == 0 && isset($result['id'])) { CRM_Core_BAO_CustomField::getTableColumnGroup($result['id'], 1); // force reset of enabled components to help grab custom fields CRM_Core_Component::getEnabledComponents(1); return $result; } }
/** * Based on the provided two contact_ids and a set of tables, move the belongings of the * other contact to the main one - be it Location / CustomFields or Contact .. related info. * A superset of moveContactBelongings() function. * * @param int $mainId * Main contact with whom merge has to happen. * @param int $otherId * Duplicate contact which would be deleted after merge operation. * * @param $migrationInfo * * @param bool $checkPermissions * Respect logged in user permissions. * * @return bool */ public static function moveAllBelongings($mainId, $otherId, $migrationInfo, $checkPermissions = TRUE) { if (empty($migrationInfo)) { return FALSE; } $qfZeroBug = 'e8cddb72-a257-11dc-b9cc-0016d3330ee9'; $relTables = CRM_Dedupe_Merger::relTables(); $moveTables = $locationMigrationInfo = $tableOperations = array(); foreach ($migrationInfo as $key => $value) { if ($value == $qfZeroBug) { $value = '0'; } if ((in_array(substr($key, 5), CRM_Dedupe_Merger::getContactFields()) || substr($key, 0, 12) == 'move_custom_') && $value != NULL) { $submitted[substr($key, 5)] = $value; } elseif (substr($key, 0, 14) == 'move_location_' and $value != NULL) { $locationMigrationInfo[$key] = $value; } elseif (substr($key, 0, 15) == 'move_rel_table_' and $value == '1') { $moveTables = array_merge($moveTables, $relTables[substr($key, 5)]['tables']); if (array_key_exists('operation', $migrationInfo)) { foreach ($relTables[substr($key, 5)]['tables'] as $table) { if (array_key_exists($key, $migrationInfo['operation'])) { $tableOperations[$table] = $migrationInfo['operation'][$key]; } } } } } self::mergeLocations($mainId, $otherId, $locationMigrationInfo, $migrationInfo); // **** Do tables related migrations if (!empty($moveTables)) { CRM_Dedupe_Merger::moveContactBelongings($mainId, $otherId, $moveTables, $tableOperations); unset($moveTables, $tableOperations); } // **** Do contact related migrations CRM_Dedupe_Merger::moveContactBelongings($mainId, $otherId); // FIXME: fix gender, prefix and postfix, so they're edible by createProfileContact() $names['gender'] = array('newName' => 'gender_id', 'groupName' => 'gender'); $names['individual_prefix'] = array('newName' => 'prefix_id', 'groupName' => 'individual_prefix'); $names['individual_suffix'] = array('newName' => 'suffix_id', 'groupName' => 'individual_suffix'); $names['communication_style'] = array('newName' => 'communication_style_id', 'groupName' => 'communication_style'); $names['addressee'] = array('newName' => 'addressee_id', 'groupName' => 'addressee'); $names['email_greeting'] = array('newName' => 'email_greeting_id', 'groupName' => 'email_greeting'); $names['postal_greeting'] = array('newName' => 'postal_greeting_id', 'groupName' => 'postal_greeting'); CRM_Core_OptionGroup::lookupValues($submitted, $names, TRUE); // fix custom fields so they're edible by createProfileContact() static $treeCache = array(); if (!array_key_exists($migrationInfo['main_details']['contact_type'], $treeCache)) { $treeCache[$migrationInfo['main_details']['contact_type']] = CRM_Core_BAO_CustomGroup::getTree($migrationInfo['main_details']['contact_type'], CRM_Core_DAO::$_nullObject, NULL, -1); } $cgTree =& $treeCache[$migrationInfo['main_details']['contact_type']]; $cFields = array(); foreach ($cgTree as $key => $group) { if (!isset($group['fields'])) { continue; } foreach ($group['fields'] as $fid => $field) { $cFields[$fid]['attributes'] = $field; } } if (!isset($submitted)) { $submitted = array(); } foreach ($submitted as $key => $value) { if (substr($key, 0, 7) == 'custom_') { $fid = (int) substr($key, 7); if (empty($cFields[$fid])) { continue; } $htmlType = $cFields[$fid]['attributes']['html_type']; switch ($htmlType) { case 'File': $customFiles[] = $fid; unset($submitted["custom_{$fid}"]); break; case 'Select Country': case 'Select State/Province': $submitted[$key] = CRM_Core_BAO_CustomField::displayValue($value, $fid); break; case 'Select Date': if ($cFields[$fid]['attributes']['is_view']) { $submitted[$key] = date('YmdHis', strtotime($submitted[$key])); } break; case 'CheckBox': case 'AdvMulti-Select': case 'Multi-Select': case 'Multi-Select Country': case 'Multi-Select State/Province': // Merge values from both contacts for multivalue fields, CRM-4385 // get the existing custom values from db. $customParams = array('entityID' => $mainId, $key => TRUE); $customfieldValues = CRM_Core_BAO_CustomValueTable::getValues($customParams); if (!empty($customfieldValues[$key])) { $existingValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $customfieldValues[$key]); if (is_array($existingValue) && !empty($existingValue)) { $mergeValue = $submmtedCustomValue = array(); if ($value == 'null') { // CRM-19074 if someone has deliberately chosen to overwrite with 'null', respect it. $submitted[$key] = $value; } else { if ($value) { $submmtedCustomValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); } //hack to remove null and duplicate values from array. foreach (array_merge($submmtedCustomValue, $existingValue) as $k => $v) { if ($v != '' && !in_array($v, $mergeValue)) { $mergeValue[] = $v; } } //keep state and country as array format. //for checkbox and m-select format w/ VALUE_SEPARATOR if (in_array($htmlType, array('CheckBox', 'Multi-Select', 'AdvMulti-Select'))) { $submitted[$key] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $mergeValue) . CRM_Core_DAO::VALUE_SEPARATOR; } else { $submitted[$key] = $mergeValue; } } } } elseif (in_array($htmlType, array('Multi-Select Country', 'Multi-Select State/Province'))) { //we require submitted values should be in array format if ($value) { $mergeValueArray = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); //hack to remove null values from array. $mergeValue = array(); foreach ($mergeValueArray as $k => $v) { if ($v != '') { $mergeValue[] = $v; } } $submitted[$key] = $mergeValue; } } break; default: break; } } } // **** Do file custom fields related migrations // FIXME: move this someplace else (one of the BAOs) after discussing // where to, and whether CRM_Core_BAO_File::deleteFileReferences() shouldn't actually, // like, delete a file... if (!isset($customFiles)) { $customFiles = array(); } foreach ($customFiles as $customId) { list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($customId); // get the contact_id -> file_id mapping $fileIds = array(); $sql = "SELECT entity_id, {$columnName} AS file_id FROM {$tableName} WHERE entity_id IN ({$mainId}, {$otherId})"; $dao = CRM_Core_DAO::executeQuery($sql); while ($dao->fetch()) { $fileIds[$dao->entity_id] = $dao->file_id; } $dao->free(); // delete the main contact's file if (!empty($fileIds[$mainId])) { CRM_Core_BAO_File::deleteFileReferences($fileIds[$mainId], $mainId, $customId); } // move the other contact's file to main contact //NYSS need to INSERT or UPDATE depending on whether main contact has an existing record if (CRM_Core_DAO::singleValueQuery("SELECT id FROM {$tableName} WHERE entity_id = {$mainId}")) { $sql = "UPDATE {$tableName} SET {$columnName} = {$fileIds[$otherId]} WHERE entity_id = {$mainId}"; } else { $sql = "INSERT INTO {$tableName} ( entity_id, {$columnName} ) VALUES ( {$mainId}, {$fileIds[$otherId]} )"; } CRM_Core_DAO::executeQuery($sql); if (CRM_Core_DAO::singleValueQuery("\n SELECT id\n FROM civicrm_entity_file\n WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$otherId]}")) { $sql = "\n UPDATE civicrm_entity_file\n SET entity_id = {$mainId}\n WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$otherId]}"; } else { $sql = "\n INSERT INTO civicrm_entity_file ( entity_table, entity_id, file_id )\n VALUES ( '{$tableName}', {$mainId}, {$fileIds[$otherId]} )"; } CRM_Core_DAO::executeQuery($sql); } // move view only custom fields CRM-5362 $viewOnlyCustomFields = array(); foreach ($submitted as $key => $value) { $fid = (int) substr($key, 7); if (array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view'])) { $viewOnlyCustomFields[$key] = $value; } } // special case to set values for view only, CRM-5362 if (!empty($viewOnlyCustomFields)) { $viewOnlyCustomFields['entityID'] = $mainId; CRM_Core_BAO_CustomValueTable::setValues($viewOnlyCustomFields); } if (!$checkPermissions || CRM_Core_Permission::check('merge duplicate contacts') && CRM_Core_Permission::check('delete contacts')) { // if ext id is submitted then set it null for contact to be deleted if (!empty($submitted['external_identifier'])) { $query = "UPDATE civicrm_contact SET external_identifier = null WHERE id = {$otherId}"; CRM_Core_DAO::executeQuery($query); } civicrm_api3('contact', 'delete', array('id' => $otherId)); } // CRM-15681 merge sub_types if ($other_sub_types = CRM_Utils_Array::value('contact_sub_type', $migrationInfo['other_details'])) { if ($main_sub_types = CRM_Utils_Array::value('contact_sub_type', $migrationInfo['main_details'])) { $submitted['contact_sub_type'] = array_unique(array_merge($main_sub_types, $other_sub_types)); } else { $submitted['contact_sub_type'] = $other_sub_types; } } // **** Update contact related info for the main contact if (!empty($submitted)) { $submitted['contact_id'] = $mainId; //update current employer field if ($currentEmloyerId = CRM_Utils_Array::value('current_employer_id', $submitted)) { if (!CRM_Utils_System::isNull($currentEmloyerId)) { $submitted['current_employer'] = $submitted['current_employer_id']; } else { $submitted['current_employer'] = ''; } unset($submitted['current_employer_id']); } //CRM-14312 include prefix/suffix from mainId if not overridden for proper construction of display/sort name if (!isset($submitted['prefix_id']) && !empty($migrationInfo['main_details']['prefix_id'])) { $submitted['prefix_id'] = $migrationInfo['main_details']['prefix_id']; } if (!isset($submitted['suffix_id']) && !empty($migrationInfo['main_details']['suffix_id'])) { $submitted['suffix_id'] = $migrationInfo['main_details']['suffix_id']; } CRM_Contact_BAO_Contact::createProfileContact($submitted, CRM_Core_DAO::$_nullArray, $mainId); } CRM_Utils_Hook::post('merge', 'Contact', $mainId, CRM_Core_DAO::$_nullObject); self::createMergeActivities($mainId, $otherId); return TRUE; }