Store & retrieve Yii2 widget configuration from database

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. You may also want to validate the attributes for saving and retrieval. This post discusses one of the approaches to do this. Let’s consider you have something like the NavBar configuration below to store in the db:

use yii\bootstrap\NavBar;
NavBar::begin([
    'brandLabel' => 'My Company',
    'brandUrl' => Yii::$app->homeUrl,
    'options' => [
        'class' => 'navbar-inverse navbar-fixed-top',
        'id' => 'navbar-1' // the unique identifier for the widget
    ],
]);
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.

CREATE TABLE `tbl_widget_config` (
    id INT(11) PRIMARY KEY COMMENT 'Your widget config identifier',
    class_name VARCHAR(180) COMMENT 'Fully namespaced widget class name',
    config TEXT COMMENT 'Serialized widget configuration',
    rules TEXT COMMENT 'Validation rules for checking the widget config'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='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($id) {
    $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($id) {
    $dbWidget = WidgetConfig::findOne($id);
    $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());
}

One thought on “Store & retrieve Yii2 widget configuration from database

  1. This tutorial is very interesting,specially for new developers. I have a similar problem.
    I have a parameters table having 60+ parameters which are set by admin. The parameters are shown as a form in the user screen. The user gives values depending on the parameters and submits it. The real problem is
    1) to show the saved parameters in the parameters table as a form in the users interface
    2)Saving the user form values to database and update them in the same form.
    Initially I was thinking of storing all the parameters to a table called parameter_entry table, but after reading your post I want to ask if it is possible to store serialized data and display the same in the form. It will be a great help if you can provide some idea regarding point no 1 and point no 2.

    paramters table

    id
    parameter_name
    parameter_type
    Parameter_isrequired

    parameter_entry table

    user_id
    paramter_id
    value

Comments are closed.