While developing an extension recently I came across the need to add the ability to allow changes on a store view level.
To start off with I wanted to make sure this functioned the same as
the built store view selection, to make it easy on the end user (take a
look at how store view is handled with CMS Page creation to see what I’m
referring to). However, by default Magento keeps its store view
information in seperate tables (ie CMS_PAGE_STORE), which wasn’t ideal
for this scenerio. The solution I came up with involves using one field ‘store_id’ in your modules table to save the Store ID’s as comma seperated values.
In your module’s adminhtml edit/create form
(<Namespace>_<Module>_Block_Adminhtml_<Model>_Edit_Tab_Form)
add the following code in the
_prepareForm function where you would like the
store selection to show up:
if (!Mage::app()->isSingleStoreMode()) {
$fieldset->addField('store_id', 'multiselect', array(
'name' => 'stores[]',
'label' => Mage::helper('')->__('Store View'),
'title' => Mage::helper('')->__('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()
));
}
(This adds the store view multiselect to your form if you have
multiple stores setup, if not it adds a hidden field with the current
stores id taking into consideration the possibility of more stores being
added in the future.)
Next in your module’s Controller
file (<Namespace>_<Module>_Adminhtml_Controller)
add the
following to your
saveAction:
if(isset($data['stores'])) {
if(in_array('0',$data['stores'])){
$data['store_id'] = '0';
}
else{
$data['store_id'] = implode(",", $data['stores']);
}
unset($data['stores']);
}
(This sets store_id to 0 if “All Store Views” was selected or sets
store_id as comma-seperated values representing the store selection.)
In your modules Grid file (<Namespace>_<Module>_Block_Adminhtml_<Model>_Grid),
add the following:
protected function _prepareCollection(){
$collection = Mage::getModel('_/')->getCollection();
foreach($collection as $link){
if($link->getStoreId() && $link->getStoreId() != 0 ){
$link->setStoreId(explode(',',$link->getStoreId()));
}
else{
$link->setStoreId(array('0'));
}
}
$this->setCollection($collection);
return parent::_prepareCollection();
}
(This parses the collections store_id’s and resets them as an Array,
taking into consideration any that might not be assigned yet or any with
a value of 0, which represents ‘All Store Views’)
In the grids
prepareColumns function add:
if (!Mage::app()->isSingleStoreMode()) {
$this->addColumn('store_id', array(
'header' => Mage::helper('')->__('Store View'),
'index' => 'store_id',
'type' => 'store',
'store_all' => true,
'store_view' => true,
'sortable' => true,
'filter_condition_callback' => array($this,
'_filterStoreCondition'),
));
}
(If you have multiple stores setup this will add the “Store View”
column with the store selection drop down, if no column is added as its
not needed.)
and add the following function:
protected function _filterStoreCondition($collection, $column){
if (!$value = $column->getFilter()->getValue()) {
return;
}
$this->getCollection()->addStoreFilter($value);
}
(This function checks to see if a store filter has been selected and
if so calls the function to add the filter to the collection.)
Lastly in your modules Collection
file(<Namespace>_<Module>_Model_Mysql4_<Model>_Collection)
add this function:
public function addStoreFilter($store, $withAdmin = true){
if ($store instanceof Mage_Core_Model_Store) {
$store = array($store->getId());
}
if (!is_array($store)) {
$store = array($store);
}
$this->addFilter('store_id', array('in' => $store));
return $this;
}