jenkins-bot has submitted this change and it was merged.

Change subject: Resolve conflicts on preferred language.
......................................................................


Resolve conflicts on preferred language.

If the language is the same the 'variant' should not cause a conflict.

Bug: T146344
Change-Id: Ia922994e955b40b12b252fff04959c579fa06f64
---
M sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php
M sites/all/modules/wmf_civicrm/wmf_civicrm.module
2 files changed, 125 insertions(+), 1 deletion(-)

Approvals:
  Ejegg: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php 
b/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php
index 2a3c0f6..5f509b6 100644
--- a/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php
+++ b/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php
@@ -358,6 +358,57 @@
     $this->assertEquals(1, $contact['values'][0]['do_not_email']);
   }
 
+
+  /**
+   * Test that a conflict on communication preferences is handled.
+   *
+   * @dataProvider getLanguageCombos
+   */
+  public function testBatchMergeConflictPreferredLanguage($dataSet) {
+    // Can't use api if we are trying to use invalid data.
+    wmf_civicrm_ensure_language_exists('en');
+    wmf_civicrm_ensure_language_exists('en_NZ');
+    CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET preferred_language 
= '{$dataSet['languages'][0]}' WHERE id = $this->contactID");
+    CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET preferred_language 
= '{$dataSet['languages'][1]}' WHERE id = $this->contactID2");
+
+    $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' 
=> 'safe'));
+    if ($dataSet['is_conflict']) {
+      $this->assertEquals(1, count($result['values']['skipped']));
+    }
+    else {
+      $this->assertEquals(1, count($result['values']['merged']));
+      $contact = $this->callAPISuccess('Contact', 'get', array(
+        'id' => $this->contactID,
+        'sequential' => 1
+      ));
+      $this->assertEquals($dataSet['selected'], 
$contact['values'][0]['preferred_language']);
+    }
+  }
+
+  /**
+   * Get combinations of languages for comparison.
+   *
+   * @return array
+   */
+  public function getLanguageCombos() {
+    $dataSet = array(
+      // Choose longer.
+      array(array('languages' => array('en', 'en_US'), 'is_conflict' => FALSE, 
'selected' => 'en_US')),
+      array(array('languages' => array('en_US', 'en'), 'is_conflict' => FALSE, 
'selected' => 'en_US')),
+      // Choose valid.
+      array(array('languages' => array('en_XX', 'en_US'), 'is_conflict' => 
FALSE, 'selected' => 'en_US')),
+      array(array('languages' => array('en_US', 'en_XX'), 'is_conflict' => 
FALSE, 'selected' => 'en_US')),
+      // Chose one with a 'real' label  (more valid).
+      array(array('languages' => array('en_US', 'en_NZ'), 'is_conflict' => 
FALSE, 'selected' => 'en_US')),
+      array(array('languages' => array('en_NZ', 'en_US'), 'is_conflict' => 
FALSE, 'selected' => 'en_US')),
+      // Chose either - feels like the return on coding any decision making 
now is negligible.
+      // Could go for most recent donor but feels like no return on effort.
+      // we will usually get the most recent donor anyway by default - as it 
merges higher number to smaller.
+      array(array('languages' => array('en_GB', 'en_US'), 'is_conflict' => 
FALSE, 'selected' => 'en_US')),
+      array(array('languages' => array('en_US', 'en_GB'), 'is_conflict' => 
FALSE, 'selected' => 'en_GB'))
+    );
+    return $dataSet;
+  }
   /**
    * Test that source conflicts are ignored.
    *
diff --git a/sites/all/modules/wmf_civicrm/wmf_civicrm.module 
b/sites/all/modules/wmf_civicrm/wmf_civicrm.module
index 5f76f55..def9a32 100644
--- a/sites/all/modules/wmf_civicrm/wmf_civicrm.module
+++ b/sites/all/modules/wmf_civicrm/wmf_civicrm.module
@@ -1281,6 +1281,16 @@
  * @return bool
  */
 function wmf_civicrm_check_language_exists($languageAbbreviation) {
+  $languages = wmf_civicrm_get_valid_languages();
+  return !empty($languages[$languageAbbreviation]);
+}
+
+/**
+ * Get valid languages.
+ *
+ * @return array
+ */
+function wmf_civicrm_get_valid_languages() {
   static $languages;
   if (empty($languages)) {
     $available_options = civicrm_api3('Contact', 'getoptions', array(
@@ -1288,8 +1298,9 @@
     ));
     $languages = $available_options['values'];
   }
-  return !empty($languages[$languageAbbreviation]);
+  return $languages;
 }
