I was wondering how to set-up the application parameters in the back-end to use them all around the application without the need of using the database and I came up with this solution, I hope it helps somebody else.
Note: The directory organization described follows this tutorial.
How to do it
We will start with the model, so create protected/backend/models/ConfigForm.php
as follows:
class ConfigForm extends CFormModel { public $adminEmail; public $paramName; public function rules() { return array( array('adminEmail, paramName','required'), ); } }
Now we will move on to the controller, so create protected/backend/controllers/ConfigController.php
as follows:
class ConfigController extends Controller { public function actionIndex() { $file = dirname(__FILE__).'../../../config/params.inc'; $content = file_get_contents($file); $arr = unserialize(base64_decode($content)); $model = new ConfigForm(); $model->setAttributes($arr); if (isset($_POST['ConfigForm'])) { $config = array( 'adminEmail'=>$_POST['ConfigForm']['adminEmail'], 'paramName'=>$_POST['ConfigForm']['paramName'], ); $str = base64_encode(serialize($config)); file_put_contents($file, $str); Yii::app()->user->setFlash('config', Yii::t('app', 'Your new options have been saved.')); $model->setAttributes($config); } $this->render('index',array('model'=>$model)); } }
Finally a view protected/backend/views/config/index.php
<div class="form"> <?php $form = $this->beginWidget('CActiveForm', array( 'id' => 'config-form', 'enableAjaxValidation' => false, )); <h1><?php echo Yii::t('app', 'Options'); </h1> <?php if(Yii::app()->user->hasFlash('config')): <div class="info"> <?php echo Yii::app()->user->getFlash('config'); </div> <?php endif; <p class="note"> <?php echo Yii::t('app', 'Fields with'); <span class="required">*</span> <?php echo Yii::t('app', 'are required'); . </p> <?php echo $form->errorSummary($model); <div class="row"> <?php echo $form->labelEx($model,'adminEmail'); <?php echo $form->textField($model, 'adminEmail'); <?php echo $form->error($model,'adminEmail'); </div><!-- row --> <div class="row"> <?php echo $form->labelEx($model,'paramName'); <?php echo $form->textField($model, 'paramName'); <?php echo $form->error($model,'paramName'); </div><!-- row --> <div class="row buttons"> <?php echo CHtml::submitButton(Yii::t('app', 'Save')); </div> <?php $this->endWidget(); </div><!-- form -->
Now, we will create the following config files under protected/config
:
- params.inc
- params.php
We need to change our protected/config/main.php
as follows:
// application-level parameters that can be accessed // using Yii::app()->params['paramName'] 'params'=>require(dirname(__FILE__).'/params.php'),
And protected/config/params.php
will contain:
$file = dirname(__FILE__).'/params.inc'; $content = file_get_contents($file); $arr = unserialize(base64_decode($content)); return CMap::mergeArray( $arr, array( 'salt'=>'P@bl0', 'someOption'=>true, ) ) ;
How it works
You can add as many parameters as you want to the ConfigForm
model. In the back-end the administrator will be able to change this parameters that will be serialized into a file and loaded into the front-end.
If you have static parameters, which doesn't need to be modified, you can add them to the protected/config/params.php
file where they will be merged with all the others.
In protected/config/main.php
the 'params' attribute is populated with an array of name/value pairs. These options are available at runtime via the Yii::app()->params['adminEmail']
hash, which is indexed by the parameter name.