/**
  * Delete a contact and all its associated records.
  *
  * @param int $id
  *   Id of the contact to delete.
  * @param bool $restore
  *   Whether to actually restore, not delete.
  * @param bool $skipUndelete
  *   Whether to force contact delete or not.
  *
  * @return bool
  *   Was contact deleted?
  */
 public static function deleteContact($id, $restore = FALSE, $skipUndelete = FALSE)
 {
     if (!$id) {
         return FALSE;
     }
     // If trash is disabled in system settings then we always skip
     if (!CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'contact_undelete', NULL, 1)) {
         $skipUndelete = TRUE;
     }
     // make sure we have edit permission for this contact
     // before we delete
     if ($skipUndelete && !CRM_Core_Permission::check('delete contacts') || $restore && !CRM_Core_Permission::check('access deleted contacts')) {
         return FALSE;
     }
     // CRM-12929
     // Restrict contact to be delete if contact has financial trxns
     $error = NULL;
     if ($skipUndelete && CRM_Financial_BAO_FinancialItem::checkContactPresent(array($id), $error)) {
         return FALSE;
     }
     // make sure this contact_id does not have any membership types
     $membershipTypeID = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $id, 'id', 'member_of_contact_id');
     if ($membershipTypeID) {
         return FALSE;
     }
     $contact = new CRM_Contact_DAO_Contact();
     $contact->id = $id;
     if (!$contact->find(TRUE)) {
         return FALSE;
     }
     $contactType = $contact->contact_type;
     // currently we only clear employer cache.
     // we are now deleting inherited membership if any.
     if ($contact->contact_type == 'Organization') {
         $action = $restore ? CRM_Core_Action::ENABLE : CRM_Core_Action::DISABLE;
         $relationshipDtls = CRM_Contact_BAO_Relationship::getRelationship($id);
         if (!empty($relationshipDtls)) {
             foreach ($relationshipDtls as $rId => $details) {
                 CRM_Contact_BAO_Relationship::disableEnableRelationship($rId, $action);
             }
         }
         CRM_Contact_BAO_Contact_Utils::clearAllEmployee($id);
     }
     if ($restore) {
         return self::contactTrashRestore($contact, TRUE);
     }
     // start a new transaction
     $transaction = new CRM_Core_Transaction();
     if ($skipUndelete) {
         CRM_Utils_Hook::pre('delete', $contactType, $id, CRM_Core_DAO::$_nullArray);
         //delete billing address if exists.
         CRM_Contribute_BAO_Contribution::deleteAddress(NULL, $id);
         // delete the log entries since we dont have triggers enabled as yet
         $logDAO = new CRM_Core_DAO_Log();
         $logDAO->entity_table = 'civicrm_contact';
         $logDAO->entity_id = $id;
         $logDAO->delete();
         // delete contact participants CRM-12155
         CRM_Event_BAO_Participant::deleteContactParticipant($id);
         // delete contact contributions CRM-12155
         CRM_Contribute_BAO_Contribution::deleteContactContribution($id);
         // do activity cleanup, CRM-5604
         CRM_Activity_BAO_Activity::cleanupActivity($id);
         // delete all notes related to contact
         CRM_Core_BAO_Note::cleanContactNotes($id);
         // delete cases related to contact
         $contactCases = CRM_Case_BAO_Case::retrieveCaseIdsByContactId($id);
         if (!empty($contactCases)) {
             foreach ($contactCases as $caseId) {
                 //check if case is associate with other contact or not.
                 $caseContactId = CRM_Case_BAO_Case::getCaseClients($caseId);
                 if (count($caseContactId) <= 1) {
                     CRM_Case_BAO_Case::deleteCase($caseId);
                 }
             }
         }
         $contact->delete();
     } else {
         self::contactTrashRestore($contact);
     }
     //delete the contact id from recently view
     CRM_Utils_Recent::delContact($id);
     // Update the group contact cache
     if ($restore) {
         CRM_Contact_BAO_GroupContactCache::remove();
     } else {
         CRM_Contact_BAO_GroupContactCache::removeContact($id);
     }
     // delete any dupe cache entry
     CRM_Core_BAO_PrevNextCache::deleteItem($id);
     $transaction->commit();
     if ($skipUndelete) {
         CRM_Utils_Hook::post('delete', $contactType, $contact->id, $contact);
     }
     // also reset the DB_DO global array so we can reuse the memory
     // http://issues.civicrm.org/jira/browse/CRM-4387
     CRM_Core_DAO::freeResult();
     return TRUE;
 }
 private function contact_create($mode = 'import')
 {
     $this->import_status_update('contact');
     // bug fix for $this->contacts keep being appended
     if (!empty($this->contacts)) {
         unset($this->contacts);
         $this->contacts = array();
     }
     for ($i = 0; $i < count($this->csv->data); $i++) {
         $param = array('version' => '3', 'contact_type' => 'Individual');
         if ($mode == 'import') {
             $param['dupe_check'] = $this->data->dupe_check == 1 ? TRUE : FALSE;
             // #FIX issue 87: auto-append contact source if it is not mapped
             // appending the date and the job id to the import
             if (!in_array('contact_source', $this->contacts)) {
                 $param['contact_source'] = date('Ymd') . '_' . $this->data->jobid;
             }
             // #FIX issue 72: Add email only de-dupe feature
             if ($this->data->dupe_check == 2) {
                 $mapping = array_flip($this->contact_data);
                 $email = $this->csv->data[$i][$mapping['email']];
                 $contact_id = $this->check_email($email);
                 if (is_numeric($contact_id)) {
                     // for email only dedupe, we delete the param and skip this iteration
                     $this->log->_log('Error on CSV line ' . $i . ':, (Matching contact found:, ' . $contact_id . '),' . implode(',', $this->csv->data[$i]), 'error_csv');
                     unset($param);
                     continue;
                 }
             }
         }
         // in case we are doing an append with *ONLY* Location data we still need to fill $this->contact
         if (count($this->contact_data) == 1) {
             $id = array_values($this->contact_data);
             $column = array_keys($this->contact_data);
             if ($id[0] == 'external_identifier') {
                 $contact_id = $this->fetch_contact_id($this->csv->data[$i][$column[0]]);
             } else {
                 $contact_id = $this->csv->data[$i][$column[0]];
             }
             if (isset($contact_id) && $contact_id != '') {
                 $this->contacts[$contact_id] = $this->csv->data[$i];
             } else {
                 // unmatched append row
                 $this->log->_log('Record not found in database:,' . implode(',', $this->csv->data[$i]), 'error_csv');
             }
         } else {
             foreach ($this->contact_data as $column => $field) {
                 // dealing with some special fields because of CiviCRM's internal workings
                 switch ($field) {
                     case 'birth_date':
                         $param[$field] = civicrm_import_utils::format_date($this->csv->data[$i][$column], $this->data->date_format);
                         break;
                     case 'gender':
                         $param[$field] = civicrm_import_utils::format_gender($this->csv->data[$i][$column]);
                         break;
                         // in appending job you have to get contact_id if they choose to match to external identifier
                     // in appending job you have to get contact_id if they choose to match to external identifier
                     case 'external_identifier':
                         // get the contact id
                         if ($mode == 'import') {
                             $param[$field] = $this->csv->data[$i][$column];
                         } else {
                             $param['contact_id'] = $this->fetch_contact_id($this->csv->data[$i][$column]);
                         }
                         break;
                     default:
                         $param[$field] = $this->csv->data[$i][$column];
                         break;
                 }
             }
             // print_r($param);
             // data filtering validation:
             // if the $param does not fit our validation requirement
             // i.e. First name, Last name, Email, we do not import them.
             // #FEATURE: $this->check_filter should return an array of bad fields so we can pin them down in
             // the log
             if ($this->check_filter($param, $mode)) {
                 if ($mode == 'import') {
                     // @CiviCRM API (v3)
                     $contact = civicrm_api('contact', 'create', $param);
                 } else {
                     if (isset($param['contact_id']) && $param['contact_id'] != '') {
                         // @CiviCRM API (v3)
                         $param['id'] = $param['contact_id'];
                         unset($param['contact_id']);
                         $contact = civicrm_api('contact', 'create', $param);
                     } else {
                         // log all the ones that did not find a matching record into the error_csv
                         $this->log->_log('Error on CSV line ' . $i . ':, (No matching contact found with the id provided),' . implode(',', $this->csv->data[$i]), 'error_csv');
                     }
                 }
                 // #FIXED: memory leak from API call
                 CRM_Core_DAO::freeResult();
                 if ($contact['is_error'] == 1) {
                     $this->log->_log('Error on CSV line ' . $i . ':, (' . $contact['error_message'] . '),' . implode(',', $this->csv->data[$i]), 'error_csv');
                 } else {
                     $this->contacts[$contact['id']] = $this->csv->data[$i];
                     $this->contact_imported++;
                     // record the contact import count for tracking
                     if ($this->contact_imported % 100 == 0) {
                         $this->update_count('contact');
                     }
                 }
             } else {
                 // log this row as bad row
                 $this->log->_log('Error on CSV line ' . $i . ':, (Bad last name or email on CSV line),' . implode(',', $this->csv->data[$i]), 'error_csv');
             }
             $this->update_count('contact');
         }
     }
     $this->log->_log($this->contact_imported . ' number of contact records created from ' . count($this->csv->data) . ' number of rows read from CSV file');
     // free the original parsed csv from memory
     unset($this->csv->data);
 }
