Difference between #9 and #8 of Multilanguage web site controlling by get request and database allowed languages

unchanged
Title
Multilanguage web site controlling by get request and database allowed languages
unchanged
Category
Tutorials
unchanged
Tags
language, multilanguage, website
changed
Content
You can controllcontrol your languages in admin
----------------------------------------

First YouFirst, you have to have create database table for
default language and allowed languages.
~~~
[php]
CREATE TABLE IF NOT EXISTS `tbl_languages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `lang` varchar(2) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `flagpath` varchar(40) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `active` tinyint(1) NOT NULL,
  `main` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

INSERT INTO `tbl_languages` (`id`, `name`, `lang`, `flagpath`, `active`, `main`)
VALUES
(1, 'English', 'en', '/img/lang/en.jpg', 1, 1),
(2, 'Croatian', 'hr', '/img/lang/hr.jpg', 1, 0);
~~~
After Table you have to make model for use:

~~~
[php]
class Lang extends CActiveRecord{
    
        /*
     * This method is used for static model calls
    */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }
    
    public function tableName() {
        return "tbl_languages";
    }
    
    /*
     * Function For check lang by get request eq /hr/site/index
     * If language is by get request found in database and active langage will
return current link eg /hr/site/active if your request is eg /fr/site/index
     * in this case will return /en/site/index while fr langage is not in
database
     * @param cod varchar 2
     * @param route current action route 
     * @param redirection default to true to redirect from eg /fr/ to /en/ while
fr dont exists as language 
     */
    public static function findByCode($cod,$route,$redirect = true){
        $cod = substr($cod,0,2);
        $data = self::model()->find('lang=:LANG AND active =
1',array(':LANG'=>$cod));
        if(empty($data)){
            $lang = self::getdefaultLanguage();
          
            if($redirect == true){
                if(preg_match("/index/", $route))
               
Yii::app()->controller->redirect(Yii::app()->homeUrl.$lang.'/');       

                else        
               
Yii::app()->controller->redirect(Yii::app()->homeUrl.$lang.'/'.$route);
            }else
            return $lang;    
        } 
        else
        return $data->lang;
    }
    
    /*
     * get default language
     */
    public static function getdefaultLanguage(){
        return self::model()->find('main = 1')->lang;
    }
    
  
}   
~~~
Now we have to make Some Functionssome functions in
component Controller witchwhich extends CController


1.init()  
--------
On every Controller instance set the language
2.processUrl()
--------------
Find the language and set current route
3.beforeAction()
----------------
Do that before each action.


~~~
[php]
class Controller extends CController{
        
        /*
         * On every Controller instance set language from get if is index page
get main language
         */
        public function init(){
            if(isset($_GET['lang']))
                Yii::app()->setLanguage($_GET['lang']);
            else
                Yii::app()->setLanguage(Lang::getdefaultLanguage());
            parent::init();
        }

       /*
         * ProcesUrl method used for resolving languages if dont have get
language
         * System gets default language defined from database
         */
        public static function processUrl(){

                if(isset($_GET['lang'])){
                    return Lang::findByCode(Yii::app()->language, 
Yii::app()->controller->route);
                }else{ 
                    return Lang::findByCode(Lang::getdefaultLanguage(), 
Yii::app()->controller->route);   
                }
        }
        
         /*
         * Aftereach action processUrl
         */
         protected function beforeAction($action) {
            self::processUrl();
            return parent::beforeAction($action);
        }


}
~~~
UrlMAnager
----------
And final make the UrlMAnager class to component folder for rewrite current
createUrl for each call add automatic lang to url

~~~
[php]
class UrlManager extends CUrlManager{
    
    /*
    * rewriten behavior
    */
    public function createUrl($route, $params = array(), $ampersand = '&') {
        //because if you wont to define language manually 
        if(empty($params['lang'])){
        $params['lang'] = Controller::processUrl();
        }
        return parent::createUrl($route, $params, $ampersand);
    }
    
    
}
~~~
Configure ROUTES
----------------
Add it to main.php
Language routes
---------------
### 1. rule is default
### 2. rule is for /hr/admin  remove index from controller
### 3. rule is for each controlercontroller action
/en/site/index
### 4. rule is for redirecting /en/ for redirecting index to language /de/ /fr/
depends on database 
~~~
[php]
'urlManager'=>array(
'class'=>'UrlManager',    
'urlFormat'=>'path',
'rules'=>array(    
'/'=>'site/index',      
'<lang>/<controller:\w+>'=>'<controller>/index', 
'<lang>/<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
  
'<lang>'=>'/',          
),
'showScriptName'=>false,
);
~~~