Requirement ¶
You may have scenarios, where you want to store a specific array configuration to the database. A classic example could be saving Yii widget configuration to the database and then retrieving it at runtime, with dynamic parameters set. This wiki discusses one of the approaches to do this. Let's consider you have something like the NavBar configuration below to store in the db:
NavBar::begin([
'brandLabel' => 'My Company',
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'navbar-inverse navbar-fixed-top',
],
]);
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => $menuItems,
]);
NavBar::end();
Design ¶
The design approach involves creating the data structure to store the serialized array configurations with tags as variables that will be replaced at runtime. The rules/validators for validating the widget configuration, will also be stored serialized in a rules column. While running the widget at runtime, the rules will be validated dynamically using the yii\base\DynamicModel.
1. Data Structure ¶
Create a table tbl_widget_config
in your database with the following minimum columns. Create a model called WidgetConfig
for this table through gii.
id INT(11) primary key COMMENT 'Your widget config identifier'
class_name VARCHAR(180) COMMENT 'Fully namespaced class name for the widget'
config TEXT COMMENT 'Serialized widget configuration'
rules TEXT COMMENT 'Rules to be checked for validating the widget configuration'
2. Storing Config To Database ¶
Convert your widget configuration in such a way that you can include tags for variables to be dynamically replaced at runtime. The following code can be used to populate your tbl_widget_config
.
// creating a configuration
public function createConfig() {
$model = new WidgetConfig;
$model->class_name = 'yii\bootstrap\NavBar';
$model->config = serialize([
'brandLabel' => 'My Company',
'brandUrl' => '{{homeUrl}}',
'options' => [
'class' => 'navbar-inverse navbar-fixed-top',
]
]);
$model->rules = serialize([
['brandUrl', \common\validators\TagValidator::className()],
// this is a custom TagValidator but could be any validator
]);
$model->save();
}
Note the tag {{homeUrl}}
will be dynamically replaced at runtime.
3. Validating Config and running widget ¶
You can use your own custom validator to parse any tags (as called in the example above but not yet described here) or simply use a 'parseTags' function such as in the following example ...
// Parse tags
public static function parseTags($config) {
return unserialize(strtr($config, [
'{{homeUrl}}' => Yii::$app->homeUrl,
'{{otherTag1}}' => 'Value 1'
]));
}
// Retrieve the configuration
public function runWidget($configId) {
$dbWidget = WidgetConfig::findOne($configId);
$widgetConfig = \yii\base\DynamicModel::validateData(
static::parseTags($dbWidget->config),
static::parseTags($dbWidget->rules)
);
// To run the widget call below
$class = $dbWidget->class_name;
$class::widget($widgetConfig->getAttributes());
}
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.