Yii 1.1: Multilanguage web site controlling by get request and database allowed languages

14 followers

You can control your languages in admin

First, you have to have create database table for default language and allowed languages.

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:

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 functions in component Controller which 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.

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

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 controller action /en/site/index

4. rule is for redirecting /en/ for redirecting index to language /de/ /fr/

depends on database

'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,
);

Total 2 comments

#4350 report it
Igor Ivanovic at 2011/06/28 04:11am
Admin Controll

This example shows how you can control language by admin section. Because you can manage your table language

#4337 report it
drumaddict at 2011/06/27 10:49am
Why not use session?

OK,but I think it's easier done using session,with minimum code.There's another article in wiki that explains it,using only a few lines of code.

Leave a comment

Please to leave your comment.

Write new article