/**
 * @todo Move this to ContactFormat.php
 * @deprecated
 */
function civicrm_contact_format_create(&$params)
{
    _civicrm_initialize();
    CRM_Core_DAO::freeResult();
    // return error if we have no params
    if (empty($params)) {
        return civicrm_create_error('Input Parameters empty');
    }
    $error = _civicrm_required_formatted_contact($params);
    if (civicrm_error($error)) {
        return $error;
    }
    $error = _civicrm_validate_formatted_contact($params);
    if (civicrm_error($error)) {
        return $error;
    }
    //get the prefix id etc if exists
    require_once 'CRM/Contact/BAO/Contact.php';
    CRM_Contact_BAO_Contact::resolveDefaults($params, TRUE);
    require_once 'CRM/Import/Parser.php';
    if (CRM_Utils_Array::value('onDuplicate', $params) != CRM_Import_Parser::DUPLICATE_NOCHECK) {
        CRM_Core_Error::reset();
        $error = _civicrm_duplicate_formatted_contact($params);
        if (civicrm_error($error)) {
            return $error;
        }
    }
    $contact = CRM_Contact_BAO_Contact::create($params, CRM_Utils_Array::value('fixAddress', $params));
    _civicrm_object_to_array($contact, $contactArray);
    return $contactArray;
}
 /**
  * A function to build an array of information required by merge function and the merge UI.
  *
  * @param int $mainId
  *   Main contact with whom merge has to happen.
  * @param int $otherId
  *   Duplicate contact which would be deleted after merge operation.
  *
  * @return array|bool|int
  */
 public static function getRowsElementsAndInfo($mainId, $otherId)
 {
     $qfZeroBug = 'e8cddb72-a257-11dc-b9cc-0016d3330ee9';
     // Fetch contacts
     foreach (array('main' => $mainId, 'other' => $otherId) as $moniker => $cid) {
         $params = array('contact_id' => $cid, 'version' => 3, 'return' => array_merge(array('display_name'), self::getContactFields()));
         $result = civicrm_api('contact', 'get', $params);
         if (empty($result['values'][$cid]['contact_type'])) {
             return FALSE;
         }
         ${$moniker} = $result['values'][$cid];
     }
     static $fields = array();
     if (empty($fields)) {
         $fields = CRM_Contact_DAO_Contact::fields();
         CRM_Core_DAO::freeResult();
     }
     // FIXME: there must be a better way
     foreach (array('main', 'other') as $moniker) {
         $contact =& ${$moniker};
         $preferred_communication_method = CRM_Utils_array::value('preferred_communication_method', $contact);
         $value = empty($preferred_communication_method) ? array() : $preferred_communication_method;
         $specialValues[$moniker] = array('preferred_communication_method' => $value, 'communication_style_id' => $value);
         if (!empty($contact['preferred_communication_method'])) {
             // api 3 returns pref_comm_method as an array, which breaks the lookup; so we reconstruct
             $prefCommList = is_array($specialValues[$moniker]['preferred_communication_method']) ? implode(CRM_Core_DAO::VALUE_SEPARATOR, $specialValues[$moniker]['preferred_communication_method']) : $specialValues[$moniker]['preferred_communication_method'];
             $specialValues[$moniker]['preferred_communication_method'] = CRM_Core_DAO::VALUE_SEPARATOR . $prefCommList . CRM_Core_DAO::VALUE_SEPARATOR;
         }
         $names = array('preferred_communication_method' => array('newName' => 'preferred_communication_method_display', 'groupName' => 'preferred_communication_method'));
         CRM_Core_OptionGroup::lookupValues($specialValues[$moniker], $names);
         if (!empty($contact['communication_style'])) {
             $specialValues[$moniker]['communication_style_id_display'] = $contact['communication_style'];
         }
     }
     static $optionValueFields = array();
     if (empty($optionValueFields)) {
         $optionValueFields = CRM_Core_OptionValue::getFields();
     }
     foreach ($optionValueFields as $field => $params) {
         $fields[$field]['title'] = $params['title'];
     }
     $diffs = self::findDifferences($main, $other);
     $rows = $elements = $relTableElements = $migrationInfo = array();
     $genders = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
     foreach ($diffs['contact'] as $field) {
         if ($field == 'contact_sub_type') {
             // CRM-15681 don't display sub-types in UI
             continue;
         }
         foreach (array('main', 'other') as $moniker) {
             $contact =& ${$moniker};
             $value = CRM_Utils_Array::value($field, $contact);
             if (isset($specialValues[$moniker][$field]) && is_string($specialValues[$moniker][$field])) {
                 $value = CRM_Core_DAO::VALUE_SEPARATOR . trim($specialValues[$moniker][$field], CRM_Core_DAO::VALUE_SEPARATOR) . CRM_Core_DAO::VALUE_SEPARATOR;
             }
             $label = isset($specialValues[$moniker]["{$field}_display"]) ? $specialValues[$moniker]["{$field}_display"] : $value;
             if (!empty($fields[$field]['type']) && $fields[$field]['type'] == CRM_Utils_Type::T_DATE) {
                 if ($value) {
                     $value = str_replace('-', '', $value);
                     $label = CRM_Utils_Date::customFormat($label);
                 } else {
                     $value = "null";
                 }
             } elseif (!empty($fields[$field]['type']) && $fields[$field]['type'] == CRM_Utils_Type::T_BOOLEAN) {
                 if ($label === '0') {
                     $label = ts('[ ]');
                 }
                 if ($label === '1') {
                     $label = ts('[x]');
                 }
             } elseif ($field == 'individual_prefix' || $field == 'prefix_id') {
                 $label = CRM_Utils_Array::value('individual_prefix', $contact);
                 $value = CRM_Utils_Array::value('prefix_id', $contact);
                 $field = 'prefix_id';
             } elseif ($field == 'individual_suffix' || $field == 'suffix_id') {
                 $label = CRM_Utils_Array::value('individual_suffix', $contact);
                 $value = CRM_Utils_Array::value('suffix_id', $contact);
                 $field = 'suffix_id';
             } elseif ($field == 'gender_id' && !empty($value)) {
                 $label = $genders[$value];
             } elseif ($field == 'current_employer_id' && !empty($value)) {
                 $label = "{$value} (" . CRM_Contact_BAO_Contact::displayName($value) . ")";
             }
             $rows["move_{$field}"][$moniker] = $label;
             if ($moniker == 'other') {
                 //CRM-14334
                 if ($value === NULL || $value == '') {
                     $value = 'null';
                 }
                 if ($value === 0 or $value === '0') {
                     $value = $qfZeroBug;
                 }
                 if (is_array($value) && empty($value[1])) {
                     $value[1] = NULL;
                 }
                 $elements[] = array('advcheckbox', "move_{$field}", NULL, NULL, NULL, $value);
                 $migrationInfo["move_{$field}"] = $value;
             }
         }
         $rows["move_{$field}"]['title'] = $fields[$field]['title'];
     }
     // handle location blocks.
     $locationBlocks = array('email', 'phone', 'address');
     $locations = array();
     foreach ($locationBlocks as $block) {
         foreach (array('main' => $mainId, 'other' => $otherId) as $moniker => $cid) {
             $cnt = 1;
             $values = civicrm_api($block, 'get', array('contact_id' => $cid, 'version' => 3));
             $count = $values['count'];
             if ($count) {
                 if ($count > $cnt) {
                     foreach ($values['values'] as $value) {
                         if ($block == 'address') {
                             CRM_Core_BAO_Address::fixAddress($value);
                             $display = CRM_Utils_Address::format($value);
                             $locations[$moniker][$block][$cnt] = $value;
                             $locations[$moniker][$block][$cnt]['display'] = $display;
                         } else {
                             $locations[$moniker][$block][$cnt] = $value;
                         }
                         $cnt++;
                     }
                 } else {
                     $id = $values['id'];
                     if ($block == 'address') {
                         CRM_Core_BAO_Address::fixAddress($values['values'][$id]);
                         $display = CRM_Utils_Address::format($values['values'][$id]);
                         $locations[$moniker][$block][$cnt] = $values['values'][$id];
                         $locations[$moniker][$block][$cnt]['display'] = $display;
                     } else {
                         $locations[$moniker][$block][$cnt] = $values['values'][$id];
                     }
                 }
             }
         }
     }
     $allLocationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
     $mainLocBlock = $locBlockIds = array();
     $locBlockIds['main'] = $locBlockIds['other'] = array();
     foreach (array('Email', 'Phone', 'IM', 'OpenID', 'Address') as $block) {
         $name = strtolower($block);
         foreach (array('main', 'other') as $moniker) {
             $locIndex = CRM_Utils_Array::value($moniker, $locations);
             $blockValue = CRM_Utils_Array::value($name, $locIndex, array());
             if (empty($blockValue)) {
                 $locValue[$moniker][$name] = 0;
                 $locLabel[$moniker][$name] = $locTypes[$moniker][$name] = array();
             } else {
                 $locValue[$moniker][$name] = TRUE;
                 foreach ($blockValue as $count => $blkValues) {
                     $fldName = $name;
                     $locTypeId = $blkValues['location_type_id'];
                     if ($name == 'im') {
                         $fldName = 'name';
                     }
                     if ($name == 'address') {
                         $fldName = 'display';
                     }
                     $locLabel[$moniker][$name][$count] = CRM_Utils_Array::value($fldName, $blkValues);
                     $locTypes[$moniker][$name][$count] = $locTypeId;
                     if ($moniker == 'main' && in_array($name, $locationBlocks)) {
                         $mainLocBlock["main_{$name}{$locTypeId}"] = CRM_Utils_Array::value($fldName, $blkValues);
                         $locBlockIds['main'][$name][$locTypeId] = $blkValues['id'];
                     } else {
                         $locBlockIds[$moniker][$name][$count] = $blkValues['id'];
                     }
                 }
             }
         }
         if ($locValue['other'][$name] != 0) {
             foreach ($locLabel['other'][$name] as $count => $value) {
                 $locTypeId = $locTypes['other'][$name][$count];
                 $rows["move_location_{$name}_{$count}"]['other'] = $value;
                 $rows["move_location_{$name}_{$count}"]['main'] = CRM_Utils_Array::value($count, $locLabel['main'][$name]);
                 $rows["move_location_{$name}_{$count}"]['title'] = ts('%1:%2:%3', array(1 => $block, 2 => $count, 3 => $allLocationTypes[$locTypeId]));
                 $elements[] = array('advcheckbox', "move_location_{$name}_{$count}");
                 $migrationInfo["move_location_{$name}_{$count}"] = 1;
                 // make sure default location type is always on top
                 $mainLocTypeId = CRM_Utils_Array::value($count, $locTypes['main'][$name], $locTypeId);
                 $locTypeValues = $allLocationTypes;
                 $defaultLocType = array($mainLocTypeId => $locTypeValues[$mainLocTypeId]);
                 unset($locTypeValues[$mainLocTypeId]);
                 // keep 1-1 mapping for address - location type.
                 $js = NULL;
                 if (in_array($name, $locationBlocks) && !empty($mainLocBlock)) {
                     $js = array('onChange' => "mergeBlock('{$name}', this, {$count} );");
                 }
                 $elements[] = array('select', "location[{$name}][{$count}][locTypeId]", NULL, $defaultLocType + $locTypeValues, $js);
                 // keep location-type-id same as that of other-contact
                 $migrationInfo['location'][$name][$count]['locTypeId'] = $locTypeId;
                 if ($name != 'address') {
                     $elements[] = array('advcheckbox', "location[{$name}][{$count}][operation]", NULL, ts('add new'));
                     // always use add operation
                     $migrationInfo['location'][$name][$count]['operation'] = 1;
                 }
             }
         }
     }
     // add the related tables and unset the ones that don't sport any of the duplicate contact's info
     $config = CRM_Core_Config::singleton();
     $mainUfId = CRM_Core_BAO_UFMatch::getUFId($mainId);
     $mainUser = NULL;
     if ($mainUfId) {
         // d6 compatible
         if ($config->userSystem->is_drupal == '1' && function_exists($mainUser)) {
             $mainUser = user_load($mainUfId);
         } elseif ($config->userFramework == 'Joomla') {
             $mainUser = JFactory::getUser($mainUfId);
         }
     }
     $otherUfId = CRM_Core_BAO_UFMatch::getUFId($otherId);
     $otherUser = NULL;
     if ($otherUfId) {
         // d6 compatible
         if ($config->userSystem->is_drupal == '1' && function_exists($mainUser)) {
             $otherUser = user_load($otherUfId);
         } elseif ($config->userFramework == 'Joomla') {
             $otherUser = JFactory::getUser($otherUfId);
         }
     }
     $relTables = CRM_Dedupe_Merger::relTables();
     $activeRelTables = CRM_Dedupe_Merger::getActiveRelTables($otherId);
     $activeMainRelTables = CRM_Dedupe_Merger::getActiveRelTables($mainId);
     foreach ($relTables as $name => $null) {
         if (!in_array($name, $activeRelTables) && !($name == 'rel_table_users' && in_array($name, $activeMainRelTables))) {
             unset($relTables[$name]);
             continue;
         }
         $relTableElements[] = array('checkbox', "move_{$name}");
         $migrationInfo["move_{$name}"] = 1;
         $relTables[$name]['main_url'] = str_replace('$cid', $mainId, $relTables[$name]['url']);
         $relTables[$name]['other_url'] = str_replace('$cid', $otherId, $relTables[$name]['url']);
         if ($name == 'rel_table_users') {
             $relTables[$name]['main_url'] = str_replace('%ufid', $mainUfId, $relTables[$name]['url']);
             $relTables[$name]['other_url'] = str_replace('%ufid', $otherUfId, $relTables[$name]['url']);
             $find = array('$ufid', '$ufname');
             if ($mainUser) {
                 $replace = array($mainUfId, $mainUser->name);
                 $relTables[$name]['main_title'] = str_replace($find, $replace, $relTables[$name]['title']);
             }
             if ($otherUser) {
                 $replace = array($otherUfId, $otherUser->name);
                 $relTables[$name]['other_title'] = str_replace($find, $replace, $relTables[$name]['title']);
             }
         }
         if ($name == 'rel_table_memberships') {
             $elements[] = array('checkbox', "operation[move_{$name}][add]", NULL, ts('add new'));
             $migrationInfo["operation"]["move_{$name}"]['add'] = 1;
         }
     }
     foreach ($relTables as $name => $null) {
         $relTables["move_{$name}"] = $relTables[$name];
         unset($relTables[$name]);
     }
     // handle custom fields
     $mainTree = CRM_Core_BAO_CustomGroup::getTree($main['contact_type'], CRM_Core_DAO::$_nullObject, $mainId, -1, CRM_Utils_Array::value('contact_sub_type', $main));
     $otherTree = CRM_Core_BAO_CustomGroup::getTree($main['contact_type'], CRM_Core_DAO::$_nullObject, $otherId, -1, CRM_Utils_Array::value('contact_sub_type', $other));
     CRM_Core_DAO::freeResult();
     foreach ($otherTree as $gid => $group) {
         $foundField = FALSE;
         if (!isset($group['fields'])) {
             continue;
         }
         foreach ($group['fields'] as $fid => $field) {
             if (in_array($fid, $diffs['custom'])) {
                 if (!$foundField) {
                     $rows["custom_group_{$gid}"]['title'] = $group['title'];
                     $foundField = TRUE;
                 }
                 if (!empty($mainTree[$gid]['fields'][$fid]['customValue'])) {
                     foreach ($mainTree[$gid]['fields'][$fid]['customValue'] as $valueId => $values) {
                         $rows["move_custom_{$fid}"]['main'] = CRM_Core_BAO_CustomGroup::formatCustomValues($values, $field, TRUE);
                     }
                 }
                 $value = "null";
                 if (!empty($otherTree[$gid]['fields'][$fid]['customValue'])) {
                     foreach ($otherTree[$gid]['fields'][$fid]['customValue'] as $valueId => $values) {
                         $rows["move_custom_{$fid}"]['other'] = CRM_Core_BAO_CustomGroup::formatCustomValues($values, $field, TRUE);
                         if ($values['data'] === 0 || $values['data'] === '0') {
                             $values['data'] = $qfZeroBug;
                         }
                         $value = $values['data'] ? $values['data'] : $value;
                     }
                 }
                 $rows["move_custom_{$fid}"]['title'] = $field['label'];
                 $elements[] = array('advcheckbox', "move_custom_{$fid}", NULL, NULL, NULL, $value);
                 $migrationInfo["move_custom_{$fid}"] = $value;
             }
         }
     }
     $result = array('rows' => $rows, 'elements' => $elements, 'rel_table_elements' => $relTableElements, 'main_loc_block' => $mainLocBlock, 'rel_tables' => $relTables, 'main_details' => $main, 'other_details' => $other, 'migration_info' => $migrationInfo);
     $result['main_details']['loc_block_ids'] = $locBlockIds['main'];
     $result['other_details']['loc_block_ids'] = $locBlockIds['other'];
     return $result;
 }
 public static function csv()
 {
     $csvFile = '/home/deepak/Desktop/crm-4247.csv';
     $delimiter = ";";
     $row = 1;
     $handle = fopen($csvFile, "r");
     if (!$handle) {
         CRM_Core_Error::fatal("Can't locate csv file.");
     }
     require_once "CRM/Contribute/BAO/Contribution/Utils.php";
     while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
         if ($row !== 1) {
             $data['header'] = $header;
             $params = self::formatAPIParams($data, self::$_csvParamsMapper, 'csv');
             if (self::processAPIContribution($params)) {
                 CRM_Core_Error::debug_log_message("Processed - line {$row} of csv file .. {$params['email']}, {$params['transaction']['total_amount']}, {$params['transaction']['trxn_id']} ..<p>", TRUE);
             } else {
                 CRM_Core_Error::debug_log_message("Skipped - line {$row} of csv file .. {$params['email']}, {$params['transaction']['total_amount']}, {$params['transaction']['trxn_id']} ..<p>", TRUE);
             }
             // clean up memory from dao's
             CRM_Core_DAO::freeResult();
         } else {
             // we assuming - first row is always the header line
             $header = $data;
             CRM_Core_Error::debug_log_message("Considering first row ( line {$row} ) as HEADER ..<p>", TRUE);
             if (empty($header)) {
                 CRM_Core_Error::fatal("Header is empty.");
             }
         }
         $row++;
     }
     fclose($handle);
 }
