Eileen has uploaded a new change for review. https://gerrit.wikimedia.org/r/312182
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, 126 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/crm refs/changes/82/312182/1 diff --git a/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php b/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php index 1f71ccd..0d464ee 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 a conflict on casing in first names is handled. * diff --git a/sites/all/modules/wmf_civicrm/wmf_civicrm.module b/sites/all/modules/wmf_civicrm/wmf_civicrm.module index 654f568..a8a939a 100644 --- a/sites/all/modules/wmf_civicrm/wmf_civicrm.module +++ b/sites/all/modules/wmf_civicrm/wmf_civicrm.module @@ -1277,6 +1277,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( @@ -1284,8 +1294,9 @@ )); $languages = $available_options['values']; } - return !empty($languages[$languageAbbreviation]); + return $languages; } + /** * Ensure the required option value exists. * @@ -2128,6 +2139,16 @@ 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], @@ -2237,6 +2258,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: newchange Gerrit-Change-Id: Ia922994e955b40b12b252fff04959c579fa06f64 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/crm Gerrit-Branch: master Gerrit-Owner: Eileen <emcnaugh...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits