Add new tab with grid of products for attach to any of post.
/* @var $installer Mage_Core_Model_Resource_Setup */
$installer = $this;
$installer->startSetup();
try {
$installer->run("ALTER TABLE {$this->getTable('blog/blog')} ADD `related_products` TEXT NOT NULL;");
} catch (Exception $e) {
Mage::logException($e);
}
$installer->endSetup();
Into AW_Blog_Block_Manage_Blog_Edit_Tabs
add:
$this->addTab(
'related_product_section',
array(
'label' => Mage::helper('blog')->__('Products in Post'),
'title' => Mage::helper('blog')->__('Products in Post'),
'url' => $this->getUrl('*/*/related', array('_current'=>true)),
'class' => 'ajax'
)
);
class AW_Blog_Block_Manage_Blog_Edit_Tab_Product_Related extends Mage_Adminhtml_Block_Widget_Grid
{
/**
* Set grid params
*
*/
public function __construct()
{
parent::__construct();
$this->setId('related_product_grid');
$this->setDefaultSort('entity_id');
$this->setUseAjax(true);
$this->setDefaultFilter(array('in_products'=>1));
$this->setFilterVisibility(true);
}
/**
* Retrieve currently edited plain model
*
* @return mixed
*/
protected function getModel()
{
$model = Mage::getSingleton('blog/blog');
if ( ! $model->getId() && $this->getRequest()->getParam('id', false)) {
$model->load($this->getRequest()->getParam('id'));
}
return $model;
}
/**
* Add filter
*
* @param object $column
* @return mixed
*/
protected function _addColumnFilterToCollection($column)
{
if ($column->getId() == 'in_products') {
$productIds = $this->_getSelectedProducts();
if (empty($productIds)) {
$productIds = 0;
}
if ($column->getFilter()->getValue()) {
$this->getCollection()->addFieldToFilter('entity_id', array('in' => $productIds));
} else {
if($productIds) {
$this->getCollection()->addFieldToFilter('entity_id', array('nin' => $productIds));
}
}
} else {
parent::_addColumnFilterToCollection($column);
}
return $this;
}
/**
* Prepare collection
*
* @return Mage_Adminhtml_Block_Widget_Grid
*/
protected function _prepareCollection()
{
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
;
$this->setCollection($collection);
return parent::_prepareCollection();
}
/**
* Add columns to grid
*
* @return Mage_Adminhtml_Block_Widget_Grid
*/
protected function _prepareColumns()
{
$this->addColumn('in_products', array(
'header_css_class' => 'a-center',
'type' => 'checkbox',
'name' => 'in_products',
'values' => $this->_getSelectedProducts(),
'align' => 'center',
'index' => 'entity_id'
));
$this->addColumn('entity_id', array(
'header' => Mage::helper('catalog')->__('ID'),
'sortable' => true,
'width' => 60,
'index' => 'entity_id'
));
$this->addColumn('name', array(
'header' => Mage::helper('catalog')->__('Name'),
'index' => 'name'
));
$this->addColumn('type', array(
'header' => Mage::helper('catalog')->__('Type'),
'width' => 100,
'index' => 'type_id',
'type' => 'options',
'options' => Mage::getSingleton('catalog/product_type')->getOptionArray(),
));
$sets = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
->load()
->toOptionHash();
$this->addColumn('set_name', array(
'header' => Mage::helper('catalog')->__('Attrib. Set Name'),
'width' => 130,
'index' => 'attribute_set_id',
'type' => 'options',
'options' => $sets,
));
$this->addColumn('status', array(
'header' => Mage::helper('catalog')->__('Status'),
'width' => 90,
'index' => 'status',
'type' => 'options',
'options' => Mage::getSingleton('catalog/product_status')->getOptionArray(),
));
$this->addColumn('visibility', array(
'header' => Mage::helper('catalog')->__('Visibility'),
'width' => 90,
'index' => 'visibility',
'type' => 'options',
'options' => Mage::getSingleton('catalog/product_visibility')->getOptionArray(),
));
$this->addColumn('sku', array(
'header' => Mage::helper('catalog')->__('SKU'),
'width' => 80,
'index' => 'sku'
));
$this->addColumn('price', array(
'header' => Mage::helper('catalog')->__('Price'),
'type' => 'currency',
'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE),
'index' => 'price'
));
$this->addColumn('position', array(
'header' => Mage::helper('catalog')->__('Position'),
'name' => 'position',
'type' => 'number',
'width' => 60,
'validate_class' => 'validate-number',
'index' => 'position',
'editable' => true,
'filter_condition_callback' => array($this, '_addLinkModelFilterCallback')
));
return parent::_prepareColumns();
}
/**
* Rerieve grid URL
*
* @return string
*/
public function getGridUrl()
{
return $this->getData('grid_url') ? $this->getData('grid_url') : $this->getUrl('*/*/relatedGrid', array('_current' => true));
}
/**
* Retrieve selected into products
*
* @return array
*/
protected function _getSelectedProducts()
{
$products = $this->getProductsRelated();
if (!is_array($products)) {
$products = array_keys($this->getSelectedRelatedProducts());
}
return $products;
}
/**
* Retrieve and prepare product array
*
* @return array
*/
public function getSelectedRelatedProducts()
{
$selectedProducts = array();
$products = $this->getRelatedProducts();
if (is_array($products)) {
foreach ($products as $productId => $productData) {
$selectedProducts[$productId] = array('position' => $productData['position']);
}
}
return $selectedProducts;
}
/**
* Retrieve products array from model
*
* @return boolean | array
*/
protected function getRelatedProducts()
{
if ($this->getModel()) {
return Mage::helper('adminhtml/js')->decodeGridSerializedInput($this->getModel()->getRelatedProducts());
}
return false;
}
}
Into ../app/design/adminhtml/default/default/layout/aw_blog.xml
<adminhtml_awblog_manage_blog_related>
<block type="core/text_list" name="root" output="toHtml">
<block type="blog/manage_blog_edit_tab_product_related" name="blog.edit.tab.product.related"/>
<block type="adminhtml/widget_grid_serializer" name="related_grid_serializer">
<reference name="related_grid_serializer">
<action method="initSerializerBlock">
<grid_block_name>blog.edit.tab.product.related</grid_block_name>
<data_callback>getSelectedRelatedProducts</data_callback>
<hidden_input_name>links[related]</hidden_input_name>
<reload_param_name>products_related</reload_param_name>
</action>
<action method="addColumnInputName">
<input_name>position</input_name>
</action>
</reference>
</block>
</block>
</adminhtml_awblog_manage_blog_related>
<adminhtml_awblog_manage_blog_relatedgrid>
<block type="core/text_list" name="root" output="toHtml">
<block type="blog/manage_blog_edit_tab_product_related" name="blog.edit.tab.product.related"/>
</block>
</adminhtml_awblog_manage_blog_relatedgrid>
Into AW_Blog_Adminhtml_Awblog_Manage_BlogController
add two methods
public function relatedAction()
{
$this->loadLayout();
$this->getLayout()
->getBlock('blog.edit.tab.product.related')
->setRelatedProducts($this->getRequest()->getPost('products_related', null));
$this->renderLayout();
}
public function relatedGridAction()
{
$this->loadLayout();
$this->getLayout()
->getBlock('blog.edit.tab.product.related')
->setRelatedProducts($this->getRequest()->getPost('products_related', null));
$this->renderLayout();
}
and add into saveAction()
code below for prepare related data to save
$links = $data['links'];
if (isset($links['related'])) {
$data['related_products'] = $links['related'];
}
Products saved into new related_products
fields serialized with adminhtml/widget_grid_serializer
for unserialize use code below
$post = Mage::getModel('blog/post')->load(1); // Load post with id = 1
$serializedString = $post->getRelatedProducts();
$relatedArray = Mage::helper('adminhtml/js')->decodeGridSerializedInput($serializedString);
// Result: array({PRODUCT_ID} => array('position' => {PRODUCT_POSITION}))
You can do anything with post data from form with related products, serialize/not serialize, create custom array structure and also save into another table, all code above is an exapmle of one of my solution based on system UpSell/Related Products
Fatal error: Call to a member function setRelatedProducts() on boolean in \xampp\htdocs\themes\app\code\community\AW\Blog\controllers\Adminhtml\Awblog\Manage\BlogController.php on line 10...