+
 /**
  * Ensure the required option value exists.
  *
@@ -2137,6 +2148,15 @@
                 continue;
               }
 
+              if (_wmf_civicrm_merge_resolve_preferred_language_conflict(
+                str_replace('move_', '', $moveField),
+                $refs['migration_info'][$moveField],
+                $refs['migration_info']['rows'][$moveField]['other'],
+                $refs['migration_info']['rows'][$moveField]['main'])) {
+                unset($refs['fields_in_conflict'][$moveField]);
+                continue;
+              }
+
               if (_wmf_civicrm_merge_resolve_casing_conflict(
                 str_replace('move_', '', $moveField),
                 $refs['migration_info'][$moveField],
@@ -2246,6 +2266,59 @@
 }
 
 /**
+ * Resolve conflicts on preferred language.
+ *
+ * If the underlying language (first 2 letters) is the same we make a value 
choice.
+ *
+ * 1) we prefer 'valid' languages - ones that have entries in the option_value 
table.
+ * 2) we prefer more explicit (longer) languages (en_US over en).
+ * 3) we prefer languages with labels that describe them. For example
+ *   'de_DE' => 'German' has been deliberately created
+ *   'de_NZ' => 'de_NZ' has been code-created.
+ *
+ * Note preferring based on the option value table means updates to what is 
enabled
+ * or whether they have labels will flow through.
+ *
+ * We could also return the later donor but this feels like poor return on 
effort given they are
+ * already the same main language and we don't easily have that info at this 
point in the code.
+ * We will usually get the most recent donor anyway by default - as it merges 
higher id to lower id.
+ *
+ * @param string $fieldName
+ * @param string $moveFieldValue
+ * @param string $valueToKeep
+ * @param string $valueToOverwrite
+ *
+ * @return bool
+ *   Has the conflict been resolved?
+ */
+function _wmf_civicrm_merge_resolve_preferred_language_conflict($fieldName, 
&$moveFieldValue, &$valueToKeep, &$valueToOverwrite) {
+  if ($fieldName !== 'preferred_language') {
+    return FALSE;
+  }
+
+  if (substr($valueToKeep, 0, 2) != substr($valueToOverwrite, 0, 2)) {
+    return FALSE;
+  }
+  if (!wmf_civicrm_check_language_exists($valueToOverwrite)) {
+    // The conflict is resolved & the value to keep is fine.
+    return TRUE;
+  }
+
+  $languages = wmf_civicrm_get_valid_languages();
+  if (!wmf_civicrm_check_language_exists($valueToKeep)
+    || strlen($valueToOverwrite) > strlen($valueToKeep)
+    || ($languages[$valueToKeep] == $valueToKeep && 
$languages[$valueToOverwrite] != $valueToOverwrite)
+  ) {
+    // The conflict is resolved & we will chose the overwrite value as the 
keeper is invalid.
+    $moveFieldValue = $valueToOverwrite;
+    $valueToKeep = $valueToOverwrite;
+    return TRUE;
+  }
+
+  return TRUE;
+}
+
+/**
  * Count the number of capital letters in a string.
  *
  * @param $string

-- 
To view, visit https://gerrit.wikimedia.org/r/312182
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia922994e955b40b12b252fff04959c579fa06f64
Gerrit-PatchSet: 2
Gerrit-Project: wikimedia/fundraising/crm
Gerrit-Branch: master
Gerrit-Owner: Eileen <emcnaugh...@wikimedia.org>
Gerrit-Reviewer: Awight <awi...@wikimedia.org>
Gerrit-Reviewer: Cdentinger <cdentin...@wikimedia.org>
Gerrit-Reviewer: Ejegg <eeggles...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to