A Web Page For Configuration

Hi,

I think we need a web interface to quickly change the fields in /protected/config/main.php

like accessing Gii (http://localhost/index.php?r=gii), it will result into something like http://localhost/index.php?r=config

Also why don’t you use a DBA file (key-value database file) instead ?

I don’t think it’s a good idea. Yii is not a CMS.

One issue with having a web page for editing the configuration is that the file then needs to be writable by the web server.

With that said you need the same level of access in order to be able to use gii so I guess it doesn’t really make a lot of difference in the dev environment.

It would have the potential advantage that configuration options could be validated & include documentation on the same page.

It does seem that using php for the configuration file is a bit of overkill.

Something like yaml might make things a little clearer however this would then add in another dependency for a yaml-processor.

I already proposed something like this http://www.yiiframework.com/forum/index.php/topic/24465-db-config/

But it seems like people prefer to edit a text file :D

There are extensions for both.

However, I don’t understand the motivation behind having a web interface for the configuration?

Firstly, there is little to prevent you from having (some of) the app settings stored in a database.

I mean: do you want to edit the actual files in the browser too? :)

I wrote my own version of db-based system configuration utility with a web interface.

And, I have to confess that I don’t like it very much myself, although I enjoyed its functionality for a while … yeah, you have to believe me, it worked great. But I had to discard it.

After all, when you are not using a CMS but constructing a web application, the system configurations should be stored much more handy in a text file (i.e. a PHP source file). When you consider the needs for version controlling and documentation, a plain text file is much more preferable than a db table. And, do we need a web interface for a text configuration file? No, I don’t think so.

Yes, but sometimes you build a CMS :)

And in that case it would be pleasing to learn that there exist several Yii extensions to help you perform that job :)

Extensions like EConfig http://www.yiiframework.com/extension/config allows to get/set settings to the database, however:

  1. It’s not made to change Yii settings (i.e. medium of cache storage, website name etc. etc.)

  2. A built-in mechanism would be nice

However this was already discussed: http://www.yiiframework.com/forum/index.php/topic/24465-db-config/

As I’ve already said, it looks like people prefer to use text files (with permission issues etc.) :)

You can use Appmanager - or you could override some Yii classes.

Except from the ability to modify cache engine, site name and other more or less fixed parameters, I don’t really see the need to have the app config stored in a database.

I can’t think of a framework which does this.

Maybe it could be done using a sqlite db, separate from the main db configuration?

I think people need two things:

[list=1]

[*]Settings that rarely change (database, cache. etc) and are managed by a developer

[*]Webapplication settings that can change over time depending on what the business wants. Params for example. These would be managed by an Application Manager. (Not totally sure if that’s the name in english…)

[/list]

For the first, a file can be better. For a second, a database config is better. Why not have both? They serve different purposes. The EConfig extension is a nice example of #2.

It’s so easy to implement params, that you need a simple table, Gii and 5 minutes to add a few methods to the model for ease of use. See under the spoiler. I don’t think that there should be a default implementation, because it’s very easy and most of us do that to our liking (some will add more fields, others will chop it down to keyword + value and make keyword unique. I for once sometimes use multiple records with the same keyword and different values).

[spoiler]

[sql]CREATE TABLE param (

`id` int unsigned not null auto_increment, 


`description` varchar(255) not null, 


`keyword` varchar(128) not null, 


`value` carchar(255) not null, 


PRIMARY KEY(`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;[/sql]




class Param extends CActiveRecord {


	public static function model($className=__CLASS__) {

		return parent::model($className);

	}


	public function tableName() {

		return 'param';

	}


	public function rules() {

		return array(

			array('description, value, keyword', 'required'),

			array('description, value', 'length', 'max'=>255),

			array('keyword', 'length', 'max'=>128),

			array('id, description, value, keyword', 'safe', 'on'=>'search'),

		);

	}


	public function relations() {

		return array(

		);

	}


	public function attributeLabels() {

		return array(

			'id' => Yii::t('app', 'ID'),

			'description' => Yii::t('app', 'Description'),

			'value' => Yii::t('app', 'Value'),

			'keyword' => Yii::t('app', 'Keyword'),

		);

	}


	public function search() {

		$criteria = new CDbCriteria;


		$criteria->compare('id', $this->id, true);

		$criteria->compare('description', $this->description, true);

		$criteria->compare('value', $this->value, true);

		$criteria->compare('keyword', $this->keyword, true);


		return new CActiveDataProvider($this, array(

			'criteria' => $criteria,

			'pagination' => array(

				'pageSize' => 50,

			),

			'sort' => array(

				'defaultOrder' => 'keyword',

			),

		));

	}


	/**

	 * @static

	 * @param $name

	 * @param bool $multiple If true, returns array, else string

	 * @return string|array

	 */

	public static function getValue($name, $multiple = false)

	{

		static $params = array();

		if (!array_key_exists($name, $params)) {

			/** @var $model Param */

			$model = $multiple 

				? self::model()->findAllByAttributes(array('keyword' => $name)) 

				: self::model()->findByAttributes(array('keyword' => $name));

			

			if (is_null($model)) {

				$params[$name] = null;

			} else {

				if ($multiple) {

					foreach ($model as $param) {

						$params[$name][] = $param->value;

					}

				} else {

					$params[$name] = $model->value;

				}

			}

			unset($model);

		}

		return $params[$name];

	}


	/**

	 * @param string $keyword

	 * @param mixed $value

	 * @param string $description

	 * @return bool

	 */

	public static function setValue($keyword, $value, $description = '[system]') {

		$model = self::model()->findByAttributes(array('keyword' => $keyword));

		if (!$model) {

			$model = new Param();

		}

		$model->keyword = $keyword;

		$model->value = $value;

		$model->description = $description;

		if ($model->save()) {

			return true;

		} else {

			return false;

		}

	}

}



[/spoiler]