/drupal/sites/all/modules/civicrm/CRM/Import/Parser/Contact.php
PHP | 1958 lines | 1423 code | 211 blank | 324 comment | 444 complexity | d52b784251cc6b633e913135b424aefd MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-1.0, LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- <?php
- /*
- +--------------------------------------------------------------------+
- | CiviCRM version 3.4 |
- +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2011 |
- +--------------------------------------------------------------------+
- | This file is a part of CiviCRM. |
- | |
- | CiviCRM is free software; you can copy, modify, and distribute it |
- | under the terms of the GNU Affero General Public License |
- | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
- | |
- | CiviCRM is distributed in the hope that it will be useful, but |
- | WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
- | See the GNU Affero General Public License for more details. |
- | |
- | You should have received a copy of the GNU Affero General Public |
- | License and the CiviCRM Licensing Exception along |
- | with this program; if not, contact CiviCRM LLC |
- | at info[AT]civicrm[DOT]org. If you have questions about the |
- | GNU Affero General Public License or the licensing of CiviCRM, |
- | see the CiviCRM license FAQ at http://civicrm.org/licensing |
- +--------------------------------------------------------------------+
- */
- /**
- *
- * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2011
- * $Id$
- *
- */
- require_once 'CRM/Import/Parser.php';
- civicrm_api_include('utils', false, 2);
- /**
- * class to parse contact csv files
- */
- class CRM_Import_Parser_Contact extends CRM_Import_Parser
- {
- protected $_mapperKeys;
- protected $_mapperLocType;
- protected $_mapperPhoneType;
- protected $_mapperImProvider;
- protected $_mapperWebsiteType;
- protected $_mapperRelated;
- protected $_mapperRelatedContactType;
- protected $_mapperRelatedContactDetails;
- protected $_mapperRelatedContactEmailType;
- protected $_mapperRelatedContactImProvider;
- protected $_mapperRelatedContactWebsiteType;
- protected $_relationships;
- protected $_emailIndex;
- protected $_firstNameIndex;
- protected $_lastNameIndex;
- protected $_householdNameIndex;
- protected $_organizationNameIndex;
- protected $_allEmails;
- protected $_phoneIndex;
- protected $_updateWithId;
- protected $_retCode;
- protected $_externalIdentifierIndex;
- protected $_allExternalIdentifiers;
- protected $_parseStreetAddress;
- /**
- * Array of succesfully imported contact id's
- *
- * @array
- */
- protected $_newContacts;
- /**
- * line count id
- *
- * @var int
- */
- protected $_lineCount;
- /**
- * Array of succesfully imported related contact id's
- *
- * @array
- */
- protected $_newRelatedContacts;
- /**
- * array of all the contacts whose street addresses are not parsed
- * of this import process
- * @var array
- */
- protected $_unparsedStreetAddressContacts;
- /**
- * class constructor
- */
- function __construct( &$mapperKeys, $mapperLocType = null, $mapperPhoneType = null,
- $mapperImProvider = null, $mapperRelated = null, $mapperRelatedContactType=null,
- $mapperRelatedContactDetails = null, $mapperRelatedContactLocType = null,
- $mapperRelatedContactPhoneType = null, $mapperRelatedContactImProvider = null,
- $mapperWebsiteType = null, $mapperRelatedContactWebsiteType = null )
- {
- parent::__construct();
- $this->_mapperKeys =& $mapperKeys;
- $this->_mapperLocType =& $mapperLocType;
- $this->_mapperPhoneType =& $mapperPhoneType;
- $this->_mapperWebsiteType = $mapperWebsiteType;
- // get IM service provider type id for contact
- $this->_mapperImProvider =& $mapperImProvider;
- $this->_mapperRelated =& $mapperRelated;
- $this->_mapperRelatedContactType =& $mapperRelatedContactType;
- $this->_mapperRelatedContactDetails =& $mapperRelatedContactDetails;
- $this->_mapperRelatedContactLocType =& $mapperRelatedContactLocType;
- $this->_mapperRelatedContactPhoneType =& $mapperRelatedContactPhoneType;
- $this->_mapperRelatedContactWebsiteType = $mapperRelatedContactWebsiteType;
- // get IM service provider type id for related contact
- $this->_mapperRelatedContactImProvider =& $mapperRelatedContactImProvider;
- }
- /**
- * the initializer code, called before the processing
- *
- * @return void
- * @access public
- */
- function init( )
- {
- require_once 'CRM/Contact/BAO/Contact.php';
- require_once 'CRM/Core/BAO/Address.php';
- $contactFields = CRM_Contact_BAO_Contact::importableFields( $this->_contactType );
- // exclude the address options disabled in the Address Settings
- $fields = CRM_Core_BAO_Address::validateAddressOptions( $contactFields );
-
- //CRM-5125
- //supporting import for contact subtypes
- $csType = null;
- if ( !empty($this->_contactSubType) ) {
- //custom fields for sub type
- $subTypeFields = CRM_Core_BAO_CustomField::getFieldsForImport( $this->_contactSubType );
-
- if ( !empty($subTypeFields) ) {
- foreach($subTypeFields as $customSubTypeField => $details ) {
- $fields[$customSubTypeField] = $details;
- }
- }
- }
-
- //Relationship importables
- $this->_relationships = $relations = CRM_Contact_BAO_Relationship::getContactRelationshipType( null, null, null, $this->_contactType,
- false, 'label', true, $this->_contactSubType );
- asort($relations);
- foreach ($relations as $key => $var) {
- list( $type ) = explode( '_', $key );
- $relationshipType[$key]['title'] = $var;
- $relationshipType[$key]['headerPattern'] = '/' . preg_quote( $var, '/' ) . '/';
- $relationshipType[$key]['import'] = true;
- $relationshipType[$key]['relationship_type_id'] = $type;
- $relationshipType[$key]['related'] = true;
- }
- if ( !empty($relationshipType) ) {
- $fields = array_merge( $fields,
- array( 'related' => array( 'title' => ts('- related contact info -') ) ),
- $relationshipType );
- }
- foreach ($fields as $name => $field) {
- $this->addField( $name,
- $field['title'],
- CRM_Utils_Array::value( 'type' , $field ),
- CRM_Utils_Array::value( 'headerPattern' , $field ),
- CRM_Utils_Array::value( 'dataPattern' , $field ),
- CRM_Utils_Array::value( 'hasLocationType', $field ) );
- }
- $this->_newContacts = array( );
- $this->setActiveFields( $this->_mapperKeys );
- $this->setActiveFieldLocationTypes( $this->_mapperLocType );
- $this->setActiveFieldPhoneTypes( $this->_mapperPhoneType );
- $this->setActiveFieldWebsiteTypes( $this->_mapperWebsiteType );
- //set active fields of IM provider of contact
- $this->setActiveFieldImProviders( $this->_mapperImProvider );
- //related info
- $this->setActiveFieldRelated( $this->_mapperRelated );
- $this->setActiveFieldRelatedContactType( $this->_mapperRelatedContactType );
- $this->setActiveFieldRelatedContactDetails( $this->_mapperRelatedContactDetails );
- $this->setActiveFieldRelatedContactLocType( $this->_mapperRelatedContactLocType );
- $this->setActiveFieldRelatedContactPhoneType( $this->_mapperRelatedContactPhoneType );
- $this->setActiveFieldRelatedContactWebsiteType( $this->_mapperRelatedContactWebsiteType );
- //set active fields of IM provider of related contact
- $this->setActiveFieldRelatedContactImProvider( $this->_mapperRelatedContactImProvider );
-
- $this->_phoneIndex = -1;
- $this->_emailIndex = -1;
- $this->_firstNameIndex = -1;
- $this->_lastNameIndex = -1;
- $this->_householdNameIndex = -1;
- $this->_organizationNameIndex = -1;
- $this->_externalIdentifierIndex = -1;
-
- $index = 0 ;
- foreach ( $this->_mapperKeys as $key ) {
- if ( substr( $key, 0, 5 ) == 'email' && substr( $key, 0, 14 ) != 'email_greeting') {
- $this->_emailIndex = $index;
- $this->_allEmails = array( );
- }
- if ( substr( $key, 0, 5 ) == 'phone' ) {
- $this->_phoneIndex = $index;
- }
- if ( $key == 'first_name' ) {
- $this->_firstNameIndex = $index;
- }
- if ( $key == 'last_name' ) {
- $this->_lastNameIndex = $index;
- }
- if ( $key == 'household_name' ) {
- $this->_householdNameIndex = $index;
- }
- if ( $key == 'organization_name' ) {
- $this->_organizationNameIndex = $index;
- }
-
- if ( $key == 'external_identifier' ) {
- $this->_externalIdentifierIndex = $index;
- $this->_allExternalIdentifiers = array( );
- }
- $index++;
- }
-
- $this->_updateWithId = false;
- if ( in_array('id', $this->_mapperKeys ) ||
- ( $this->_externalIdentifierIndex >= 0 &&
- in_array( $this->_onDuplicate, array( CRM_Import_Parser::DUPLICATE_UPDATE, CRM_Import_Parser::DUPLICATE_FILL ) ) ) ) {
- $this->_updateWithId = true;
- }
-
- require_once 'CRM/Core/BAO/Preferences.php';
- $this->_parseStreetAddress = CRM_Utils_Array::value( 'street_address_parsing',
- CRM_Core_BAO_Preferences::valueOptions( 'address_options' ),
- false );
- }
- /**
- * handle the values in mapField mode
- *
- * @param array $values the array of values belonging to this line
- *
- * @return boolean
- * @access public
- */
- function mapField( &$values )
- {
- return CRM_Import_Parser::VALID;
- }
- /**
- * handle the values in preview mode
- *
- * @param array $values the array of values belonging to this line
- *
- * @return boolean the result of this processing
- * @access public
- */
- function preview( &$values )
- {
- return $this->summary($values);
- }
- /**
- * handle the values in summary mode
- *
- * @param array $values the array of values belonging to this line
- *
- * @return boolean the result of this processing
- * @access public
- */
- function summary( &$values )
- {
- $response = $this->setActiveFieldValues( $values );
-
- $errorMessage = null;
- $errorRequired = false;
- switch ($this->_contactType) {
-
- case 'Individual' :
- $missingNames = array( );
- if ( $this->_firstNameIndex < 0 ||
- !CRM_Utils_Array::value( $this->_firstNameIndex, $values ) ) {
- $errorRequired = true;
- $missingNames[] = ts('First Name');
- }
- if ( $this->_lastNameIndex < 0 ||
- !CRM_Utils_Array::value( $this->_lastNameIndex, $values ) ) {
- $errorRequired = true;
- $missingNames[] = ts('Last Name');
- }
- if ( $errorRequired ) {
- $and = ' ' . ts('and') . ' ';
- $errorMessage = ts('Missing required fields:') . ' ' . implode( $and, $missingNames );
- }
- break;
-
- case 'Household' :
- if ( $this->_householdNameIndex < 0 ||
- !CRM_Utils_Array::value( $this->_householdNameIndex, $values ) ) {
- $errorRequired = true;
- $errorMessage = ts('Missing required fields:') . ' ' . ts('Household Name');
- }
- break;
-
- case 'Organization' :
- if ( $this->_organizationNameIndex < 0 ||
- !CRM_Utils_Array::value( $this->_organizationNameIndex, $values ) ) {
- $errorRequired = true;
- $errorMessage = ts('Missing required fields:') . ' ' . ts('Organization Name');
- }
- break;
- }
-
- $statusFieldName = $this->_statusFieldName;
- if ( $this->_emailIndex >= 0 ) {
- /* If we don't have the required fields, bail */
- if ($this->_contactType == 'Individual' &&! $this->_updateWithId ) {
- if ($errorRequired && ! CRM_Utils_Array::value($this->_emailIndex, $values)) {
- if ( $errorMessage ) {
- $errorMessage .= ' ' . ts('OR') . ' ' . ts('Email Address');
- } else {
- $errorMessage = ts('Missing required field:') . ' ' . ts('Email Address');
- }
- array_unshift($values, $errorMessage);
- $importRecordParams = array($statusFieldName => 'ERROR', "${statusFieldName}Msg" => $errorMessage);
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
-
- return CRM_Import_Parser::ERROR;
- }
- }
-
- $email = CRM_Utils_Array::value( $this->_emailIndex, $values );
- if ( $email ) {
- /* If the email address isn't valid, bail */
- if (! CRM_Utils_Rule::email($email)) {
- $errorMessage = ts('Invalid Email address');
- array_unshift($values, $errorMessage);
- $importRecordParams = array($statusFieldName => 'ERROR', "${statusFieldName}Msg" => $errorMessage);
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
-
- return CRM_Import_Parser::ERROR;
- }
- /* otherwise, count it and move on */
- $this->_allEmails[$email] = $this->_lineCount;
- }
- } else if ($errorRequired && ! $this->_updateWithId) {
- if ( $errorMessage ) {
- $errorMessage .= ' ' . ts('OR') . ' ' . ts('Email Address');
- } else {
- $errorMessage = ts('Missing required field:') . ' ' . ts('Email Address');
- }
- array_unshift($values, $errorMessage);
- $importRecordParams = array($statusFieldName => 'ERROR', "${statusFieldName}Msg" => $errorMessage);
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
-
- return CRM_Import_Parser::ERROR;
- }
-
- //check for duplicate external Identifier
- $externalID = CRM_Utils_Array::value( $this->_externalIdentifierIndex, $values );
- if ( $externalID ) {
- /* If it's a dupe,external Identifier */
- if ( $externalDupe = CRM_Utils_Array::value( $externalID,
- $this->_allExternalIdentifiers ) ) {
- $errorMessage = ts('External Identifier conflicts with record %1', array(1 => $externalDupe));
- array_unshift($values, $errorMessage);
- $importRecordParams = array($statusFieldName => 'ERROR', "${statusFieldName}Msg" => $errorMessage);
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
- return CRM_Import_Parser::ERROR;
- }
- //otherwise, count it and move on
- $this->_allExternalIdentifiers[$externalID] = $this->_lineCount;
- }
- //Checking error in custom data
- $params =& $this->getActiveFieldParams( );
- $params['contact_type'] = $this->_contactType;
- //date-format part ends
- $errorMessage = null;
-
- //checking error in custom data
-
- $this->isErrorInCustomData($params, $errorMessage);
- //checking error in core data
- $this->isErrorInCoreData($params, $errorMessage);
- if ( $errorMessage ) {
- $tempMsg = "Invalid value for field(s) : $errorMessage";
- // put the error message in the import record in the DB
- $importRecordParams = array($statusFieldName => 'ERROR', "${statusFieldName}Msg" => $tempMsg);
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
- array_unshift($values, $tempMsg);
- $errorMessage = null;
- return CRM_Import_Parser::ERROR;
- }
-
- //if user correcting errors by walking back
- //need to reset status ERROR msg to null
- //now currently we are having valid data.
- $importRecordParams = array( $statusFieldName => 'NEW' );
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
-
- return CRM_Import_Parser::VALID;
- }
- /**
- * handle the values in import mode
- *
- * @param int $onDuplicate the code for what action to take on duplicates
- * @param array $values the array of values belonging to this line
- *
- * @return boolean the result of this processing
- * @access public
- */
- function import( $onDuplicate, &$values, $doGeocodeAddress = false )
- {
- $config =& CRM_Core_Config::singleton( );
- $this->_unparsedStreetAddressContacts = array( );
- if ( ! $doGeocodeAddress ) {
- // CRM-5854, reset the geocode method to null to prevent geocoding
- $config->geocodeMethod = null;
- }
- // first make sure this is a valid line
- //$this->_updateWithId = false;
- $response = $this->summary( $values );
-
- $statusFieldName = $this->_statusFieldName;
-
- if ( $response != CRM_Import_Parser::VALID ) {
- $importRecordParams = array($statusFieldName => 'INVALID', "${statusFieldName}Msg" => "Invalid (Error Code: $response)");
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
- return $response;
- }
-
- $params =& $this->getActiveFieldParams( );
- $formatted = array('contact_type' => $this->_contactType);
-
- static $contactFields = null;
- if ( $contactFields == null) {
- require_once "CRM/Contact/DAO/Contact.php";
- $contactFields =& CRM_Contact_DAO_Contact::import( );
- }
-
- //check if external identifier exists in database
- if ( CRM_Utils_Array::value('external_identifier', $params ) &&
- ( CRM_Utils_Array::value('id', $params ) ||
- in_array( $onDuplicate, array( CRM_Import_Parser::DUPLICATE_SKIP, CRM_Import_Parser::DUPLICATE_NOCHECK ) ) ) ) {
-
- require_once "CRM/Contact/BAO/Contact.php";
- if ( $internalCid = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $params['external_identifier'],
- 'id',
- 'external_identifier' ) ) {
- if ( $internalCid != CRM_Utils_Array::value('id', $params) ) {
-
- $errorMessage = ts('External Identifier already exists in database.');
- array_unshift($values, $errorMessage);
- $importRecordParams = array($statusFieldName => 'ERROR', "${statusFieldName}Msg" => $errorMessage);
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
- return CRM_Import_Parser::DUPLICATE;
- }
- }
- }
-
- if ( !empty($this->_contactSubType) ) {
- $params['contact_sub_type'] = $this->_contactSubType;
- }
-
- if ( $subType = CRM_Utils_Array::value('contact_sub_type', $params) ) {
- if ( CRM_Contact_BAO_ContactType::isExtendsContactType($subType, $this->_contactType,false,'label') ) {
- $subTypes = CRM_Contact_BAO_ContactType::subTypePairs($this->_contactType, false, null );
- $params['contact_sub_type'] = array_search( $subType ,$subTypes );
- } elseif ( !CRM_Contact_BAO_ContactType::isExtendsContactType($subType, $this->_contactType) ) {
- $message = "Mismatched or Invalid Contact SubType.";
- array_unshift($values, $message);
- return CRM_Import_Parser::NO_MATCH;
- }
- }
-
- //get contact id to format common data in update/fill mode,
- //if external identifier is present, CRM-4423
- if ( $this->_updateWithId &&
- ! CRM_Utils_Array::value( 'id', $params ) &&
- CRM_Utils_Array::value( 'external_identifier', $params ) ) {
- if ( $cid = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $params['external_identifier'], 'id',
- 'external_identifier' ) ) {
- $formatted['id'] = $cid;
- }
- }
-
- //format common data, CRM-4062
- $this->formatCommonData( $params, $formatted, $contactFields );
-
- $relationship = false;
- $createNewContact = true;
- // Support Match and Update Via Contact ID
- if ( $this->_updateWithId ) {
- $createNewContact = false;
- if ( !CRM_Utils_Array::value('id', $params) && CRM_Utils_Array::value('external_identifier', $params) ) {
- if ( $cid ) {
- $params['id'] = $cid;
- } else {
- //update contact if dedupe found contact id, CRM-4148
- $dedupeParams = $formatted;
-
- //special case to check dedupe if external id present.
- //if we send external id dedupe will stop.
- unset( $dedupeParams['external_identifier'] );
-
- $checkDedupe = _civicrm_duplicate_formatted_contact( $dedupeParams );
- if ( civicrm_duplicate( $checkDedupe ) ) {
- $matchingContactIds = explode( ',', $checkDedupe['error_message']['params'][0] );
- if ( count( $matchingContactIds ) == 1 ) {
- $params['id'] = array_pop( $matchingContactIds );
- } else {
- $message = "More than one matching contact found for given criteria.";
- array_unshift($values, $message);
- $this->_retCode = CRM_Import_Parser::NO_MATCH;
- }
- } else {
- $createNewContact = true;
- }
- }
- }
-
- $error = _civicrm_duplicate_formatted_contact($formatted);
- if ( civicrm_duplicate($error) ) {
- $matchedIDs = explode( ',', $error['error_message']['params'][0] );
- if ( count( $matchedIDs) >= 1 ) {
- $updateflag = true;
- foreach ($matchedIDs as $contactId) {
- if ($params['id'] == $contactId) {
- $contactType = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $params['id'],
- 'contact_type' );
-
- if ($formatted['contact_type'] == $contactType ) {
-
- //validation of subtype for update mode
- //CRM-5125
- $contactSubType = null;
- if ( CRM_Utils_Array::value('contact_sub_type', $params) ) {
- $contactSubType = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $params['id'],
- 'contact_sub_type' );
- }
-
- if ( !empty($contactSubType) &&
- ( !CRM_Contact_BAO_ContactType::isAllowEdit($params['id'], $contactSubType) &&
- $contactSubType != CRM_Utils_Array::value('contact_sub_type', $formatted) ) ) {
-
- $message = "Mismatched contact SubTypes :";
- array_unshift($values, $message);
- $updateflag = false;
- $this->_retCode = CRM_Import_Parser::NO_MATCH;
- } else {
-
- $newContact = $this->createContact( $formatted, $contactFields,
- $onDuplicate, $contactId, false );
- $updateflag = false;
- $this->_retCode = CRM_Import_Parser::VALID;
- }
- } else {
- $message = "Mismatched contact Types :";
- array_unshift($values, $message);
- $updateflag = false;
- $this->_retCode = CRM_Import_Parser::NO_MATCH;
- }
- }
- }
- if ( $updateflag ) {
- $message = "Mismatched contact IDs OR Mismatched contact Types :" ;
- array_unshift($values, $message);
- $this->_retCode = CRM_Import_Parser::NO_MATCH;
- }
- }
- } else {
- $contactType = null;
- if ( CRM_Utils_Array::value( 'id', $params ) ) {
- $contactType = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $params['id'],
- 'contact_type' );
- if ( $contactType ) {
- if ($formatted['contact_type'] == $contactType ) {
- //validation of subtype for update mode
- //CRM-5125
- $contactSubType = null;
- if ( CRM_Utils_Array::value('contact_sub_type', $params) ) {
- $contactSubType = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $params['id'],
- 'contact_sub_type' );
- }
-
- if ( !empty($contactSubType) &&
- (!CRM_Contact_BAO_ContactType::isAllowEdit($params['id'], $contactSubType) &&
- $contactSubType != CRM_Utils_Array::value('contact_sub_type', $formatted) ) ) {
-
- $message = "Mismatched contact SubTypes :";
- array_unshift($values, $message);
- $this->_retCode = CRM_Import_Parser::NO_MATCH;
- } else {
- $newContact = $this->createContact( $formatted, $contactFields,
- $onDuplicate, $params['id'], false );
-
- $this->_retCode = CRM_Import_Parser::VALID;
- }
- } else {
- $message = "Mismatched contact Types :";
- array_unshift($values, $message);
- $this->_retCode = CRM_Import_Parser::NO_MATCH;
- }
- } else {
- // we should avoid multiple errors for single record
- // since we have already retCode and we trying to force again.
- if ( $this->_retCode != CRM_Import_Parser::NO_MATCH ) {
- $message ="No contact found for this contact ID:".$params['id'] ;
- array_unshift($values, $message);
- $this->_retCode = CRM_Import_Parser::NO_MATCH;
- }
- }
- } else {
- //CRM-4148
- //now we want to create new contact on update/fill also.
- $createNewContact = true;
- }
- }
-
- if (is_a( $newContact, 'CRM_Contact_BAO_Contact' )) {
- $relationship = true;
- } else if (is_a( $error, 'CRM_Core_Error' )) {
- $newContact = $error;
- $relationship = true;
- }
- }
-
- //fixed CRM-4148
- //now we create new contact in update/fill mode also.
- if ( $createNewContact ) {
-
- //CRM-4430, don't carry if not submitted.
- foreach ( array( 'prefix', 'suffix', 'gender' ) as $name ) {
- if ( array_key_exists( $name, $formatted ) ) {
- if ( in_array( $name, array( 'prefix', 'suffix' ) ) ) {
- $formattedName = "individual_{$name}";
- $formatted[$formattedName] = CRM_Core_OptionGroup::getValue( $formattedName, (string)$formatted[$name] );
- } else {
- $formatted[$name] = CRM_Core_OptionGroup::getValue( $name, (string)$formatted[$name] );
- }
- }
- }
- $newContact = $this->createContact( $formatted, $contactFields, $onDuplicate );
- }
- $contactID = null;
- if ( is_object( $newContact ) || ( $newContact instanceof CRM_Contact_BAO_Contact ) ) {
- $relationship = true;
- $newContact = clone( $newContact );
- $contactID = $newContact->id;
- $this->_newContacts[] = $contactID;
-
- //get return code if we create new contact in update mode, CRM-4148
- if ( $this->_updateWithId ) {
- $this->_retCode = CRM_Import_Parser::VALID;
- }
- } else if ( civicrm_duplicate( $newContact ) ) {
- // if duplicate, no need of further processing
- if ( $onDuplicate == CRM_Import_Parser::DUPLICATE_SKIP ) {
- $errorMessage = "Skipping duplicate record";
- array_unshift( $values, $errorMessage );
- $importRecordParams = array( $statusFieldName => 'DUPLICATE', "${statusFieldName}Msg" => $errorMessage );
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
- return CRM_Import_Parser::DUPLICATE;
- }
-
- $relationship = true;
- $contactID = $newContact['error_message']['params'][0];
- if ( !in_array( $contactID, $this->_newContacts ) ) {
- $this->_newContacts[] = $contactID;
- }
- }
-
- if ( $contactID ) {
- // call import hook
- require_once 'CRM/Utils/Hook.php';
- $currentImportID = end($values);
-
- $hookParams = array( 'contactID' => $contactID,
- 'importID' => $currentImportID,
- 'importTempTable' => $this->_tableName,
- 'fieldHeaders' => $this->_mapperKeys,
- 'fields' => $this->_activeFields );
-
- CRM_Utils_Hook::import( 'Contact',
- 'process',
- $this,
- $hookParams );
- }
- if ( $relationship ) {
- $primaryContactId = null;
- if ( civicrm_duplicate($newContact) ) {
- if ( CRM_Utils_Rule::integer( $newContact['error_message']['params'][0] ) ) {
- $primaryContactId = $newContact['error_message']['params'][0];
- }
- } else {
- $primaryContactId = $newContact->id;
- }
-
- if ( ( civicrm_duplicate($newContact) || is_a( $newContact, 'CRM_Contact_BAO_Contact' ) )
- && $primaryContactId ) {
-
- //relationship contact insert
- foreach ($params as $key => $field) {
- list($id, $first, $second) = CRM_Utils_System::explode('_', $key, 3);
- if ( !($first == 'a' && $second == 'b') && !($first == 'b' && $second == 'a') ) {
- continue;
- }
-
- $relationType = new CRM_Contact_DAO_RelationshipType();
- $relationType->id = $id;
- $relationType->find(true);
- $direction = "contact_sub_type_$second";
-
- $formatting = array('contact_type' => $params[$key]['contact_type']);
-
- //set subtype for related contact CRM-5125
- if ( isset($relationType->$direction) ) {
- //validation of related contact subtype for update mode
- if ( $relCsType = CRM_Utils_Array::value('contact_sub_type', $params[$key])
- && $relCsType != $relationType->$direction ) {
- $errorMessage = ts( "Mismatched or Invalid contact subtype found for this related contact" );
- array_unshift($values, $errorMessage);
- return CRM_Import_Parser::NO_MATCH;
- } else {
- $formatting['contact_sub_type'] = $relationType->$direction;
- }
- }
- $relationType->free( );
-
- $contactFields = null;
- $contactFields = CRM_Contact_DAO_Contact::import( );
-
- //Relation on the basis of External Identifier.
- if ( !CRM_Utils_Array::value( 'id' , $params[$key] ) && !empty( $params[$key]['external_identifier'] ) ) {
- $params[$key]['id'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
- $params[$key]['external_identifier'],'id',
- 'external_identifier' );
- }
- // check for valid related contact id in update/fill mode, CRM-4424
- if ( in_array( $onDuplicate,
- array( CRM_Import_Parser::DUPLICATE_UPDATE,
- CRM_Import_Parser::DUPLICATE_FILL ) ) &&
- CRM_Utils_Array::value( 'id', $params[$key] ) ) {
- $relatedContactType = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $params[$key]['id'],
- 'contact_type' );
- if ( ! $relatedContactType ) {
- $errorMessage = ts( "No contact found for this related contact ID: %1", array( 1 => $params[$key]['id'] ) );
- array_unshift($values, $errorMessage);
- return CRM_Import_Parser::NO_MATCH;
- } else {
- //validation of related contact subtype for update mode
- //CRM-5125
- $relatedCsType = null;
- if ( CRM_Utils_Array::value('contact_sub_type', $formatting) ) {
- $relatedCsType = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $params[$key]['id'],
- 'contact_sub_type' );
- }
-
- if ( !empty($relatedCsType) &&
- (!CRM_Contact_BAO_ContactType::isAllowEdit($params[$key]['id'], $relatedCsType) &&
- $relatedCsType != CRM_Utils_Array::value( 'contact_sub_type', $formatting ) ) ) {
- $errorMessage = ts( "Mismatched or Invalid contact subtype found for this related contact ID: %1", array( 1 => $params[$key]['id'] ) );
- array_unshift($values, $errorMessage);
- return CRM_Import_Parser::NO_MATCH;
- } else {
- // get related contact id to format data in update/fill mode,
- //if external identifier is present, CRM-4423
- $formatting['id'] = $params[$key]['id'];
- }
- }
- }
-
- //format common data, CRM-4062
- $this->formatCommonData( $field, $formatting, $contactFields );
- //do we have enough fields to create related contact.
- $allowToCreate = $this->checkRelatedContactFields( $key, $formatting );
-
- if ( !$allowToCreate ) {
- $errorMessage = ts( 'Related contact required fields are missing.' );
- array_unshift($values, $errorMessage);
- return CRM_Import_Parser::NO_MATCH;
- }
-
- //fixed for CRM-4148
- if ( $params[$key]['id'] ) {
- $contact = array( 'contact_id' => $params[$key]['id'] );
- $defaults = array( );
- $relatedNewContact = CRM_Contact_BAO_Contact::retrieve( $contact, $defaults );
- } else {
- $relatedNewContact = $this->createContact( $formatting, $contactFields,
- $onDuplicate, null, false );
- }
-
- if ( is_object( $relatedNewContact ) || ( $relatedNewContact instanceof CRM_Contact_BAO_Contact ) ) {
- $relatedNewContact = clone($relatedNewContact);
- }
-
- $matchedIDs = array( );
- // To update/fill contact, get the matching contact Ids if duplicate contact found
- // otherwise get contact Id from object of related contact
- if ( is_array( $relatedNewContact ) && civicrm_error( $relatedNewContact ) ) {
- if ( civicrm_duplicate($relatedNewContact) ) {
- $matchedIDs = explode(',',$relatedNewContact['error_message']['params'][0]);
- } else {
- $errorMessage = $relatedNewContact['error_message'];
- array_unshift( $values, $errorMessage );
- $importRecordParams = array($statusFieldName => 'ERROR', "${statusFieldName}Msg" => $errorMessage);
- $this->updateImportRecord( $values[count($values)-1], $importRecordParams );
- return CRM_Import_Parser::ERROR;
- }
- } else {
- $matchedIDs[] = $relatedNewContact->id;
- }
- // update/fill related contact after getting matching Contact Ids, CRM-4424
- if ( in_array( $onDuplicate, array( CRM_Import_Parser::DUPLICATE_UPDATE, CRM_Import_Parser::DUPLICATE_FILL ) ) ) {
- //validation of related contact subtype for update mode
- //CRM-5125
- $relatedCsType = null;
- if ( CRM_Utils_Array::value('contact_sub_type', $formatting) ) {
- $relatedCsType = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact',
- $matchedIDs[0],
- 'contact_sub_type' );
- }
-
- if ( !empty($relatedCsType) &&
- (!CRM_Contact_BAO_ContactType::isAllowEdit($matchedIDs[0], $relatedCsType) &&
- $relatedCsType != CRM_Utils_Array::value('contact_sub_type', $formatting) ) ) {
- $errorMessage = ts( "Mismatched or Invalid contact subtype found for this related contact." );
- array_unshift($values, $errorMessage);
- return CRM_Import_Parser::NO_MATCH;
- } else {
- $updatedContact = $this->createContact( $formatting, $contactFields, $onDuplicate, $matchedIDs[0] );
- }
- }
- static $relativeContact = array( ) ;
- if ( civicrm_duplicate( $relatedNewContact ) ) {
- if ( count( $matchedIDs ) >= 1 ) {
- $relContactId = $matchedIDs[0];
- //add relative contact to count during update & fill mode.
- //logic to make count distinct by contact id.
- if ( $this->_newRelatedContacts || ! empty( $relativeContact ) ) {
- $reContact = array_keys( $relativeContact, $relContactId );
-
- if ( empty( $reContact ) ) {
- $this->_newRelatedContacts[] = $relativeContact[] = $relContactId;
- }
- } else {
- $this->_newRelatedContacts[] = $relativeContact[] = $relContactId;
- }
- }
- } else {
- $relContactId = $relatedNewContact->id;
- $this->_newRelatedContacts[] = $relativeContact[] = $relContactId;
- }
-
- if ( civicrm_duplicate( $relatedNewContact ) ||
- ( $relatedNewContact instanceof CRM_Contact_BAO_Contact ) ) {
- //fix for CRM-1993.Checks for duplicate related contacts
- if ( count( $matchedIDs ) >= 1 ) {
- //if more than one duplicate contact
- //found, create relationship with first contact
- // now create the relationship record
- $relationParams = array( );
- $relationParams = array('relationship_type_id' => $key,
- 'contact_check' => array( $relContactId => 1),
- 'is_active' => 1,
- 'skipRecentView' => true
- );
-
- // we only handle related contact success, we ignore failures for now
- // at some point wold be nice to have related counts as separate
- $relationIds = array('contact' => $primaryContactId);
-
- list( $valid, $invalid, $duplicate, $saved, $relationshipIds ) =
- CRM_Contact_BAO_Relationship::create( $relationParams, $relationIds );
-
- if ( $valid || $duplicate ) {
- $relationIds['contactTarget'] = $relContactId;
- $action = ( $duplicate ) ? CRM_Core_Action::UPDATE : CRM_Core_Action::ADD;
- CRM_Contact_BAO_Relationship::relatedMemberships( $primaryContactId,
- $relationParams,
- $relationIds,
- $action );
- }
-
- //handle current employer, CRM-3532
- if ( $valid ) {
- require_once 'CRM/Core/PseudoConstant.php';
- $allRelationships = CRM_Core_PseudoConstant::relationshipType( 'name' );
- $relationshipTypeId = str_replace( array('_a_b', '_b_a'), array('', ''), $key );
- $relationshipType = str_replace( $relationshipTypeId . '_', '', $key );
- $orgId = $individualId = null;
- if ( $allRelationships[$relationshipTypeId]["name_{$relationshipType}"] == 'Employee of' ) {
- $orgId = $relContactId;
- $individualId = $primaryContactId;
- } else if ( $allRelationships[$relationshipTypeId]["name_{$relationshipType}"] == 'Employer of' ) {
- $orgId = $primaryContactId;
- $individualId = $relContactId;
- }
- if ( $orgId && $individualId ) {
- $currentEmpParams[$individualId] = $orgId;
- require_once 'CRM/Contact/BAO/Contact/Utils.php';
- CRM_Contact_BAO_Contact_Utils::setCurrentEmployer( $currentEmpParams );
- }
- }
- }
- }
- }
- }
- }
- if( $this->_updateWithId ) {
- //return warning if street address is unparsed, CRM-5886
- return $this->processMessage( $values, $statusFieldName, $this->_retCode );
- }
- //dupe checking
- if ( is_array( $newContact ) && civicrm_error( $newContact ) ) {
- $code = null;
-
- if ( ( $code = CRM_Utils_Array::value( 'code', $newContact['error_message'] ) ) &&
- ( $code == CRM_Core_Error::DUPLICATE_CONTACT ) ) {
- $urls = array( );
- // need to fix at some stage and decide if the error will return an
- // array or string, crude hack for now
- if ( is_array( $newContact['error_message']['params'][0] ) ) {
- $cids = $newContact['error_message']['params'][0];
- } else {
- $cids = explode( ',', $newContact['error_message']['params'][0] );
- }
-
- foreach ($cids as $cid) {
- $urls[] = CRM_Utils_System::url('civicrm/contact/view',
- 'reset=1&cid=' . $cid, true);
- }
-
- $url_string = implode("\n", $urls);
-
- // If we duplicate more than one record, skip no matter what
- if (count($cids) > 1) {
- $errorMessage = ts('Record duplicates multiple contacts');
- $importRecordParams = array($statusFieldName => 'ERROR', "${statusFieldName}Msg" => $errorMessage);
-
- //combine error msg to avoid mismatch between error file columns.
- $errorMessage .= "\n" . $url_string;
- array_unshift($values, $errorMessage);
- $this->updateImportRecord( $valu…
Large files files are truncated, but you can click here to view the full file