0

I am trying to add another tab to the category edit page that contains another product grid. I need to do this because i want to add to each category page a zone that contains the products that are selected in this grid.

Can anyone help me finish the module ? or is there a easier or existing module to do this ?

PS: Complete code is greatly appreciated :)

This is where i got so far: etc/config.xml

<?xml version="1.0"?>
<config>
  <modules>
    <Forideas_Promotion>
      <version>0.1.0</version>
    </Forideas_Promotion>
  </modules>
  <global>
    <resources>
        <forideas_promotion_setup>
            <setup>
                <module>Forideas_Promotion</module>
                <class>Forideas_Promotion_Model_Resource_Setup</class>
            </setup>
        </forideas_promotion_setup>
    </resources>
    <helpers>
      <promotion>
        <class>Forideas_Promotion_Helper</class>
      </promotion>
    </helpers>
    <models>
        <forideas_promotion>
            <class>Forideas_Promotion_Model</class>
        </forideas_promotion>
        <promotion_resource>
            <entities>
              <category_product>
                  <table>category_product</table>
              </category_product>
            </entities>
        </promotion_resource>
    </models>
    <events>
        <adminhtml_catalog_category_tabs>
            <observers>
                <forideas_promotion_observer>
                    <class>forideas_promotion/observer</class>
                    <method>addCategoryTab</method>
                </forideas_promotion_observer>
            </observers>
        </adminhtml_catalog_category_tabs>
    </events>
  </global>
  <adminhtml>
    <layout>
        <updates>
            <forideas_category_promotion>
                <file>forideas_promotion.xml</file>
            </forideas_category_promotion>
        </updates>
    </layout>
  </adminhtml>
  <admin>
      <routers>
          <adminhtml>
              <args>
                  <modules>
                      <Forideas_Promotion before="Mage_Adminhtml">Forideas_Promotion_Adminhtml</Forideas_Promotion>
                  </modules>
              </args>
          </adminhtml>
      </routers>
  </admin>
</config> 

Block/Adminhtml/Category/Edit/Tab/Product.php:

<?php
class Forideas_Promotion_Block_Adminhtml_Category_Edit_Tab_Product
    extends Mage_Adminhtml_Block_Widget_Grid {
    public function __construct(){
        parent::__construct();
        $this->setId('product_grid');
        $this->setDefaultSort('position');
        $this->setDefaultDir('ASC');
        $this->setUseAjax(true);
        if ($this->getCategory()->getId()) {
            $this->setDefaultFilter(array('in_products'=>1));
        }
    }
    protected function _prepareCollection() {
        $collection = Mage::getResourceModel('catalog/product_collection');
        $collection->addAttributeToSelect('price');
        $adminStore = Mage_Core_Model_App::ADMIN_STORE_ID;
        $collection->joinAttribute('product_name', 'catalog_product/name', 'entity_id', null, 'left', $adminStore);
        if ($this->getCategory()->getId()){
            $constraint = '{{table}}.category_id='.$this->getCategory()->getId();
        }
        else{
            $constraint = '{{table}}.category_id=0';
        }
        $collection->joinField('position',
            'promotion/category_product',
            'position',
            'product_id=entity_id',
            $constraint,
            'left');
        $this->setCollection($collection);
        parent::_prepareCollection();
        return $this;
    }
     protected function _prepareMassaction(){
        return $this;
    }
    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('product_name', array(
            'header'=> Mage::helper('catalog')->__('Name'),
            'align' => 'left',
            'index' => 'product_name',
        ));
        $this->addColumn('sku', array(
            'header'=> Mage::helper('catalog')->__('SKU'),
            'align' => 'left',
            'index' => 'sku',
        ));
        $this->addColumn('price', array(
            'header'=> Mage::helper('catalog')->__('Price'),
            'type'  => 'currency',
            'width' => '1',
            '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',
            'width' => 60,
            'type'  => 'number',
            'validate_class'=> 'validate-number',
            'index' => 'position',
            'editable'  => true,
        ));
    }
    protected function _getSelectedProducts(){
        $products = $this->getCategoryProducts();
        if (!is_array($products)) {
            $products = array_keys($this->getSelectedProducts());
        }
        return $products;
    }
    public function getSelectedProducts() {
        $products = array();
        $selected = Mage::registry('current_category')->getSelectedProducts();
        if (!is_array($selected)){
            $selected = array();
        }
        foreach ($selected as $product) {
            $products[$product->getId()] = array('position' => $product->getPosition());
        }
        return $products;
    }
    public function getRowUrl($item){
        return '#';
    }
    public function getGridUrl(){
        return $this->getUrl('*/*/productsGrid', array(
            'id'=>$this->getCategory()->getId()
        ));
    }
    public function getCategory(){
        return Mage::registry('current_category');
    }
    protected function _addColumnFilterToCollection($column){
        // Set custom filter for in product flag
        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;
    }
}

controllers/Adminhtml/Promotion/Category/ProductController.php:

