From 412585fb59dcbcb030c18d2e9a5ae29900e04170 Mon Sep 17 00:00:00 2001 From: eileen Date: Tue, 12 Sep 2017 18:53:02 +1200 Subject: [PATCH] CRM-21175 fix fatal error on multiple custom field import. Additional test is tangental.... --- CRM/Contact/Import/Parser/Contact.php | 3 +- CRM/Core/BAO/Mapping.php | 34 +++++++++++++++++++ CRM/Import/Form/DataSource.php | 3 +- .../CRM/Contact/Import/Parser/ContactTest.php | 14 ++++++++ tests/phpunit/CiviTest/CiviUnitTestCase.php | 6 ++-- 5 files changed, 54 insertions(+), 6 deletions(-) diff --git a/CRM/Contact/Import/Parser/Contact.php b/CRM/Contact/Import/Parser/Contact.php index 7c4816d30c..a70ab571eb 100644 --- a/CRM/Contact/Import/Parser/Contact.php +++ b/CRM/Contact/Import/Parser/Contact.php @@ -1147,8 +1147,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Contact_Import_Parser { * @param null $relationships */ public static function isErrorInCustomData($params, &$errorMessage, $csType = NULL, $relationships = NULL) { - $session = CRM_Core_Session::singleton(); - $dateType = $session->get("dateTypes"); + $dateType = CRM_Core_Session::singleton()->get("dateTypes"); if (!empty($params['contact_sub_type'])) { $csType = CRM_Utils_Array::value('contact_sub_type', $params); diff --git a/CRM/Core/BAO/Mapping.php b/CRM/Core/BAO/Mapping.php index dd0710a6df..34934ab123 100644 --- a/CRM/Core/BAO/Mapping.php +++ b/CRM/Core/BAO/Mapping.php @@ -130,6 +130,40 @@ class CRM_Core_BAO_Mapping extends CRM_Core_DAO_Mapping { return $mapping; } + /** + * Get the mappings array, creating if it does not exist. + * + * @param string $mappingType + * Mapping type name. + * + * @return array + * Array of mapping names, keyed by id. + * + * @throws \CiviCRM_API3_Exception + */ + public static function getCreateMappingValues($mappingType) { + try { + return CRM_Core_BAO_Mapping::getMappings($mappingType); + } + catch (CiviCRM_API3_Exception $e) { + // Having a valid mapping_type_id is now enforced. However, rather than error let's + // add it. This is required for Multi value which could be done by upgrade script, but + // it feels like there could be other instances so this is safer. + $errorParams = $e->getExtraParams(); + if ($errorParams['error_field'] === 'mapping_type_id') { + $mappingValues = civicrm_api3('Mapping', 'getoptions', array('field' => 'mapping_type_id')); + civicrm_api3('OptionValue', 'create', array( + 'option_group_id' => 'mapping_type', + 'label' => $mappingType, + 'value' => max(array_keys($mappingValues['values'])) + 1, + 'is_reserved' => 1, + )); + return CRM_Core_BAO_Mapping::getMappings($mappingType); + } + throw $e; + } + } + /** * Get the mapping fields. * diff --git a/CRM/Import/Form/DataSource.php b/CRM/Import/Form/DataSource.php index 0040e2584f..6a7ba2ab93 100644 --- a/CRM/Import/Form/DataSource.php +++ b/CRM/Import/Form/DataSource.php @@ -79,9 +79,8 @@ abstract class CRM_Import_Form_DataSource extends CRM_Core_Form { $this->add('text', 'fieldSeparator', ts('Import Field Separator'), array('size' => 2), TRUE); $this->setDefaults(array('fieldSeparator' => $config->fieldSeparator)); + $mappingArray = CRM_Core_BAO_Mapping::getCreateMappingValues('Import ' . static::IMPORT_ENTITY); - //get the saved mapping details - $mappingArray = CRM_Core_BAO_Mapping::getMappings('Import ' . static::IMPORT_ENTITY); $this->assign('savedMapping', $mappingArray); $this->add('select', 'savedMapping', ts('Mapping Option'), array('' => ts('- select -')) + $mappingArray); diff --git a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php index 0aa3ee3196..8e4a0c1ed7 100644 --- a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php +++ b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php @@ -302,6 +302,20 @@ class CRM_Contact_Imports_Parser_ContactTest extends CiviUnitTestCase { $this->callAPISuccessGetSingle('Contact', $contactValues); } + /** + * Test the determination of whether a custom field is valid. + */ + public function testCustomFieldValidation() { + $errorMessage = array(); + $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'ABC')); + $customField = $this->customFieldOptionValueCreate($customGroup, 'fieldABC', array('html_type' => 'Multi-Select')); + $params = array( + 'custom_' . $customField['id'] => 'Label1|Label2', + ); + CRM_Contact_Import_Parser_Contact::isErrorInCustomData($params, $errorMessage); + $this->assertEquals(array(), $errorMessage); + } + /** * Run the import parser. * diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index e434936742..b782927b1c 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -2431,10 +2431,12 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { * @param array $customGroup * @param string $name * Name of custom field. + * @param array $extraParams + * Additional parameters to pass through. * * @return array|int */ - public function customFieldOptionValueCreate($customGroup, $name) { + public function customFieldOptionValueCreate($customGroup, $name, $extraParams = array()) { $fieldParams = array( 'custom_group_id' => $customGroup['id'], 'name' => 'test_custom_group', @@ -2461,7 +2463,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { 'option_status' => 1, ); - $params = array_merge($fieldParams, $optionGroup, $optionValue); + $params = array_merge($fieldParams, $optionGroup, $optionValue, $extraParams); return $this->callAPISuccess('custom_field', 'create', $params); } -- 2.25.1