Exemple #6
0
 /**
  * A function to build an array of information required by merge function and the merge UI.
  *
  * @param int $mainId
  *   Main contact with whom merge has to happen.
  * @param int $otherId
  *   Duplicate contact which would be deleted after merge operation.
  *
  * @return array|bool|int
  *   'main_loc_block' => Stores all location blocks associated with the 'main' contact
  */
 public static function getRowsElementsAndInfo($mainId, $otherId)
 {
     $qfZeroBug = 'e8cddb72-a257-11dc-b9cc-0016d3330ee9';
     // Fetch contacts
     foreach (array('main' => $mainId, 'other' => $otherId) as $moniker => $cid) {
         $params = array('contact_id' => $cid, 'version' => 3, 'return' => array_merge(array('display_name'), self::getContactFields()));
         $result = civicrm_api('contact', 'get', $params);
         if (empty($result['values'][$cid]['contact_type'])) {
             return FALSE;
         }
         ${$moniker} = $result['values'][$cid];
     }
     $fields = CRM_Contact_DAO_Contact::fields();
     // FIXME: there must be a better way
     foreach (array('main', 'other') as $moniker) {
         $contact =& ${$moniker};
         $preferred_communication_method = CRM_Utils_array::value('preferred_communication_method', $contact);
         $value = empty($preferred_communication_method) ? array() : $preferred_communication_method;
         $specialValues[$moniker] = array('preferred_communication_method' => $value, 'communication_style_id' => $value);
         if (!empty($contact['preferred_communication_method'])) {
             // api 3 returns pref_comm_method as an array, which breaks the lookup; so we reconstruct
             $prefCommList = is_array($specialValues[$moniker]['preferred_communication_method']) ? implode(CRM_Core_DAO::VALUE_SEPARATOR, $specialValues[$moniker]['preferred_communication_method']) : $specialValues[$moniker]['preferred_communication_method'];
             $specialValues[$moniker]['preferred_communication_method'] = CRM_Core_DAO::VALUE_SEPARATOR . $prefCommList . CRM_Core_DAO::VALUE_SEPARATOR;
         }
         $names = array('preferred_communication_method' => array('newName' => 'preferred_communication_method_display', 'groupName' => 'preferred_communication_method'));
         CRM_Core_OptionGroup::lookupValues($specialValues[$moniker], $names);
         if (!empty($contact['communication_style'])) {
             $specialValues[$moniker]['communication_style_id_display'] = $contact['communication_style'];
         }
     }
     static $optionValueFields = array();
     if (empty($optionValueFields)) {
         $optionValueFields = CRM_Core_OptionValue::getFields();
     }
     foreach ($optionValueFields as $field => $params) {
         $fields[$field]['title'] = $params['title'];
     }
     $compareFields = self::retrieveFields($main, $other);
     $rows = $elements = $relTableElements = $migrationInfo = array();
     foreach ($compareFields['contact'] as $field) {
         if ($field == 'contact_sub_type') {
             // CRM-15681 don't display sub-types in UI
             continue;
         }
         foreach (array('main', 'other') as $moniker) {
             $contact =& ${$moniker};
             $value = CRM_Utils_Array::value($field, $contact);
             if (isset($specialValues[$moniker][$field]) && is_string($specialValues[$moniker][$field])) {
                 $value = CRM_Core_DAO::VALUE_SEPARATOR . trim($specialValues[$moniker][$field], CRM_Core_DAO::VALUE_SEPARATOR) . CRM_Core_DAO::VALUE_SEPARATOR;
             }
             $label = isset($specialValues[$moniker]["{$field}_display"]) ? $specialValues[$moniker]["{$field}_display"] : $value;
             if (!empty($fields[$field]['type']) && $fields[$field]['type'] == CRM_Utils_Type::T_DATE) {
                 if ($value) {
                     $value = str_replace('-', '', $value);
                     $label = CRM_Utils_Date::customFormat($label);
                 } else {
                     $value = "null";
                 }
             } elseif (!empty($fields[$field]['type']) && $fields[$field]['type'] == CRM_Utils_Type::T_BOOLEAN) {
                 if ($label === '0') {
                     $label = ts('[ ]');
                 }
                 if ($label === '1') {
                     $label = ts('[x]');
                 }
             } elseif ($field == 'individual_prefix' || $field == 'prefix_id') {
                 $label = CRM_Utils_Array::value('individual_prefix', $contact);
                 $value = CRM_Utils_Array::value('prefix_id', $contact);
                 $field = 'prefix_id';
             } elseif ($field == 'individual_suffix' || $field == 'suffix_id') {
                 $label = CRM_Utils_Array::value('individual_suffix', $contact);
                 $value = CRM_Utils_Array::value('suffix_id', $contact);
                 $field = 'suffix_id';
             } elseif ($field == 'gender_id' && !empty($value)) {
                 $genderOptions = civicrm_api3('contact', 'getoptions', array('field' => 'gender_id'));
                 $label = $genderOptions['values'][$value];
             } elseif ($field == 'current_employer_id' && !empty($value)) {
                 $label = "{$value} (" . CRM_Contact_BAO_Contact::displayName($value) . ")";
             }
             $rows["move_{$field}"][$moniker] = $label;
             if ($moniker == 'other') {
                 //CRM-14334
                 if ($value === NULL || $value == '') {
                     $value = 'null';
                 }
                 if ($value === 0 or $value === '0') {
                     $value = $qfZeroBug;
                 }
                 if (is_array($value) && empty($value[1])) {
                     $value[1] = NULL;
                 }
                 // Display a checkbox to migrate, only if the values are different
                 if ($value != $main[$field]) {
                     $elements[] = array('advcheckbox', "move_{$field}", NULL, NULL, NULL, $value);
                 }
                 $migrationInfo["move_{$field}"] = $value;
             }
         }
         $rows["move_{$field}"]['title'] = $fields[$field]['title'];
     }
     // Handle location blocks.
     // @todo OpenID not in API yet, so is not supported here.
     // Set up useful information about the location blocks
     $locationBlocks = self::getLocationBlockInfo();
     $locations = array('main' => array(), 'other' => array());
     $mainLocBlock = array();
     // @todo This could probably be defined and used earlier
     $mergeTargets = array('main' => $mainId, 'other' => $otherId);
     foreach ($locationBlocks as $blockName => $blockInfo) {
         // Collect existing fields from both 'main' and 'other' contacts first
         // This allows us to match up location/types when building the table rows
         foreach ($mergeTargets as $moniker => $cid) {
             $cnt = 1;
             $searchParams = array('version' => 3, 'contact_id' => $cid, 'options' => array('sort' => $blockInfo['sortString']));
             $values = civicrm_api($blockName, 'get', $searchParams);
             if ($values['count']) {
                 $cnt = 0;
                 foreach ($values['values'] as $index => $value) {
                     $locations[$moniker][$blockName][$cnt] = $value;
                     // Fix address display
                     $display = '';
                     if ($blockName == 'address') {
                         CRM_Core_BAO_Address::fixAddress($value);
                         $display = CRM_Utils_Address::format($value);
                         $locations[$moniker][$blockName][$cnt]['display'] = $display;
                     }
                     // Add any 'main' contact block values to an array for the JS
                     // @todo The JS should just access the main_details to find this info?
                     if ($moniker == 'main') {
                         if ($blockInfo['hasType']) {
                             // Handle websites, no location type ID
                             // @todo Remove the need for this specific 'if'
                             if ($blockName == 'website') {
                                 $value['location_type_id'] = 0;
                             }
                             $mainLocBlock["main_" . $blockName . "_" . $value['location_type_id'] . "_" . $value[$blockInfo['hasType']]]['display'] = $value[$blockInfo['displayField']];
                             $mainLocBlock["main_" . $blockName . "_" . $value['location_type_id'] . "_" . $value[$blockInfo['hasType']]]['id'] = $value['id'];
                         } else {
                             // Get the correct display value for addresses
                             // @todo Remove the need for this if...
                             if ($blockName == 'address') {
                                 $mainLocBlock["main_" . $blockName . "_" . $value['location_type_id']]['display'] = $display;
                                 $mainLocBlock["main_" . $blockName . "_" . $value['location_type_id']]['id'] = $value['id'];
                             } else {
                                 $mainLocBlock["main_" . $blockName . "_" . $value['location_type_id']]['display'] = $value[$blockInfo['displayField']];
                                 $mainLocBlock["main_" . $blockName . "_" . $value['location_type_id']]['id'] = $value['id'];
                             }
                         }
                     }
                     $cnt++;
                 }
             }
         }
         // Now, build the table rows appropriately, based off the information on
         // the 'other' contact
         if (!empty($locations['other']) && !empty($locations['other'][$blockName])) {
             foreach ($locations['other'][$blockName] as $count => $value) {
                 $displayValue = $value[$blockInfo['displayField']];
                 // Add this value to the table rows
                 $rows["move_location_{$blockName}_{$count}"]['other'] = $displayValue;
                 // CRM-17556 Only display 'main' contact value if it's the same location + type
                 // Look it up from main values...
                 $lookupLocation = FALSE;
                 if ($blockInfo['hasLocation']) {
                     $lookupLocation = $value['location_type_id'];
                 }
                 $lookupType = FALSE;
                 if ($blockInfo['hasType']) {
                     $lookupType = $value[$blockInfo['hasType']];
                 }
                 // Hold ID of main contact's matching block
                 $mainContactBlockId = 0;
                 if (!empty($locations['main'][$blockName])) {
                     foreach ($locations['main'][$blockName] as $mainValueCheck) {
                         // No location/type, or matching location and type
                         if ((empty($lookupLocation) || $lookupLocation == $mainValueCheck['location_type_id']) && (empty($lookupType) || $lookupType == $mainValueCheck[$blockInfo['hasType']])) {
                             // Set this value as the default against the 'other' contact value
                             $rows["move_location_{$blockName}_{$count}"]['main'] = $mainValueCheck[$blockInfo['displayField']];
                             $mainContactBlockId = $mainValueCheck['id'];
                             break;
                         }
                     }
                 }
                 // Add checkbox to migrate data from 'other' to 'main'
                 $elements[] = array('advcheckbox', "move_location_{$blockName}_{$count}");
                 // Flag up this field to skipMerge function (@todo: do we need to?)
                 $migrationInfo["move_location_{$blockName}_{$count}"] = 1;
                 // Add a hidden field to store the ID of the target main contact block
                 $elements[] = array('hidden', "location[{$blockName}][{$count}][mainContactBlockId]", $mainContactBlockId);
                 // Setup variables
                 $thisTypeId = FALSE;
                 $thisLocId = FALSE;
                 // Provide a select drop-down for the location's location type
                 // eg: Home, Work...
                 $js = NULL;
                 if ($blockInfo['hasLocation']) {
                     // Load the location options for this entity
                     $locationOptions = civicrm_api3($blockName, 'getoptions', array('field' => 'location_type_id'));
                     // JS lookup 'main' contact's location (if there are any)
                     if (!empty($locations['main'][$blockName])) {
                         $js = array('onChange' => "mergeBlock('{$blockName}', this, {$count}, 'locTypeId' );");
                     }
                     $thisLocId = $value['location_type_id'];
                     // Put this field's location type at the top of the list
                     $tmpIdList = $locationOptions['values'];
                     $defaultLocId = array($thisLocId => $tmpIdList[$thisLocId]);
                     unset($tmpIdList[$thisLocId]);
                     // Add the element
                     $elements[] = array('select', "location[{$blockName}][{$count}][locTypeId]", NULL, $defaultLocId + $tmpIdList, $js);
                     // Add the relevant information to the $migrationInfo
                     // Keep location-type-id same as that of other-contact
                     // @todo Check this logic out
                     $migrationInfo['location_blocks'][$blockName][$count]['locTypeId'] = $thisLocId;
                     if ($blockName != 'address') {
                         $elements[] = array('advcheckbox', "location[{$blockName}][{$count}][operation]", NULL, ts('add new'));
                         // always use add operation
                         $migrationInfo['location_blocks'][$blockName][$count]['operation'] = 1;
                     }
                 }
                 // Provide a select drop-down for the location's type/provider
                 // eg websites: Google+, Facebook...
                 $js = NULL;
                 if ($blockInfo['hasType']) {
                     // Load the type options for this entity
                     $typeOptions = civicrm_api3($blockName, 'getoptions', array('field' => $blockInfo['hasType']));
                     // CRM-17556 Set up JS lookup of 'main' contact's value by type
                     if (!empty($locations['main'][$blockName])) {
                         $js = array('onChange' => "mergeBlock('{$blockName}', this, {$count}, 'typeTypeId' );");
                     }
                     $thisTypeId = $value[$blockInfo['hasType']];
                     // Put this field's location type at the top of the list
                     $tmpIdList = $typeOptions['values'];
                     $defaultTypeId = array($thisTypeId => $tmpIdList[$thisTypeId]);
                     unset($tmpIdList[$thisTypeId]);
                     // Add the element
                     $elements[] = array('select', "location[{$blockName}][{$count}][typeTypeId]", NULL, $defaultTypeId + $tmpIdList, $js);
                     // Add the information to the migrationInfo (@todo Why?)
                     $migrationInfo['location_blocks'][$blockName][$count]['typeTypeId'] = $thisTypeId;
                 }
                 // Set the label for this row
                 $rowTitle = $blockInfo['label'] . ' ' . ($count + 1);
                 if (!empty($thisLocId)) {
                     $rowTitle .= ' (' . $locationOptions['values'][$thisLocId] . ')';
                 }
                 if (!empty($thisTypeId)) {
                     $rowTitle .= ' (' . $typeOptions['values'][$thisTypeId] . ')';
                 }
                 $rows["move_location_{$blockName}_{$count}"]['title'] = $rowTitle;
             }
             // End loop through 'other' locations of this type
         }
         // End if 'other' location for this type exists
     }
     // End loop through each location block entity
     // add the related tables and unset the ones that don't sport any of the duplicate contact's info
     $config = CRM_Core_Config::singleton();
     $mainUfId = CRM_Core_BAO_UFMatch::getUFId($mainId);
     $mainUser = NULL;
     if ($mainUfId) {
         // d6 compatible
         if ($config->userSystem->is_drupal == '1' && function_exists($mainUser)) {
             $mainUser = user_load($mainUfId);
         } elseif ($config->userFramework == 'Joomla') {
             $mainUser = JFactory::getUser($mainUfId);
         }
     }
     $otherUfId = CRM_Core_BAO_UFMatch::getUFId($otherId);
     $otherUser = NULL;
     if ($otherUfId) {
         // d6 compatible
         if ($config->userSystem->is_drupal == '1' && function_exists($mainUser)) {
             $otherUser = user_load($otherUfId);
         } elseif ($config->userFramework == 'Joomla') {
             $otherUser = JFactory::getUser($otherUfId);
         }
     }
     $relTables = CRM_Dedupe_Merger::relTables();
     $activeRelTables = CRM_Dedupe_Merger::getActiveRelTables($otherId);
     $activeMainRelTables = CRM_Dedupe_Merger::getActiveRelTables($mainId);
     foreach ($relTables as $name => $null) {
         if (!in_array($name, $activeRelTables) && !($name == 'rel_table_users' && in_array($name, $activeMainRelTables))) {
             unset($relTables[$name]);
             continue;
         }
         $relTableElements[] = array('checkbox', "move_{$name}");
         $migrationInfo["move_{$name}"] = 1;
         $relTables[$name]['main_url'] = str_replace('$cid', $mainId, $relTables[$name]['url']);
         $relTables[$name]['other_url'] = str_replace('$cid', $otherId, $relTables[$name]['url']);
         if ($name == 'rel_table_users') {
             $relTables[$name]['main_url'] = str_replace('%ufid', $mainUfId, $relTables[$name]['url']);
             $relTables[$name]['other_url'] = str_replace('%ufid', $otherUfId, $relTables[$name]['url']);
             $find = array('$ufid', '$ufname');
             if ($mainUser) {
                 $replace = array($mainUfId, $mainUser->name);
                 $relTables[$name]['main_title'] = str_replace($find, $replace, $relTables[$name]['title']);
             }
             if ($otherUser) {
                 $replace = array($otherUfId, $otherUser->name);
                 $relTables[$name]['other_title'] = str_replace($find, $replace, $relTables[$name]['title']);
             }
         }
         if ($name == 'rel_table_memberships') {
             $elements[] = array('checkbox', "operation[move_{$name}][add]", NULL, ts('add new'));
             $migrationInfo["operation"]["move_{$name}"]['add'] = 1;
         }
     }
     foreach ($relTables as $name => $null) {
         $relTables["move_{$name}"] = $relTables[$name];
         unset($relTables[$name]);
     }
     // handle custom fields
     $mainTree = CRM_Core_BAO_CustomGroup::getTree($main['contact_type'], CRM_Core_DAO::$_nullObject, $mainId, -1, CRM_Utils_Array::value('contact_sub_type', $main));
     $otherTree = CRM_Core_BAO_CustomGroup::getTree($main['contact_type'], CRM_Core_DAO::$_nullObject, $otherId, -1, CRM_Utils_Array::value('contact_sub_type', $other));
     CRM_Core_DAO::freeResult();
     foreach ($otherTree as $gid => $group) {
         $foundField = FALSE;
         if (!isset($group['fields'])) {
             continue;
         }
         foreach ($group['fields'] as $fid => $field) {
             if (in_array($fid, $compareFields['custom'])) {
                 if (!$foundField) {
                     $rows["custom_group_{$gid}"]['title'] = $group['title'];
                     $foundField = TRUE;
                 }
                 if (!empty($mainTree[$gid]['fields'][$fid]['customValue'])) {
                     foreach ($mainTree[$gid]['fields'][$fid]['customValue'] as $valueId => $values) {
                         $rows["move_custom_{$fid}"]['main'] = CRM_Core_BAO_CustomField::displayValue($values['data'], $fid);
                     }
                 }
                 $value = "null";
                 if (!empty($otherTree[$gid]['fields'][$fid]['customValue'])) {
                     foreach ($otherTree[$gid]['fields'][$fid]['customValue'] as $valueId => $values) {
                         $rows["move_custom_{$fid}"]['other'] = CRM_Core_BAO_CustomField::displayValue($values['data'], $fid);
                         if ($values['data'] === 0 || $values['data'] === '0') {
                             $values['data'] = $qfZeroBug;
                         }
                         $value = $values['data'] ? $values['data'] : $value;
                     }
                 }
                 $rows["move_custom_{$fid}"]['title'] = $field['label'];
                 $elements[] = array('advcheckbox', "move_custom_{$fid}", NULL, NULL, NULL, $value);
                 $migrationInfo["move_custom_{$fid}"] = $value;
             }
         }
     }
     $result = array('rows' => $rows, 'elements' => $elements, 'rel_table_elements' => $relTableElements, 'main_loc_block' => $mainLocBlock, 'rel_tables' => $relTables, 'main_details' => $main, 'other_details' => $other, 'migration_info' => $migrationInfo);
     $result['main_details']['location_blocks'] = $locations['main'];
     $result['other_details']['location_blocks'] = $locations['other'];
     return $result;
 }
