Translating Site Based On User Preferences / At A User Level

I am fairly new to php and Yii. I wanted to put something I did to deal with issues we had in translating our site. I found that there was quite a bit of documentation on the messing and how to actually set up the translations themselves, but not much that I could find on actually setting up the switching of languages.

I wanted to know if what I did makes sense, or if there is a better way to do this that I missed somewhere.

Since the translation method by default uses the app level language setting, this causes problems in some cases. Most of the posts suggested editing the language using Yii::app()->setLanguage($lang); and putting the code in the init() method of the CController class. We initially tried this, by adding a method to the Profiles.php called getLanguage() and calling Yii::app()->setLanguage(Yii::app()->getModule(‘user’)->user()->profile->getLanguage()); in the init.

The problem with this was that this was changing the language at the app level, and not at the user level. I was concerned that this would cause issues because if two (or more) users were using the application at the same time and selected different languages, the value may be swapped while the request was in progress, and it wouldn’t display the language correctly for each user. The problem that actually manifested itself was that any user who was going through our registration process (not logged in or having a session) was getting their language switched if any other user switched. The code above allowed us to store the language in session, or in the user’s profile.

In order to make the translation work at the user level, the following changes were made to the yii::t method.




   public static function t($category,$message,$params=array(),$source=null,$language=null)

   {

      /*

       * Ian Coughlin: Adding functionality to pull language from session if available

      */

      if ($language==null){

         if (isset(Yii::app()->session['_lang'])&&!empty(Yii::app()->session['_lang'])){ //Check the session as the first priority

            $language=Yii::app()->session['_lang'];

         } else if (isset(Yii::app()->getModule('user')->user()->profile)){ // Check the profile, this method checks for a language profile field, and sets the session, so the next request has it.

            $language=Yii::app()->getModule('user')->user()->profile->getLanguage();

            Yii::app()->session['_lang']=$language;

         } else if (Yii::app()->request->getQuery('lang', '')!=''){ // lastly check the url, this is needed for users who aren't logged in.

            $language=Yii::app()->request->getQuery('lang', 'en');

         }

      }



The contents of the Profile->getLanguage() are as follows:




public function getLanguage(){

      $lang='en';

      $app = Yii::app();

      $profileLang=$this->getAttribute('language');

        

      if (isset($profileLang)&&!empty($profileLang)){

         $lang=$profileLang;

         $app->session['_lang']=$profileLang;

      }

      return $lang;

   }



This method wrapped the language profile field, and selected ‘en’ as the default if the user hadn’t set a language. In this case the user’s language is stored in a profile field under a column called “language”, but it could be stored almost anywhere, as long as it is tied to a specific user.

I would appreciate any feedback anyone has.

If you are saving the user’s language preference in a ‘Profile’ or ‘User’ table, then calling setLanguage() upon login. Yes it will change the preference for the app, FOR THAT USER, not for everyone. You don’t need to change the Yii::t() function. The only thing that I think needs to be added is ‘sourceLanguage’ to you main config file. Tis is set to the language that the site was written in, so Yii knows if it actually needs to look for a translation (messages) file.

There is an extension that allows for the user to select there prefers lang, or you could setLanguage() in the login process.

I thought that was how it worked based on the other posts I saw, but in practice if I changed the language for the user by setting it at the app level, it changed it for any user who wasn’t logged in. I tested this by having one logged in user in my main chrome window, and a user who was going through the registration process (who wasn’t logged in) in an incognito window. Every time I called Yii::app()->setLanguage() for the logged in user, it also changed the language for the user who was going through the registration process. I am not sure if I am missing something.

Weird. You might download this extension, look at the code, and see how it does it. Or just use it. I haven’t used it, so no recommendation. I just remember having seen it before.