Fix for failure to handle label on import
authoreileen <emcnaughton@wikimedia.org>
Wed, 24 Mar 2021 04:29:16 +0000 (17:29 +1300)
committereileen <emcnaughton@wikimedia.org>
Wed, 24 Mar 2021 21:36:03 +0000 (10:36 +1300)
This adds generic handling for where label has been submitted and flips to using the api
to provide generic handling for names

CRM/Contact/Import/Parser/Contact.php
api/v3/utils.php
tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php

index 75bbb421d3a96e169797708909ddc5fd29909025..3cc2600b25580dfa7c09e43d5cad631cbf105ff9 100644 (file)
@@ -8,6 +8,9 @@
  | and copyright information, see https://civicrm.org/licensing       |
  +--------------------------------------------------------------------+
  */
+
+use Civi\Api4\Contact;
+
 require_once 'CRM/Utils/DeprecatedUtils.php';
 require_once 'api/v3/utils.php';
 
@@ -425,6 +428,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Contact_Import_Parser {
    *
    * @throws \CiviCRM_API3_Exception
    * @throws \CRM_Core_Exception
+   * @throws \API_Exception
    */
   public function import($onDuplicate, &$values, $doGeocodeAddress = FALSE) {
     $config = CRM_Core_Config::singleton();
@@ -640,16 +644,20 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Contact_Import_Parser {
     //now we create new contact in update/fill mode also.
     $contactID = NULL;
     if ($createNewContact || ($this->_retCode != CRM_Import_Parser::NO_MATCH && $this->_updateWithId)) {
-
-      //CRM-4430, don't carry if not submitted.
-      foreach (['prefix_id', 'suffix_id', 'gender_id'] as $name) {
-        if (!empty($formatted[$name])) {
-          $options = CRM_Contact_BAO_Contact::buildOptions($name, 'get');
-          if (!isset($options[$formatted[$name]])) {
-            $formatted[$name] = CRM_Utils_Array::key((string) $formatted[$name], $options);
-          }
+      // @todo - there are multiple places where formatting is done that need consolidation.
+      // This handles where the label has been passed in and it has gotten this far.
+      // probably a bunch of hard-coded stuff could be removed to rely on this.
+      $fields = Contact::getFields(FALSE)
+        ->addWhere('options', '=', TRUE)
+        ->setLoadOptions(TRUE)
+        ->execute()->indexBy('name');
+      foreach ($fields as $fieldName => $fieldSpec) {
+        if (!empty($formatted[$fieldName])
+          && empty($fieldSpec['options'][$formatted[$fieldName]])) {
+          $formatted[$fieldName] = array_search($formatted[$fieldName], $fieldSpec['options'], TRUE) ?? $formatted[$fieldName];
         }
       }
+      //CRM-4430, don't carry if not submitted.
       if ($this->_updateWithId && !empty($params['id'])) {
         $contactID = $params['id'];
       }
@@ -1607,8 +1615,8 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Contact_Import_Parser {
       }
     }
 
-    $contact = CRM_Contact_BAO_Contact::create($data);
-    $cid = $contact->id;
+    $contact = civicrm_api3('Contact', 'create', $data);
+    $cid = $contact['id'];
 
     CRM_Core_Config::setPermitCacheFlushMode(TRUE);
 
index 88237f41f0a53e1d6911e84bea9648e84b5cd3be..f67ada48905b3ddbb9e5f40b9a4d70e89d34a145 100644 (file)
@@ -1077,6 +1077,11 @@ function _civicrm_api3_object_to_array_unique_fields(&$dao, &$values) {
  *   ID of entity per $extends.
  */
 function _civicrm_api3_custom_format_params($params, &$values, $extends, $entityId = NULL) {
+  if (!empty($params['custom'])) {
+    // The Import class does the formatting first - ideally it wouldn't but this early return
+    // provides transitional support.
+    return;
+  }
   $values['custom'] = [];
   $checkCheckBoxField = FALSE;
   $entity = $extends;
index e3025cacbbf2b032218d7620aa2363f60027040b..42a7a6f43913c27f43db90263770f52d58c1c7bf 100644 (file)
@@ -461,7 +461,7 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase {
    * @throws \CRM_Core_Exception
    * @throws \CiviCRM_API3_Exception
    */
-  public function testPrefixLabel() {
+  public function testPrefixLabel(): void {
     $this->callAPISuccess('OptionValue', 'create', ['option_group_id' => 'individual_prefix', 'name' => 'new_one', 'label' => 'special', 'value' => 70]);
     $mapping = [
       ['name' => 'first_name', 'column_number' => 0],
@@ -491,9 +491,11 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase {
   /**
    * Test that labels work for importing custom data.
    *
+   * @throws \API_Exception
    * @throws \CRM_Core_Exception
+   * @throws \CiviCRM_API3_Exception
    */
-  public function testCustomDataLabel() {
+  public function testCustomDataLabel(): void {
     $this->createCustomGroupWithFieldOfType([], 'select');
     $contactValues = [
       'first_name' => 'Bill',