<?php

require_once ("Mage/Adminhtml/controllers/Catalog/ProductController.php");
class Forideas_Promotion_Adminhtml_Promotion_Category_ProductController extends Mage_Adminhtml_Catalog_ProductController
{

    public function productsAction(){
        //$this->_initEntity(); //if you don't have such a method then replace it with something that will get you the entity you are editing.
        $this->loadLayout();
        $this->getLayout()->getBlock('category.edit.tab.product')
            ->setCategoryProducts($this->getRequest()->getPost('category_products', null));
        $this->renderLayout();
    }
    public function productsgridAction(){
        //$this->_initCategory();
        $this->loadLayout();
        $this->getLayout()->getBlock('category.edit.tab.product')
            ->setCategoryProducts($this->getRequest()->getPost('category_products', null));
        $this->renderLayout();
    }

}

Model/Observer.php

<?php

class Forideas_Promotion_Model_Observer{


    public function addCategoryTab($observer)
    {
        $block = $observer->getEvent()->getTabs();

            $block->addTab('features', array(
                'label' => Mage::helper('catalog')->__('Some Label here'),

                'url'   => Mage::helper('adminhtml')->getUrl('adminhtml/promotion_category_product/productsgrid', array('_current' => true)),
                'class' => 'ajax', 
            ));


    }

}

sql/setup/install-0.1.0.php

$this->startSetup();

$table = $this->getConnection()
    ->newTable($this->getTable('promotion/category_product'))
    ->addColumn('rel_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'unsigned'  => true,
        'identity'  => true,
        'nullable'  => false,
        'primary'   => true,
        ), 'Relation ID')
    ->addColumn('category_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'unsigned'  => true,
        'nullable'  => false,
        'default'   => '0',
    ), 'Category ID')
    ->addColumn('product_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'unsigned'  => true,
        'nullable'  => false,
        'default'   => '0',
    ), 'Product ID')
    ->addColumn('position', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'nullable'  => false,
        'default'   => '0',
    ), 'Position')
    ->addIndex($this->getIdxName('promotion/category_product', array('product_id')), array('product_id'))
    ->addForeignKey($this->getFkName('promotion/category_product', 'category_id', 'promotion/category', 'entity_id'), 'category_id', $this->getTable('promotion/category'), 'entity_id', Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
    ->addForeignKey($this->getFkName('promotion/category_product', 'product_id', 'catalog/product', 'entity_id'),    'product_id', $this->getTable('catalog/product'), 'entity_id', Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
    ->setComment('Category to Product Linkage Table');
$this->getConnection()->createTable($table);

$this->endSetup();
neko
  • 23
  • 8

2 Answers2

0

Don't know for what purpose you have uploaded all these code. As far as I can see it doesn't refer to your question. If you want to add new tab do following:

config.xml

<adminhtml>
    <events>
        <adminhtml_catalog_category_tabs>
            <observers>
                <add_new_tab>
                    <type>singleton</type>
                    <class>company_module/observer</class>
                    <method>addNewCategoryTab</method>
                </add_new_tab>
            </observers>
        </adminhtml_catalog_category_tabs>
    </events>
</adminhtml>

Model/Observer.php

class Company_Module_Model_Observer
{
    public function addNewCategoryTab($observer)
    {
        $tabs = $observer->getTabs();
        $tabs->addTab('prod', array(
            'label'     => Mage::helper('catalog')->__('Other Products'),
            'content'   => $tabs->getLayout()->createBlock(
                'adminhtml/catalog_category_tab_product',
                'category.product.grid'
            )->toHtml(),
        ));
    }

Than use your block extended from adminhtml/catalog_category_tab_product with yours rewrited _prepareCollection method. (Don't forget to put you block inside createBlock method)

zhartaunik
  • 932
  • 12
  • 29
  • Ok i extended the block and used it how you proposed and it works, but where/how can i access/save the products that are selected in this grid ? – neko Apr 10 '15 at 13:40
  • And i have one more problem with the changing pages and applying filter, meaning that when i use one of the above the products are changing but the ajax loader will not disappear. – neko Apr 10 '15 at 14:57
  • The question was about how to create additional tab. I showed you how to do it. If you want to edit content of the tab - look at the example adminhtml/catalog_category_tab_product, create your own block with its own logic. – zhartaunik Apr 11 '15 at 07:10
0

I found the answer to your 'ajax loader will not disappear' problem. This is due to the fact that the HTML that is returned from the AJAX call actually refers to the original table, catalog_category_products_table. But the Javascript is looking for your own table name but can't find it and thus the infinite Please wait loader.

The solution is to create your own controller that extends Mage_Adminhtml_Catalog_CategoryController and load your own block with your gridname there. Then, in the block where you extended Mage_Adminhtml_Block_Catalog_Category_Tab_Product, you will define getGridUrl() and return the path to your newly created controller. Now everything will just work fine.

peterjaap
  • 255
  • 1
  • 8