Feature to provide mostly used countries in top section of Country select list
authorSunil Pawar <sunil@skvare.com>
Mon, 23 Nov 2020 09:01:30 +0000 (14:31 +0530)
committerSunil Pawar <sunil@skvare.com>
Mon, 23 Nov 2020 09:01:30 +0000 (14:31 +0530)
CRM/Admin/Form/Setting/Localization.php
CRM/Core/BAO/Country.php
CRM/Core/PseudoConstant.php
settings/Localization.setting.php
templates/CRM/Admin/Form/Setting/Localization.hlp
templates/CRM/Admin/Form/Setting/Localization.tpl

index d33ebb369df1096f9e78358b8119c1438f0b516b..eec3334e2a9a0c6aa3f0f938487c236970b66283 100644 (file)
@@ -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,
index 49413ba891d41640a39a644efa0aad4ef9ba5d08..2c32a578cdf2f91463de450eb60b95ce66eab37c 100644 (file)
@@ -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.
    *
index c1f5af9e77f31390486d0ba084780327eae84e41..92b12571d9fd15fb4e82e20083ab51c2546519e6 100644 (file)
@@ -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);
index dbfbaa38a03aa64553cf999676461b27d637ed79..20da0af84f612902108412fe7691a06dfa4f5ed2 100644 (file)
@@ -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',
+    ],
+  ],
 ];
index 42d93a6739252b38f3820444fabcc1b99d1b5eec..74bc8afb391af948c29c86c62f2e68d31845255a 100644 (file)
@@ -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 <strong>Profile forms which include both a Country and a State/Province field</strong>.  This setting controls which countries' states and/or provinces are available in the State/Province selection field <strong>for Custom Fields</strong> or for Profile forms which do NOT include a Country field.{/ts}
   </p>
 {/htxt}
+{htxt id="favouriteContactCountries"}
+  <p>
+      {ts}Selected countries will appear in top section of country list.{/ts}
+  </p>
+{/htxt}
index 498e9f13a0c55d153ce6454cab81592f2acbfbc7..491aa1103a870d75201b9bd51fffc2d5785652c4 100644 (file)
                 <td class="label">{$form.defaultContactCountry.label} {help id='defaultContactCountry' title=$form.defaultContactCountry.label}</td>
                 <td>{$form.defaultContactCountry.html}</td>
             </tr>
+            <tr class="crm-localization-form-block-favouriteContactCountries">
+                <td class="label">{$form.favouriteContactCountries.label} {help id='favouriteContactCountries' title=$form.favouriteContactCountries.label}</td>
+                <td>{$form.favouriteContactCountries.html}</td>
+            </tr>
            <tr class="crm-localization-form-block-defaultContactStateProvince">
                 <td class="label">{$form.defaultContactStateProvince.label} {help id='defaultContactCountry' title=$form.defaultContactStateProvince.label}</td>
                 <td>{$form.defaultContactStateProvince.html}</td>