Changing application configuration dynamically

How can i switch between the main.php configuration and e.g. the admin.php configuration in a CController.

I think that could help me to set various properties like "themes", for the main application and the admin panel instantly.

Example:




/**

	 * Creates a new model.

	 * If creation is successful, the browser will be redirected to the 'show' page.

	 */

	public function actionCreate()

	{

            #code to change from main.php conf to admin.php conf

            #set the "administrator" theme, title and so on

	}




I don’t know if this will actually work, but I’m fairly certain that it will. Let me know.




$new_config = require('/path/to/config/file.php');

Yii::app()->configure($new_config);



Because the Yii include files return an array, $new_config will be assigned the value of that array. Then, we call the configure function (found in yii/framework/base/CModule.php, the parent class of CApplication), which re initializes all the values.

The only problem with this method, however, is that it does not call preloadComponents() or init(). Which both seem to be critical in the update process but are declared as protected.

If the above method does not work, you may consider creating a subclass of CWebApplication and declaring a new method called ‘reconfigure’ or some such, that then does the same functionality as CApplication::__construct(). I’m not sure about what subtle problems that might introduce, though. I haven’t dug thoroughly through the application classes yet.

IMO it doesn’t make much sense to change the application configuration in the controller as that’s much too late in the app life cycle: The config is required earlier to e.g. find out which controller to use at all. Or which auth mechanism, etc. etc.

So you should better put some logic into index.php to include different config files before you run() your application.

Ok, thanks!

I want to store config values such as site name, email, theme etc. in my database, so these can only be retrieved after the application is running.

Where (which file) is the best place pull these values into the app?

The tutorial at the following url should prove useful:

http://programmersnotes.info/2009/03/04/handling-application-parameters-in-yii-using-the-database/

Maybe I’m missing something…

If you make a copy of index.php and call it admin.php or whatever, you can customize the file to meet your requirements. If you redirect to http://yourdomain/admin.php (assuming you are using SEO friendly urls) from your application menu or browse to the url directly from your browser, a separate session should be started independent of the frontend session. This should not present a problem if you are using a browser supporting a tabs feature because you can view your frontend and backend from separate tabs.

If you are using modules, an admin module can have submodules each of which can handle your various admin requirements. Just treat the admin module as a separate application within your application.

Fine leave it to someone else to think of the better solution and a good rational for it. ;)

Nice, but far more than what I need. The following works just fine:




$siteConfig = Config::model()->findAll();


foreach($siteConfig as $conf) {

	

	define($conf->config_key, $conf->config_value);

	

}

Yii::app()->theme = THEME_COLOR;

Yii::app()->name = SITE_NAME;



My question clarified is: Where is the best place (file) within the application to include my file that pulls these values from the database. I have tested by including it at the top of my main.php layout file, but since this is a layout file I don’t feel that is the best place (even though it works).

I wrote this big long stupid response that worked, but then I discovered the best way of doing this.

Edit your main.php config file




return array(

  ...

  'onBeginRequest' => array('Config', 'initApp'),

  ...

);



Now add this static method to your Config.php model




public static function initApp() {

  $siteConfig = self::model()->findAll();

  foreach($siteConfig as $conf) {

    define($conf->config_key, $conf->config_value);

  }

  Yii::app()->theme = THEME_COLOR;

  Yii::app()->name = SITE_NAME;}

}



This should work like a charm…

Good stuff! Just what I was looking for.

Of course you can just use the constant within the application if you want, eg. I have a config_key in the database: PAYPAL_EMAIL and can use PAYPAL_EMAIL within the app where I want it.

You may also, just for error checking purposed do a check to make sure the constants are not defined before defining them. Otherwise, if you run into a collision the page will error out. Then again, that may be what you want. But you may want to do custom error handling or some such.

The standard errors are quite clear (explicit) when a constant has already been defined. I am building the application with predefined constants in the database. The constant values can be edited, however it wont be possible to add new ones (unless some idiot decides to edit the database directly, then that’s their problem!).

Well, consider setting up the config_key as a UNIQUE KEY in your table. That way, even if some idiot tries to edit the data manually they can’t create a collision. It’ll also make lookups faster.