Exemple #7
0
 function run($tableName, &$mapper, $mode = self::MODE_PREVIEW, $contactType = self::CONTACT_INDIVIDUAL, $primaryKeyName = '_id', $statusFieldName = '_status', $onDuplicate = self::DUPLICATE_SKIP, $statusID = NULL, $totalRowCount = NULL, $doGeocodeAddress = FALSE, $timeout = CRM_Contact_Import_Parser::DEFAULT_TIMEOUT, $contactSubType = NULL, $dedupeRuleGroupID = NULL)
 {
     // TODO: Make the timeout actually work
     $this->_onDuplicate = $onDuplicate;
     $this->_dedupeRuleGroupID = $dedupeRuleGroupID;
     switch ($contactType) {
         case CRM_Import_Parser::CONTACT_INDIVIDUAL:
             $this->_contactType = 'Individual';
             break;
         case CRM_Import_Parser::CONTACT_HOUSEHOLD:
             $this->_contactType = 'Household';
             break;
         case CRM_Import_Parser::CONTACT_ORGANIZATION:
             $this->_contactType = 'Organization';
     }
     $this->_contactSubType = $contactSubType;
     $this->init();
     $this->_rowCount = $this->_warningCount = 0;
     $this->_invalidRowCount = $this->_validCount = 0;
     $this->_totalCount = $this->_conflictCount = 0;
     $this->_errors = array();
     $this->_warnings = array();
     $this->_conflicts = array();
     $this->_unparsedAddresses = array();
     $status = '';
     $this->_tableName = $tableName;
     $this->_primaryKeyName = $primaryKeyName;
     $this->_statusFieldName = $statusFieldName;
     if ($mode == self::MODE_MAPFIELD) {
         $this->_rows = array();
     } else {
         $this->_activeFieldCount = count($this->_activeFields);
     }
     if ($mode == self::MODE_IMPORT) {
         //get the key of email field
         foreach ($mapper as $key => $value) {
             if (strtolower($value) == 'email') {
                 $emailKey = $key;
                 break;
             }
         }
     }
     if ($statusID) {
         $skip = 50;
         // $skip = 1;
         $config = CRM_Core_Config::singleton();
         $statusFile = "{$config->uploadDir}status_{$statusID}.txt";
         $status = "<div class='description'>&nbsp; " . ts('No processing status reported yet.') . "</div>";
         //do not force the browser to display the save dialog, CRM-7640
         $contents = json_encode(array(0, $status));
         file_put_contents($statusFile, $contents);
         $startTimestamp = $currTimestamp = $prevTimestamp = time();
     }
     // get the contents of the temp. import table
     $query = "SELECT * FROM {$tableName}";
     if ($mode == self::MODE_IMPORT) {
         $query .= " WHERE {$statusFieldName} = 'NEW'";
     }
     $dao = new CRM_Core_DAO();
     $db = $dao->getDatabaseConnection();
     $result = $db->query($query);
     while ($values = $result->fetchRow(DB_FETCHMODE_ORDERED)) {
         $this->_rowCount++;
         /* trim whitespace around the values */
         $empty = TRUE;
         foreach ($values as $k => $v) {
             $values[$k] = trim($v, " \t\r\n");
         }
         if (CRM_Utils_System::isNull($values)) {
             continue;
         }
         $this->_totalCount++;
         if ($mode == self::MODE_MAPFIELD) {
             $returnCode = $this->mapField($values);
         } elseif ($mode == self::MODE_PREVIEW) {
             $returnCode = $this->preview($values);
         } elseif ($mode == self::MODE_SUMMARY) {
             $returnCode = $this->summary($values);
         } elseif ($mode == self::MODE_IMPORT) {
             //print "Running parser in import mode<br/>\n";
             $returnCode = $this->import($onDuplicate, $values, $doGeocodeAddress);
             if ($statusID && $this->_rowCount % $skip == 0) {
                 $currTimestamp = time();
                 $totalTime = $currTimestamp - $startTimestamp;
                 $time = $currTimestamp - $prevTimestamp;
                 $recordsLeft = $totalRowCount - $this->_rowCount;
                 if ($recordsLeft < 0) {
                     $recordsLeft = 0;
                 }
                 $estimatedTime = $recordsLeft / $skip * $time;
                 $estMinutes = floor($estimatedTime / 60);
                 $timeFormatted = '';
                 if ($estMinutes > 1) {
                     $timeFormatted = $estMinutes . ' ' . ts('minutes') . ' ';
                     $estimatedTime = $estimatedTime - $estMinutes * 60;
                 }
                 $timeFormatted .= round($estimatedTime) . ' ' . ts('seconds');
                 $processedPercent = (int) ($this->_rowCount * 100 / $totalRowCount);
                 $statusMsg = ts('%1 of %2 records - %3 remaining', array(1 => $this->_rowCount, 2 => $totalRowCount, 3 => $timeFormatted));
                 $status = "\n<div class=\"description\">\n&nbsp; <strong>{$statusMsg}</strong>\n</div>\n";
                 $contents = json_encode(array($processedPercent, $status));
                 file_put_contents($statusFile, $contents);
                 $prevTimestamp = $currTimestamp;
             }
             // sleep(1);
         } else {
             $returnCode = self::ERROR;
         }
         // note that a line could be valid but still produce a warning
         if ($returnCode & self::VALID) {
             $this->_validCount++;
             if ($mode == self::MODE_MAPFIELD) {
                 $this->_rows[] = $values;
                 $this->_activeFieldCount = max($this->_activeFieldCount, count($values));
             }
         }
         if ($returnCode & self::WARNING) {
             $this->_warningCount++;
             if ($this->_warningCount < $this->_maxWarningCount) {
                 $this->_warningCount[] = $line;
             }
         }
         if ($returnCode & self::ERROR) {
             $this->_invalidRowCount++;
             if ($this->_invalidRowCount < $this->_maxErrorCount) {
                 array_unshift($values, $this->_rowCount);
                 $this->_errors[] = $values;
             }
         }
         if ($returnCode & self::CONFLICT) {
             $this->_conflictCount++;
             array_unshift($values, $this->_rowCount);
             $this->_conflicts[] = $values;
         }
         if ($returnCode & self::NO_MATCH) {
             $this->_unMatchCount++;
             array_unshift($values, $this->_rowCount);
             $this->_unMatch[] = $values;
         }
         if ($returnCode & self::DUPLICATE) {
             if ($returnCode & self::MULTIPLE_DUPE) {
                 /* TODO: multi-dupes should be counted apart from singles
                  * on non-skip action */
             }
             $this->_duplicateCount++;
             array_unshift($values, $this->_rowCount);
             $this->_duplicates[] = $values;
             if ($onDuplicate != self::DUPLICATE_SKIP) {
                 $this->_validCount++;
             }
         }
         if ($returnCode & self::UNPARSED_ADDRESS_WARNING) {
             $this->_unparsedAddressCount++;
             array_unshift($values, $this->_rowCount);
             $this->_unparsedAddresses[] = $values;
         }
         // we give the derived class a way of aborting the process
         // note that the return code could be multiple code or'ed together
         if ($returnCode & self::STOP) {
             break;
         }
         // if we are done processing the maxNumber of lines, break
         if ($this->_maxLinesToProcess > 0 && $this->_validCount >= $this->_maxLinesToProcess) {
             break;
         }
         // clean up memory from dao's
         CRM_Core_DAO::freeResult();
         // see if we've hit our timeout yet
         /* if ( $the_thing_with_the_stuff ) {
                do_something( );
            } */
     }
     if ($mode == self::MODE_PREVIEW || $mode == self::MODE_IMPORT) {
         $customHeaders = $mapper;
         $customfields = CRM_Core_BAO_CustomField::getFields($this->_contactType);
         foreach ($customHeaders as $key => $value) {
             if ($id = CRM_Core_BAO_CustomField::getKeyID($value)) {
                 $customHeaders[$key] = $customfields[$id][0];
             }
         }
         if ($this->_invalidRowCount) {
             // removed view url for invlaid contacts
             $headers = array_merge(array(ts('Line Number'), ts('Reason')), $customHeaders);
             $this->_errorFileName = self::errorFileName(self::ERROR);
             self::exportCSV($this->_errorFileName, $headers, $this->_errors);
         }
         if ($this->_conflictCount) {
             $headers = array_merge(array(ts('Line Number'), ts('Reason')), $customHeaders);
             $this->_conflictFileName = self::errorFileName(self::CONFLICT);
             self::exportCSV($this->_conflictFileName, $headers, $this->_conflicts);
         }
         if ($this->_duplicateCount) {
             $headers = array_merge(array(ts('Line Number'), ts('View Contact URL')), $customHeaders);
             $this->_duplicateFileName = self::errorFileName(self::DUPLICATE);
             self::exportCSV($this->_duplicateFileName, $headers, $this->_duplicates);
         }
         if ($this->_unMatchCount) {
             $headers = array_merge(array(ts('Line Number'), ts('Reason')), $customHeaders);
             $this->_misMatchFilemName = self::errorFileName(self::NO_MATCH);
             self::exportCSV($this->_misMatchFilemName, $headers, $this->_unMatch);
         }
         if ($this->_unparsedAddressCount) {
             $headers = array_merge(array(ts('Line Number'), ts('Contact Edit URL')), $customHeaders);
             $this->_errorFileName = self::errorFileName(self::UNPARSED_ADDRESS_WARNING);
             self::exportCSV($this->_errorFileName, $headers, $this->_unparsedAddresses);
         }
     }
     //echo "$this->_totalCount,$this->_invalidRowCount,$this->_conflictCount,$this->_duplicateCount";
     return $this->fini();
 }
