Add Store View Selector To Your Magento Module

back to tech articles
Magento CE 1.7.0.2

The store view selector is a very useful feature in Magento. It’s very easy to hook into this functionality for addition in your own modules. Let’s do it.

Database Field

To start, we need a field in our database which will hold the stores data. This will be in the form of a comma-delimited string (1,2,3 for example), so we need to use a text field to store the data.

For a traditional flat database table, the following syntax is used:

1
2
3
4
5
6
...
->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_TEXT, 63, array(
    'nullable' => true,
    'default' => null,
), 'Store View Selector')
...

For an EAV table structure, we create the field with the following:

1
2
3
4
5
6
7
8
9
10
11
...
'store_id' => array(
    'type' => 'text',
    'label' => 'Store View Selector',
    'input' => 'text',
    'required' => false,
    'sort_order' => 30,
    'position' => 30,
    'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
),
...

Obviously, I’ve only shown you the field to add, the rest of the file in each case is also required!

The Form

Now we need a field on our form to select this data and specify the store view. In my case, I’m adding this to an admin form which extends the Mage_Adminhtml_Block_Widget_Form class. Inside the _prepareForm method, I have added:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
if (!Mage::app()->isSingleStoreMode()) {
    $fieldset->addField('store_id', 'multiselect', array(
        'name' => 'stores[]',
        'label' => Mage::helper('myhelper')->__('Store View'),
        'title' => Mage::helper('myhelper')->__('Store View'),
        'required' => true,
        'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, true),
    ));
} else {
    $fieldset->addField('store_id', 'hidden', array(
        'name' => 'stores[]',
        'value' => Mage::app()->getStore(true)->getId(),
    ));
}
...

The field will only show up if we have multiple stores set up in Magento. Otherwise, a hidden field is created to preserve the selected value when we write our changes to the database.

The Controller

In the admin controller, in the save action, we check for the submitted field and add it to the data array:

1
2
3
4
5
6
7
8
9
10
...
if( isset($data['stores']) ) {
    if( in_array('0', $data['stores']) ){
        $data['store_id'] = '0';
    } else {
        $data['store_id'] = join(",", $data['stores']);
    }
    unset($data['stores']);
}
...

We check for the submitted field (an array) and join it into a string, separated by commas. We then unset the field that we won’t need for the database (in our case $data[‘stores’]).

Admin Grid

We can show the field in our admin grid too, if we want. My grid extends the Mage_Adminhtml_Block_Widget_Grid class. We need to add the data to the collection first:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected function _prepareCollection()
{
    $collection = Mage::getModel('tc_storeview/stores')->getResourceCollection();

    foreach ($collection as $view) {
        if ( $view->getStoreId() && $view->getStoreId() != 0 ) {
            $view->setStoreId(explode(',',$view->getStoreId()));
        } else {
            $view->setStoreId(array('0'));
        }
    }

    $this->setCollection($collection);
    return parent::_prepareCollection();
}

And then we add a column to our _prepareColumns method:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
if ( !Mage::app()->isSingleStoreMode() ) {
    $this->addColumn('store_id', array(
        'header' => Mage::helper('myhelper')->__('Store View'),
        'index' => 'store_id',
        'type' => 'store',
        'store_all' => true,
        'store_view' => true,
        'sortable' => true,
        'filter_condition_callback' => array($this, '_filterStoreCondition'),
    ));
}
...

Unless you are too busy copy-pasting, you might have noticed the new callback _filterStoreCondition. That is a new method, and it looks like so:

1
2
3
4
5
6
7
protected function _filterStoreCondition($collection, $column)
{
    if ( !$value = $column->getFilter()->getValue() ) {
        return;
    }
    $this->getCollection()->addStoreFilter($value);
}

This allows us to filter the grid on the store view.

Conclusion

That is all. Our store view functionality is finished. The folks at Magento have done all the hard work, so we can easily hook into this excellent feature.