How to use an application behavior to maintain runtime configuration

In this tutorial will be explained a method to manage some configuration runtime. This excellent tutorial follows a similar approach, but requires to write a masterclass which all controllers are supposed to extend, following this wiki you can achieve the same by only editing the configuration.

This is often needed to manage internationalization, themes and other configuration that depends from the user.

The most comfortable way is to user an application behavior. In this example we save the language in the session, but it can also be saved in the database.

Create a file in components named ApplicationConfigBehavior and copy this code:

<?php
 
/**
 * ApplicationConfigBehavior is a behavior for the application.
 * It loads additional config parameters that cannot be statically 
 * written in config/main
 */
class ApplicationConfigBehavior extends CBehavior
{
    /**
     * Declares events and the event handler methods
     * See yii documentation on behavior
     */
    public function events()
    {
        return array_merge(parent::events(), array(
            'onBeginRequest'=>'beginRequest',
        ));
    }
 
    /**
     * Load configuration that cannot be put in config/main
     */
    public function beginRequest()
    {
       if (isset($_POST['lang']))
               $this->owner->user->setState('applicationLanguage', $_POST['lang']);
       if ($this->owner->user->getState('applicationLanguage'))
            $this->owner->language=$this->owner->user->getState('applicationLanguage');
        else 
            $this->owner->language='en';
    }
}

This file must be included in config/main.php:

'behaviors' => array('ApplicationConfigBehavior')

To update the language we can use a widget (to be included in layout/main), for example:

components/LangBox.php

<?php
class LangBox extends CWidget
{
    public function run()
    {
        $currentLang = Yii::app()->language;
        $this->render('langBox', array('currentLang' => $currentLang));
    }
}
?>

components/views/langBox.php

<?php echo CHtml::form(); ?>
    <div id="langdrop">
        <?php echo CHtml::dropDownList('lang', $currentLang, array(
            'en_us' => 'English', 'is_is' => 'Icelandic'), array('submit' => '')); ?>
    </div>
<?php echo CHtml::endForm(); ?>