Exemple #8
0
 /**
  * This function acts as a listener to dao->update whenever there is an update,
  * and propagates any changes to all related entities present in recurring entity table
  *
  * @param object $event
  *   An object of /Civi/Core/DAO/Event/PostUpdate containing dao object that was just updated .
  *
  *
  * @return void
  */
 public static function triggerUpdate($event)
 {
     // if DB version is earlier than 4.6 skip any processing
     static $currentVer = NULL;
     if (!$currentVer) {
         $currentVer = CRM_Core_BAO_Domain::version();
     }
     if (version_compare($currentVer, '4.6.alpha1') < 0) {
         return;
     }
     static $processedEntities = array();
     $obj =& $event->object;
     if (empty($obj->id) || empty($obj->__table)) {
         return FALSE;
     }
     $key = "{$obj->__table}_{$obj->id}";
     if (array_key_exists($key, $processedEntities)) {
         // already processed
         return NULL;
     }
     // get related entities
     $repeatingEntities = self::getEntitiesFor($obj->id, $obj->__table, FALSE, NULL);
     if (empty($repeatingEntities)) {
         // return if its not a recurring entity parent
         return NULL;
     }
     // mark being processed
     $processedEntities[$key] = 1;
     // to make sure we not copying to source itself
     unset($repeatingEntities[$key]);
     foreach ($repeatingEntities as $key => $val) {
         $entityID = $val['id'];
         $entityTable = $val['table'];
         $processedEntities[$key] = 1;
         if (array_key_exists($entityTable, self::$_tableDAOMapper)) {
             $daoName = self::$_tableDAOMapper[$entityTable];
             $skipData = array();
             if (array_key_exists($entityTable, self::$_updateSkipFields)) {
                 $skipFields = self::$_updateSkipFields[$entityTable];
                 foreach ($skipFields as $sfield) {
                     $skipData[$sfield] = NULL;
                 }
             }
             $updateDAO = CRM_Core_DAO::cascadeUpdate($daoName, $obj->id, $entityID, $skipData);
             CRM_Core_DAO::freeResult();
         } else {
             CRM_Core_Error::fatal("DAO Mapper missing for {$entityTable}.");
         }
     }
     // done with processing. lets unset static var.
     unset($processedEntities);
 }
