From 3c4a4657cf5d8a10316b3b9a48e4b727900face3 Mon Sep 17 00:00:00 2001
From: Sunil Pawar
Date: Mon, 23 Nov 2020 14:31:30 +0530
Subject: [PATCH] Feature to provide mostly used countries in top section of
Country select list
---
CRM/Admin/Form/Setting/Localization.php | 1 +
CRM/Core/BAO/Country.php | 57 +++++++++++++++++++
CRM/Core/PseudoConstant.php | 37 +++++-------
settings/Localization.setting.php | 23 ++++++++
.../CRM/Admin/Form/Setting/Localization.hlp | 5 ++
.../CRM/Admin/Form/Setting/Localization.tpl | 4 ++
6 files changed, 103 insertions(+), 24 deletions(-)
diff --git a/CRM/Admin/Form/Setting/Localization.php b/CRM/Admin/Form/Setting/Localization.php
index d33ebb369d..eec3334e2a 100644
--- a/CRM/Admin/Form/Setting/Localization.php
+++ b/CRM/Admin/Form/Setting/Localization.php
@@ -25,6 +25,7 @@ class CRM_Admin_Form_Setting_Localization extends CRM_Admin_Form_Setting {
'countryLimit' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME,
'customTranslateFunction' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME,
'defaultContactCountry' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME,
+ 'favouriteContactCountries' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME,
'defaultContactStateProvince' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME,
'defaultCurrency' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME,
'fieldSeparator' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME,
diff --git a/CRM/Core/BAO/Country.php b/CRM/Core/BAO/Country.php
index 49413ba891..2c32a578cd 100644
--- a/CRM/Core/BAO/Country.php
+++ b/CRM/Core/BAO/Country.php
@@ -94,6 +94,63 @@ class CRM_Core_BAO_Country extends CRM_Core_DAO_Country {
return $cachedContactCountry;
}
+ /**
+ * Provide list of favourite contries.
+ *
+ * @param $availableCountries
+ * @return array
+ */
+ public static function favouriteContactCountries($availableCountries) {
+ static $cachedFavouriteContactCountries = [];
+ $favouriteContactCountries = Civi::settings()->get('favouriteContactCountries');
+
+ if (!empty($favouriteContactCountries) && !$cachedFavouriteContactCountries) {
+ $favouriteCountries = [];
+ foreach($favouriteContactCountries as $favouriteContactCountry) {
+ if (array_key_exists($favouriteContactCountry, $availableCountries)) {
+ $favouriteCountries[$favouriteContactCountry] = $availableCountries[$favouriteContactCountry];
+ }
+ }
+ $cachedFavouriteContactCountries = $favouriteCountries;
+ }
+ return $cachedFavouriteContactCountries;
+ }
+
+ /**
+ * Provide sorted list of countries with default country with first position
+ * then favourite countries then rest of countries.
+ *
+ * @param $availableCountries
+ * @return array
+ */
+ public static function _defaultContactCountries($availableCountries) {
+ // localise the country names if in an non-en_US locale
+ $tsLocale = CRM_Core_I18n::getLocale();
+ if ($tsLocale != '' and $tsLocale != 'en_US') {
+ $i18n = CRM_Core_I18n::singleton();
+ $i18n->localizeArray($availableCountries, [
+ 'context' => 'country',
+ ]);
+ $availableCountries = CRM_Utils_Array::asort($availableCountries);
+ }
+ $favouriteContactCountries = CRM_Core_BAO_Country::favouriteContactCountries($availableCountries);
+ // if default country is set, percolate it to the top
+ if ($defaultContactCountry = CRM_Core_BAO_Country::defaultContactCountry()) {
+ $countryIsoCodes = CRM_Core_PseudoConstant::countryIsoCode();
+ $defaultID = array_search($defaultContactCountry, $countryIsoCodes);
+ if ($defaultID !== FALSE) {
+ $default = [];
+ $default[$defaultID] = $availableCountries[$defaultID] ?? NULL;
+ $availableCountries = $default + $favouriteContactCountries + $availableCountries;
+ }
+ }
+ elseif (!empty($favouriteContactCountries)) {
+ $availableCountries = $favouriteContactCountries + $availableCountries;
+ }
+
+ return $availableCountries;
+ }
+
/**
* Provide cached default country name.
*
diff --git a/CRM/Core/PseudoConstant.php b/CRM/Core/PseudoConstant.php
index c1f5af9e77..92b12571d9 100644
--- a/CRM/Core/PseudoConstant.php
+++ b/CRM/Core/PseudoConstant.php
@@ -732,25 +732,7 @@ WHERE id = %1";
self::populate(self::$country, 'CRM_Core_DAO_Country', TRUE, 'name', 'is_active', $whereClause);
- // if default country is set, percolate it to the top
- if (CRM_Core_BAO_Country::defaultContactCountry()) {
- $countryIsoCodes = self::countryIsoCode();
- $defaultID = array_search(CRM_Core_BAO_Country::defaultContactCountry(), $countryIsoCodes);
- if ($defaultID !== FALSE) {
- $default[$defaultID] = self::$country[$defaultID] ?? NULL;
- self::$country = $default + self::$country;
- }
- }
-
- // localise the country names if in an non-en_US locale
- $tsLocale = CRM_Core_I18n::getLocale();
- if ($tsLocale != '' and $tsLocale != 'en_US') {
- $i18n = CRM_Core_I18n::singleton();
- $i18n->localizeArray(self::$country, [
- 'context' => 'country',
- ]);
- self::$country = CRM_Utils_Array::asort(self::$country);
- }
+ self::$country = CRM_Core_BAO_Country::_defaultContactCountries(self::$country);
}
if ($id) {
if (array_key_exists($id, self::$country)) {
@@ -1579,12 +1561,19 @@ WHERE id = %1
}
// Localize results
if (!empty($params['localize']) || $pseudoconstant['table'] === 'civicrm_country' || $pseudoconstant['table'] === 'civicrm_state_province') {
- $I18nParams = [];
- if ($localizeContext) {
- $I18nParams['context'] = $localizeContext;
+ if ($pseudoconstant['table'] === 'civicrm_country') {
+ $output = CRM_Core_BAO_Country::_defaultContactCountries($output);
+ // avoid further sorting
+ $order = '';
+ }
+ else {
+ $I18nParams = [];
+ if ($localizeContext) {
+ $I18nParams['context'] = $localizeContext;
+ }
+ $i18n = CRM_Core_I18n::singleton();
+ $i18n->localizeArray($output, $I18nParams);
}
- $i18n = CRM_Core_I18n::singleton();
- $i18n->localizeArray($output, $I18nParams);
// Maintain sort by label
if ($order === 'ORDER BY %2') {
$output = CRM_Utils_Array::asort($output);
diff --git a/settings/Localization.setting.php b/settings/Localization.setting.php
index dbfbaa38a0..20da0af84f 100644
--- a/settings/Localization.setting.php
+++ b/settings/Localization.setting.php
@@ -528,4 +528,27 @@ return [
'help_text' => 'If a contact is created with no language this setting will determine the language data (if any) to save.'
. 'You may or may not wish to make an assumption here about whether it matches the site language',
],
+ 'favouriteContactCountries' => [
+ 'group_name' => 'Localization Preferences',
+ 'group' => 'localization',
+ 'name' => 'favouriteContactCountries',
+ 'type' => 'Array',
+ 'quick_form_type' => 'Element',
+ 'html_type' => 'advmultiselect',
+ 'html_attributes' => [
+ 'size' => 5,
+ 'style' => 'width:150px',
+ 'class' => 'advmultiselect',
+ ],
+ 'default' => [],
+ 'add' => '5.31',
+ 'title' => ts('Favourite Countries'),
+ 'is_domain' => 1,
+ 'is_contact' => 0,
+ 'description' => ts('Appear in Top section of select list'),
+ 'help_text' => 'Selected countries will appear in top section of country list',
+ 'pseudoconstant' => [
+ 'callback' => 'CRM_Admin_Form_Setting_Localization::getAvailableCountries',
+ ],
+ ],
];
diff --git a/templates/CRM/Admin/Form/Setting/Localization.hlp b/templates/CRM/Admin/Form/Setting/Localization.hlp
index 42d93a6739..74bc8afb39 100644
--- a/templates/CRM/Admin/Form/Setting/Localization.hlp
+++ b/templates/CRM/Admin/Form/Setting/Localization.hlp
@@ -65,3 +65,8 @@
{ts}State/province listings are populated dynamically based on the selected Country for all standard contact address editing forms, as well as for Profile forms which include both a Country and a State/Province field. This setting controls which countries' states and/or provinces are available in the State/Province selection field for Custom Fields or for Profile forms which do NOT include a Country field.{/ts}
{/htxt}
+{htxt id="favouriteContactCountries"}
+
+ {ts}Selected countries will appear in top section of country list.{/ts}
+
+{/htxt}
diff --git a/templates/CRM/Admin/Form/Setting/Localization.tpl b/templates/CRM/Admin/Form/Setting/Localization.tpl
index 498e9f13a0..491aa1103a 100644
--- a/templates/CRM/Admin/Form/Setting/Localization.tpl
+++ b/templates/CRM/Admin/Form/Setting/Localization.tpl
@@ -92,6 +92,10 @@
{$form.defaultContactCountry.label} {help id='defaultContactCountry' title=$form.defaultContactCountry.label} |
{$form.defaultContactCountry.html} |
+
+ {$form.favouriteContactCountries.label} {help id='favouriteContactCountries' title=$form.favouriteContactCountries.label} |
+ {$form.favouriteContactCountries.html} |
+
{$form.defaultContactStateProvince.label} {help id='defaultContactCountry' title=$form.defaultContactStateProvince.label} |
{$form.defaultContactStateProvince.html} |
--
2.25.1