Best Practice Extension Configuration

I’ve written some code to improve filtering in grid views and I’m considering packaging it up as an extension for other people to use.

The extension is split into several classes, each of which have some configurable properties. How should I set up the application component so that the user can configure the individual components from their main config file?

I’ve considered adding a property to the application component class that looks something like this:




public $filterConfig = array(

    'ComponentClassName'=>array(

        'property1'=>'defaultValue',

        ...

    ),

    ...

);



and then calling Yii::createComponent() to construct each instance of each component. The down side is that the default values are no longer stored in the component classes themselves, which seems like poor encapsulation. It might also impact extensibility.

Is there a recommended way to handle this? Any suggestions would be appreciated.

Update:

It occurs to me that I can keep the default config in the separate components and keep the application component’s configuration as simple as:




$filterConfig = array(

    'FilterClass1'=>array(

        'class'=>'path.to.FilterClass1',

    ),

    'FilterClass2'=>array(

        'class'=>'path.to.FilterClass2',

    ),

    ...

);



The user could still override the default config. This would also mean that the user could add their own filter classes via config.

Is this the right thing to do?

In all my applications I do similar. I do not use an additional application property, but add the extensions and configurations I need in the index.php.

I do like this - see directory structure: Application Configurations

I have a common dir with all my extensions, only few applications use there own extensions in ‘application.extensions’,

the most are used from the common directory. An alias ‘common’ is added in the index.php.

The applications use the same extensions, but need different configs.

I have default configs for the extensions stored in 'common/config/ directory.

  • default.php:



'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',

'preload'=>array('log'),

'import' => array(

        'application.models.*',

        'application.components.*',

         ...

    ),

   'components' => array(

        'urlManager' => array(

          .....




Then I use config files for (a set of or single) extensions I normally use in an application

  • yiistrap.php (the config for yiistrap, yiiwheels, …)

  • mongodb.php (all the stuff I need for mongodb: imports the extensions,config the db, directmongosuite, mongoyii …)

  • db.php (if I use a CDbConnection, holds a default config for the ‘db’ component)

  • gii.php (the config for gii)

In the main.php I can override alle the settings from the imported default configs.

So my index.php looks like this:





$appDir = dirname(__FILE__);

Yii::setPathOfAlias('common',$appDir.'/../common');

$commonConfigDir = $appDir.'/../common/config';


....





$configs=CMap::mergeArray(

    require($commonConfigDir.'/default.php'),

    require($commonConfigDir.'/yiistrap.php'),

    require($commonConfigDir.'/dbmysql.php'),

    //require($commonConfigDir.'/mongodb.php'),

    ... 

);


$config=CMap::mergeArray($configs,require($appDir.'/protected/config/main.php'));

Yii::createWebApplication($config)->run();




The main.php for the application now is only a small config file, that holds a few configs (parts) for specific settings I have to override or some modules/components I only use in the application:




'db'=>array(

            'connectionString'=>...,

            'username'=>...,

            'password'=>...,


...

        ),



You can do similar with your filter classes.

Create a default config for your extension ‘filterclasses_default.php’ which the user has to place in ‘protected/config’.

The the user can copy and modify (set other property values, add classes…) this file to ‘filterclasses_app.php’.

In index.php





....

$configDir = dirname(__FILE__).'/protected/config';


$configs=CMap::mergeArray(

    require($configDir .'/filterclasses_default.php'),

    require($configDir .'/filterclasses_app.php'),  //overrides filterclasses_default

);


$config=CMap::mergeArray($configs,require($configDir .'/main.php'));

Yii::createWebApplication($config)->run();




Thanks for the detailed response. That looks like an interesting approach. My only concern would be making the extension more difficult to install for users.

I’ll definitely consider it, depending on the complexity of the configuration.