Exemple #9
0
 /**
  * Delete a contact and all its associated records
  * 
  * @param  int  $id id of the contact to delete
  *
  * @return boolean true if contact deleted, false otherwise
  * @access public
  * @static
  */
 function deleteContact($id)
 {
     require_once 'CRM/Activity/BAO/Activity.php';
     if (!$id) {
         return false;
     }
     // make sure we have edit permission for this contact
     // before we delete
     require_once 'CRM/Contact/BAO/Contact/Permission.php';
     if (!CRM_Core_Permission::check('delete contacts')) {
         return false;
     }
     // make sure this contact_id does not have any membership types
     $membershipTypeID = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $id, 'id', 'member_of_contact_id');
     if ($membershipTypeID) {
         return false;
     }
     $contact =& new CRM_Contact_DAO_Contact();
     $contact->id = $id;
     if (!$contact->find(true)) {
         return false;
     }
     $contactType = $contact->contact_type;
     // currently we only clear employer cache.
     // we are not deleting inherited membership if any.
     if ($contact->contact_type == 'Organization') {
         require_once 'CRM/Contact/BAO/Contact/Utils.php';
         CRM_Contact_BAO_Contact_Utils::clearAllEmployee($id);
     }
     require_once 'CRM/Utils/Hook.php';
     CRM_Utils_Hook::pre('delete', $contactType, $id, CRM_Core_DAO::$_nullArray);
     // start a new transaction
     require_once 'CRM/Core/Transaction.php';
     $transaction = new CRM_Core_Transaction();
     //delete billing address if exists.
     require_once 'CRM/Contribute/BAO/Contribution.php';
     CRM_Contribute_BAO_Contribution::deleteAddress(null, $id);
     // delete the log entries since we dont have triggers enabled as yet
     require_once 'CRM/Core/DAO/Log.php';
     $logDAO =& new CRM_Core_DAO_Log();
     $logDAO->entity_table = 'civicrm_contact';
     $logDAO->entity_id = $id;
     $logDAO->delete();
     $contact->delete();
     //delete the contact id from recently view
     require_once 'CRM/Utils/Recent.php';
     CRM_Utils_Recent::delContact($id);
     // reset the group contact cache for this group
     require_once 'CRM/Contact/BAO/GroupContactCache.php';
     CRM_Contact_BAO_GroupContactCache::remove();
     $transaction->commit();
     CRM_Utils_Hook::post('delete', $contactType, $contact->id, $contact);
     // also reset the DB_DO global array so we can reuse the memory
     // http://issues.civicrm.org/jira/browse/CRM-4387
     CRM_Core_DAO::freeResult();
     return true;
 }
