Merge pull request #19225 from colemanw/select2Tweak
[civicrm-core.git] / CRM / Core / BAO / ConfigSetting.php
index c462bae66426c3692bd8010734eee1752b5dc3b1..54ad2e1a74d16c79630fef4e8cf6f55846ed0ea7 100644 (file)
@@ -119,105 +119,120 @@ class CRM_Core_BAO_ConfigSetting {
   }
 
   /**
-   * Evaluate locale preferences and activate a chosen locale by
-   * updating session+global variables.
+   * Activate a chosen locale.
+   *
+   * The locale is set by updating the session and global variables.
+   *
+   * When there is a choice of permitted languages (set on the "Administer" ->
+   * "Localisation" -> "Languages, Currency, Locations" screen) the locale to
+   * be applied can come from a variety of sources. The list below is the order
+   * of priority for deciding which of the sources "wins":
+   *
+   * - The request - when the "lcMessages" query variable is present in the URL.
+   * - The session - when the "lcMessages" session variable has been set.
+   * - Inherited from the CMS - when the "inheritLocale" setting is set.
+   * - CiviCRM settings - the fallback when none of the above set the locale.
+   *
+   * Single-language installs skip this and always set the default locale.
    *
    * @param \Civi\Core\SettingsBag $settings
    * @param string $activatedLocales
    *   Imploded list of locales which are supported in the DB.
    */
   public static function applyLocale($settings, $activatedLocales) {
-    // are we in a multi-language setup?
-    $multiLang = (bool) $activatedLocales;
 
-    // set the current language
-    $chosenLocale = NULL;
+    // Declare access to locale globals.
+    global $dbLocale, $tsLocale;
 
+    // Grab session reference.
     $session = CRM_Core_Session::singleton();
 
-    $permittedLanguages = CRM_Core_I18n::uiLanguages(TRUE);
+    // Set flag for multi-language setup.
+    $multiLang = (bool) $activatedLocales;
+
+    // Initialise the default and chosen locales.
+    $defaultLocale = $settings->get('lcMessages');
+    $chosenLocale = NULL;
 
-    // The locale to be used can come from various places:
-    // - the request (url)
-    // - the session
-    // - civicrm_uf_match
-    // - inherited from the CMS
-    // Only look at this if there is actually a choice of permitted languages
+    // When there is a choice of permitted languages.
+    $permittedLanguages = CRM_Core_I18n::uiLanguages(TRUE);
     if (count($permittedLanguages) >= 2) {
+
+      // Is the "lcMessages" query variable present in the URL?
       $requestLocale = CRM_Utils_Request::retrieve('lcMessages', 'String');
       if (in_array($requestLocale, $permittedLanguages)) {
         $chosenLocale = $requestLocale;
-
-        //CRM-8559, cache navigation do not respect locale if it is changed, so reseting cache.
-        // Ed: This doesn't sound good.
-        // Civi::cache('navigation')->flush();
-      }
-      else {
-        $requestLocale = NULL;
       }
 
-      if (!$requestLocale) {
+      // Check the session if the chosen locale hasn't been set yet.
+      if (empty($chosenLocale)) {
         $sessionLocale = $session->get('lcMessages');
         if (in_array($sessionLocale, $permittedLanguages)) {
           $chosenLocale = $sessionLocale;
         }
-        else {
-          $sessionLocale = NULL;
-        }
       }
 
-      if ($requestLocale) {
-        $ufm = new CRM_Core_DAO_UFMatch();
-        $ufm->contact_id = $session->get('userID');
-        if ($ufm->find(TRUE)) {
-          $ufm->language = $chosenLocale;
-          $ufm->save();
+      /*
+       * Maybe inherit the language from the CMS.
+       *
+       * If the language is specified via "lcMessages" we skip this, since the
+       * intention of the URL query var is to override all other sources.
+       */
+      if ($settings->get('inheritLocale')) {
+
+        /*
+         * FIXME: On multi-language installs, CRM_Utils_System::getUFLocale() in
+         * many cases returns nothing if $dbLocale is not set, so set it to the
+         * default - even if it's overridden later.
+         */
+        $dbLocale = $multiLang && $defaultLocale ? "_{$defaultLocale}" : '';
+
+        // Retrieve locale as reported by CMS.
+        $cmsLocale = CRM_Utils_System::getUFLocale();
+        if (in_array($cmsLocale, $permittedLanguages)) {
+          $chosenLocale = $cmsLocale;
         }
-        $session->set('lcMessages', $chosenLocale);
-      }
 
-      if (!$chosenLocale and $session->get('userID')) {
-        $ufm = new CRM_Core_DAO_UFMatch();
-        $ufm->contact_id = $session->get('userID');
-        if ($ufm->find(TRUE) &&
-          in_array($ufm->language, $permittedLanguages)
-        ) {
-          $chosenLocale = $ufm->language;
+        // Clear chosen locale if not activated in multi-language CiviCRM.
+        if ($activatedLocales && !in_array($chosenLocale, explode(CRM_Core_DAO::VALUE_SEPARATOR, $activatedLocales))) {
+          $chosenLocale = NULL;
         }
-        $session->set('lcMessages', $chosenLocale);
+
       }
-    }
-    global $dbLocale;
-
-    // try to inherit the language from the hosting CMS
-    // If the language is specified in the session (ie. via lcMessages) we still allow it to be overridden.
-    if ($settings->get('inheritLocale') && empty($sessionLocale)) {
-      // FIXME: On multilanguage installs, CRM_Utils_System::getUFLocale() in many cases returns nothing if $dbLocale is not set
-      $lcMessages = $settings->get('lcMessages');
-      $dbLocale = $multiLang && $lcMessages ? "_{$lcMessages}" : '';
-      $chosenLocale = CRM_Utils_System::getUFLocale();
-      if ($activatedLocales and !in_array($chosenLocale, explode(CRM_Core_DAO::VALUE_SEPARATOR, $activatedLocales))) {
-        $chosenLocale = NULL;
+
+      // Assign the system default if the chosen locale hasn't been set.
+      if (empty($chosenLocale)) {
+        $chosenLocale = $defaultLocale;
       }
+
+      // Always assign the chosen locale to the session.
+      $session->set('lcMessages', $chosenLocale);
+
     }
+    else {
+
+      // CRM-11993 - Use default when it's a single-language install.
+      $chosenLocale = $defaultLocale;
 
-    if (empty($chosenLocale)) {
-      //CRM-11993 - if a single-lang site, use default
-      $chosenLocale = $settings->get('lcMessages');
     }
 
-    // set suffix for table names - use views if more than one language
+    /*
+     * Set suffix for table names in multi-language installs.
+     * Use views if more than one language.
+     */
     $dbLocale = $multiLang && $chosenLocale ? "_{$chosenLocale}" : '';
 
-    // FIXME: an ugly hack to fix CRM-4041
-    global $tsLocale;
+    // FIXME: an ugly hack to fix CRM-4041.
     $tsLocale = $chosenLocale;
 
-    // FIXME: as bad aplace as any to fix CRM-5428
-    // (to be moved to a sane location along with the above)
+    /*
+     * FIXME: as bad a place as any to fix CRM-5428.
+     * (to be moved to a sane location along with the above)
+     */
     if (function_exists('mb_internal_encoding')) {
       mb_internal_encoding('UTF-8');
     }
+
   }
 
   /**