Exemple #10
0
 /**
  * Dedupe a pair of contacts.
  *
  * @param array $migrationInfo
  * @param array $resultStats
  * @param array $deletedContacts
  * @param string $mode
  * @param bool $checkPermissions
  * @param int $mainId
  * @param int $otherId
  * @param string $cacheKeyString
  */
 protected static function dedupePair(&$migrationInfo, &$resultStats, &$deletedContacts, $mode, $checkPermissions, $mainId, $otherId, $cacheKeyString)
 {
     // go ahead with merge if there is no conflict
     $conflicts = array();
     if (!CRM_Dedupe_Merger::skipMerge($mainId, $otherId, $migrationInfo, $mode, $conflicts)) {
         CRM_Dedupe_Merger::moveAllBelongings($mainId, $otherId, $migrationInfo, $checkPermissions);
         $resultStats['merged'][] = array('main_id' => $mainId, 'other_id' => $otherId);
         $deletedContacts[] = $otherId;
     } else {
         $resultStats['skipped'][] = array('main_id' => $mainId, 'other_id' => $otherId);
     }
     // store any conflicts
     if (!empty($conflicts)) {
         foreach ($conflicts as $key => $dnc) {
             $conflicts[$key] = "{$migrationInfo['rows'][$key]['title']}: '{$migrationInfo['rows'][$key]['main']}' vs. '{$migrationInfo['rows'][$key]['other']}'";
         }
         CRM_Core_BAO_PrevNextCache::markConflict($mainId, $otherId, $cacheKeyString, $conflicts);
     } else {
         // delete entry from PrevNextCache table so we don't consider the pair next time
         // pair may have been flipped, so make sure we delete using both orders
         CRM_Core_BAO_PrevNextCache::deletePair($mainId, $otherId, $cacheKeyString, TRUE);
     }
     CRM_Core_DAO::freeResult();
 }
 /**
  * Delete a contact and all its associated records
  *
  * @param  int  $id id of the contact to delete
  * @param  bool $restore       whether to actually restore, not delete
  * @param  bool $skipUndelete  whether to force contact delete or not
  *
  * @return boolean true if contact deleted, false otherwise
  * @access public
  * @static
  */
 static function deleteContact($id, $restore = FALSE, $skipUndelete = FALSE)
 {
     if (!$id) {
         return FALSE;
     }
     // make sure we have edit permission for this contact
     // before we delete
     if ($skipUndelete && !CRM_Core_Permission::check('delete contacts') || $restore && !CRM_Core_Permission::check('access deleted contacts')) {
         return FALSE;
     }
     // make sure this contact_id does not have any membership types
     $membershipTypeID = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $id, 'id', 'member_of_contact_id');
     if ($membershipTypeID) {
         return FALSE;
     }
     $contact = new CRM_Contact_DAO_Contact();
     $contact->id = $id;
     if (!$contact->find(TRUE)) {
         return FALSE;
     }
     $contactType = $contact->contact_type;
     $action = $restore ? 'restore' : 'delete';
     CRM_Utils_Hook::pre($action, $contactType, $id, CRM_Core_DAO::$_nullArray);
     if ($restore) {
         self::contactTrashRestore($contact, TRUE);
         CRM_Utils_Hook::post($action, $contactType, $contact->id, $contact);
         return TRUE;
     }
     // currently we only clear employer cache.
     // we are not deleting inherited membership if any.
     if ($contact->contact_type == 'Organization') {
         CRM_Contact_BAO_Contact_Utils::clearAllEmployee($id);
     }
     // start a new transaction
     $transaction = new CRM_Core_Transaction();
     $config = CRM_Core_Config::singleton();
     if ($skipUndelete or !$config->contactUndelete) {
         //delete billing address if exists.
         CRM_Contribute_BAO_Contribution::deleteAddress(NULL, $id);
         // delete the log entries since we dont have triggers enabled as yet
         $logDAO = new CRM_Core_DAO_Log();
         $logDAO->entity_table = 'civicrm_contact';
         $logDAO->entity_id = $id;
         $logDAO->delete();
         // do activity cleanup, CRM-5604
         CRM_Activity_BAO_Activity::cleanupActivity($id);
         // delete all notes related to contact
         CRM_Core_BAO_Note::cleanContactNotes($id);
         $contact->delete();
     } else {
         self::contactTrashRestore($contact);
     }
     //delete the contact id from recently view
     CRM_Utils_Recent::delContact($id);
     // reset the group contact cache for this group
     CRM_Contact_BAO_GroupContactCache::remove();
     // delete any dupe cache entry
     CRM_Core_BAO_PrevNextCache::deleteItem($id);
     $transaction->commit();
     CRM_Utils_Hook::post('delete', $contactType, $contact->id, $contact);
     // also reset the DB_DO global array so we can reuse the memory
     // http://issues.civicrm.org/jira/browse/CRM-4387
     CRM_Core_DAO::freeResult();
     return TRUE;
 }