Related
I'm learning how to use magento cache and I'm a bit stuck trying to serialize a collection.
Actually this is my code:
class Feliu_Featuredcategories_Block_Topcategories extends Mage_Core_Block_Template
{
protected function _construct()
{
$storeId = Mage::app()->getStore()->getId();
$this->addData(array(
'cache_lifetime' => 3600,
'cache_tags' => array(Mage_Catalog_Model_Product::CACHE_TAG),
'cache_key' => 'homepage-most-view-' . $storeId,
));
}
public function setData()
{
$storeId = Mage::app()->getStore()->getId();
$cache = Mage::app()->getCache();
$key = 'homepage-most-view-' . $storeId;
$cached_categories = $cache->load($key);
if (! $cached_categories) {
$categories = Mage::getModel('catalog/category')
->getCollection()
->addAttributeToSelect(array('data', 'name', 'add_to_top_categories'))
->addAttributeToFilter('add_to_top_categories', array('eq' => '1'));
$categories->load();
$cache->save(serialize($categories), $key);
} else {
$categories = unserialize($cached_categories);
}
return $categories;
}
}
At first I tried to $cache->save($categories, $key); directly, but I read that collections can't be saved directly and I got an error that said: 'automatic_serialization must be on' when I tried to set automatic_serialization to true then I received a message saying that it can't be activated for security reasons.
Then I tried to serialize, just as the above code shows, but it did not work neither. It seems that magento protects collections from being serialized because they can be really big.
So finally I tried to urlencode() before serializing serialize(urlencode($categories)) and urldecode(unserialize($categories)) but I got the string "N;" serializing with this aproach and an empty string when unserialize.
I'm using magento 1.9.3 and I followed this documentation and previous questions:
https://www.nicksays.co.uk/developers-guide-magento-cache/
http://inchoo.net/magento/magento-block-caching/
Magento: serialization error on caching Collection
Magento how to cache a productCollection
And some other questions about this, but maybe there is no need to write too much links, I don't want to spam.
Edit: If instead a collection I use an array like
$categories = array('banana', 'apple', 'kiwi', 'strawberry', 'pomelo', 'melon');
then the code seems to work correctly
Finally I solved it, the answer it's easiest than I though at the beginning but I write it here because maybe it will help somebody in the future.
As collections cannot be cached nor serialized, I made an array with the data I need from the collection.
$categories = Mage::getModel('catalog/category')
->getCollection()
->addAttributeToFilter('add_to_top_categories', array('eq' => '1'))
->addAttributeToSelect(array('data', 'name'));
I make the collection adding only the fields I need, and selecting the data I want.
$array = array();
foreach ($categories as $_category)
{
array_push($array, array('url' => $_category->getUrl(), 'name' => $_category->getName()));
}
Now I make an array that holds objects with the data I wanted. Next step is serialize the array I just made and save it on the cache.
$cache->save(serialize($array), $key, array('custom_home_cache'), 60*60);
and retrieve the data is as easy as $cache->load(unserialize($key))
I want to add a custom field in Attribute option in Manage Attribute Options menu in admin. Like value column beside the position column in admin. I have attached an image.
What I have done ... (Magento 1.8)
created a new field in eav_attribute_option table named value after sort_order filed.
changed magento\app\design\adminhtml\default\default\template\eav\attribute\options.phtml this file to show the Value column beside the Position column.
changed getOptionValues() method in this file magento\app\code\core\Mage\Eav\Block\Adminhtml\Attribute\Edit\Options\Abstract.php to get data for my custom value column from database and show in admin side. It shows the default value of db in admin form.
But when I want to save from admin panel the data doesn’t save in db.
I've been trying to find the model or controller that actually handles writing into the database to make sure my new field saves too.
Any help would be appreciated.
(I'd post an image to make you understand, but I can't since I need 10 points to be able to do it.)
Got it!
Update: Mage/Eav/Model/Resource/Entity/Attribute.php
in function: _saveOption(Mage_Core_Model_Abstract $object)
change:
$sortOrder = !empty($option[’order’][$optionId]) ? $option[’order’][$optionId] : 0;
if (!$intOptionId) {
$data = array(
‘attribute_id’ => $object->getId(),
‘sort_order’ => $sortOrder,
);
$adapter->insert($optionTable, $data);
$intOptionId = $adapter->lastInsertId($optionTable);
} else {
$data = array(’sort_order’ => $sortOrder);
$where = array(’option_id =?’ => $intOptionId);
$adapter->update($optionTable, $data, $where);
}
for this:
$sortOrder = !empty($option[’order’][$optionId]) ? $option[’order’][$optionId] : 0;
$yourAttribute = (isset($option[’your_attr_field’]) && !empty($option[’your_attr_field’][$optionId])) ? $option[’your_attr_field’][$optionId] : ‘’;
if (!$intOptionId) {
$data = array(
‘attribute_id’ => $object->getId(),
‘sort_order’ => $sortOrder,
‘your_attr_field’ => $yourAttribute
);
$adapter->insert($optionTable, $data);
$intOptionId = $adapter->lastInsertId($optionTable);
} else {
$data = array(’sort_order’ => $sortOrder, ‘your_attr_field’ => $yourAttribute);
$where = array(’option_id =?’ => $intOptionId);
$adapter->update($optionTable, $data, $where);
}
I could use some help in making all this changes 'the Magento way'
I want to change the attribute set of Magento. I searched through, and everyone suggested to delete the product and re-import it with new attribute set.
I did the same however after importing the data I could not see product reviews and associated blog post with product.
Can anyone tell me is it possible to get product reviews and associated blog post after re-importing the product with new attribute set.
Once set you can't change the attribute set of a product. But it's possible using this module so you don't have to reimport your data
https://marketplace.magento.com/flagbit-magento-changeattributeset.html
It's also possible to change the attribute set directly in the database.
Look up the attribute set ID in table eav_attribute_set
Change the attribute set ID in catalog_product_entity
Of course, be careful when changing data this way.
It is fiddly to do and a bit messy:
Make sure new attribute set is set up
Export the products you want to change
Delete the products that you are changing on the site
Change the attribute set on the downloaded file
Import changed file again
Open each changed product, set their attribute values, save it
Or do what I do, install this great extension from Amasty http://amasty.com/mass-product-actions.html - it makes changing a breeze and gives many more time saving and enhancing options.
Once you delete the product you can't get the old review.
You don't need to delete the product . You can change the attribute set by editing and use.
other wise create a new attribute set and create new product.
Yes. We can change product attribute set programmatically.
I prefer to create massaction in catalog product grid to multiselect product and then select massaction for the products.
Creating massaction in grid.php
$sets = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
->load()
->toOptionHash();
$this->getMassactionBlock()->addItem('changeattributeset', array(
'label'=> Mage::helper('catalog')->__('Change attribute set'),
'url' => $block->getUrl('*/*/changeattributeset', array('_current'=>true)),
'additional' => array(
'visibility' => array(
'name' => 'attribute_set',
'type' => 'select',
'class' => 'required-entry',
'label' => Mage::helper('catalog')->__('Attribute Set'),
'values' => $sets
)
)
));
Creating controller action for change attribute sets of the selected products.
public function changeattributesetAction()
{
$productIds = $this->getRequest()->getParam('product');
$storeId = (int)$this->getRequest()->getParam('store', 0);
if (!is_array($productIds)) {
$this->_getSession()->addError($this->__('Please select product(s)'));
} else {
try {
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')
->unsetData()
->setStoreId($storeId)
->load($productId)
->setAttributeSetId($this->getRequest()->getParam('attribute_set'))
->setIsMassupdate(true)
->save();
}
Mage::dispatchEvent('catalog_product_massupdate_after', array('products'=>$productIds));
$this->_getSession()->addSuccess(
$this->__('Total of %d record(s) were successfully updated', count($productIds))
);
}
catch (Exception $e) {
$this->_getSession()->addException($e, $e->getMessage());
}
}
$this->_redirect('adminhtml/catalog_product/index/', array());
}
You can add to your data patch apply function something like this:
public function apply(): self
{
$this->moduleDataSetup->getConnection()->startSetup();
/** #var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttributeToSet(
Product::ENTITY,
'Default',
'General',
CustomAttributesInterface::ATTRIBUTE_CODE_MANUFACTURER
);
$this->moduleDataSetup->getConnection()->endSetup();
return $this;
}
This changes the manufacturer products attribute to the Default attribute set. (By default this attribute has no attribute set.)
Hope it helps :)
I created a new attribute ("for example my_attribute"). Magento's store already has many attribute sets (approx 20).
It's a very time consuming process if I manually add the attribute to the sets because my server is very slow.
I want to assign this new attribute("my_attribute") to all attribute sets programmatically.
Can anyone can help me?
Thanks in advance.
It's quite simple. In a custom module setup script:
$installer = Mage::getResourceModel('catalog/setup','default_setup');
$installer->startSetup();
$installer->addAttribute(
'catalog_product',
'your_attribute_code',
array(
'label' => 'Attribute Label',
'group' => 'General', // this will add to all attribute sets in the General group
// ...
)
)
$installer->endSetup();
For other utilities, see Mage_Eav_Model_Entity_Setup.
Here's something quick, dirty, and untested :)
<?php
$attributeId = ID_HERE;
$installer = new Mage_Catalog_Model_Resource_Eav_Mysql4_Setup('core_setup');
$entityType = Mage::getModel('catalog/product')->getResource()->getEntityType();
$collection = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter($entityType->getId());
foreach ($collection as $attributeSet) {
$attributeGroupId = $installer->getDefaultAttributeGroupId('catalog_product', $attributeSet->getId());
$installer->addAttributeToSet('catalog_product', $attributeSet->getId(), $attributeGroupId, $attributeId);
}
$installer = Mage::getResourceModel('catalog/setup','default_setup');
$installer->startSetup();
$attributeCode = 'my_attribute';
$entity = Mage_Catalog_Model_Product::ENTITY;
// create a new attribute if it doesn't exist
$existingAttribute = $installer->getAttribute($entity, $attributeCode);
if (empty($existingAttribute)) {
$installer->addAttribute($entity, $attributeCode, array(<configure your attribute here>));
}
$attributeId = $installer->getAttributeId($entity, $attributeCode);
// add it to all attribute sets' default group
foreach ($installer->getAllAttributeSetIds($entity) as $setId) {
$installer->addAttributeToSet(
$entity,
$setId,
$installer->getDefaultAttributeGroupId($entity, $setId),
$attributeId
);
}
$installer->endSetup();
As Attributes are not assigned with any attribute set then, you can delete that attribute you created and then create required attribute programmatically.
In the Magento wiki's Programmatically Adding Attributes and Attribute Sets Section, It describes createAttribute as the function that will solve your problem because it will create attributes and also assign them to attribute sets.
Hope This Helps!!
Additionally, Mage_Eav_Model_Entity_Setup and Mage_Catalog_Model_Resource_Setup, which extends from the aforementioned class, have all of the methods that you need to create attributes, sets, and groups. They are fairly straightforward, and they will help you understand how you're supposed to do it properly and prevent you from from writing bad or redundant code. I find most of the articles floating around the Internet and even Magento's own wiki entries feature poorly written code.
I'm trying to add a category column to the product grid.
I've modified Mage_Adminhtml_Block_Catalog_Product_Grid.
Added the following to _prepareCollection :
->joinField('category_ids',
'catalog/category_product_index',
'category_id',
'product_id=entity_id',
null,
'left')
which gives me an error :
a:5:{i:0;s:72:"Item (Mage_Catalog_Model_Product) with the same id "16243" already exist".
In prepareColumns I'm adding :
$this->addColumn('category_ids',
array(
'header'=> Mage::helper('catalog')->__('Categories'),
'index' => 'category_ids',
'width' => '150px'
));
How can I fix my query so I won't get the error?
Is it possible to show and filter by category names instead of ids?
A forum post shows a similar code but I couldn't make it work with categories
http://www.magentocommerce.com/boards/viewthread/44534/
static protected $COLUMN_ID_TRADE_REFERENCES = 'ref_text';
protected function _prepareCollection()
{
$store = $this->_getStore();
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('name')
->addAttributeToSelect('attribute_set_id')
->addAttributeToSelect('type_id')
->addAttributeToSelect('ref_text')
->joinTable('productreferences/reference',
'product_id=entity_id',
array('ref_text'),
null,
'left')
->joinField('qty',
'cataloginventory/stock_item',
'qty',
'product_id=entity_id',
'{{table}}.stock_id=1',
'left')
->addStaticField('ref_text')
->addExpressionAttributeToSelect(self::$COLUMN_ID_TRADE_REFERENCES,
'GROUP_CONCAT(ref_text SEPARATOR " ; ")',
'ref_text')
->groupByAttribute('entity_id');
I’ve worked several days on this problem and have finally solved it. Since my solution is only one part of several product admin grid enhancements I have developed, I can’t show you a simple cut-and-paste solution. Instead, I will focus on what to do instead of how to do it. Of course I’ll provide as many code snippets as possible, but I cannot guarantee they will work on their own. Also, please note that the solution I describe has been tested with Magento 1.3.2.4 only.
First of all, the category_ids attribute of your products will most likely be of no use for you. This is a comma-separated list of category IDs (for example 206,208,231). I assume that most people will not need the categories in that form. (If you do, you’re lucky, simply add a column containing the category_ids attribute to your grid and be done.) Additionally, as far as I know this attribute does not exist anymore in Magento 1.4.
The problem with this attribute is that it is just a redundant copy of the actual category assignment. The authoritative category information is stored in the table catalog_category_product, one row per product/category pair.
Since categories are entities in Magento and are not directly referenced via a product attribute, you cannot use joinAttribute() or joinField() with them. As far as I know, you cannot join at all entities of another type than that of the collection into it.
However, you can use joinTable() to put the category IDs into the result set like this:
$collection->joinTable(
'catalog/category_product',
'product_id=entity_id',
array('single_category_id' => 'category_id'),
null,
'left'
);
As you’ve already found out, this has to be added to Mage_Adminhtml_Block_Catalog_Product_Grid’s _prepareCollection() function. The best way to do this, as always, is to create your own module and add a class that extends the Magento class. Since there is no way to cleanly hook into the original _prepareCollection() method, you will have to copy the whole method over to your overriding class and add the code there. (Remember to check for code changes in the original when updating Magento.)
We’re using a left join here, which will lead to multiple rows being returned for products having multiple categories. This is basically what we want, since we can then take the single category IDs (that’s why I called the field single_category_id) and translate them to the category name. However, the collection cannot handle multiple rows for the same entity (i.e. the same product). That’s possibly where your error message comes from.
Now, getting the category name is a bit complicated, since we cannot join other entity types into our collection. Therefore we’ll have to do it the dirty way and directly take the names out of the EAV database data for category entities. I’ve tried to stay as clean as possible and not hard-code any attribute type IDs or the like into the query. You will need some knowledge about Magento’s EAV structure to understand what’s going on below.
Here’s how it works:
$res = Mage::getSingleton('core/resource');
$eav = Mage::getModel('eav/config');
$nameattr = $eav->getAttribute('catalog_category', 'name');
$nametable = $res->getTableName('catalog/category') . '_' . $nameattr->getBackendType();
$nameattrid = $nameattr->getAttributeId();
After this, $nametable will contain the name of the database table that contains the category’s name, $nameattrid will contain the numeric attribute ID for “name”.
Having this information, we can now join the correct EAV table manually into the query:
$collection->joinTable(
$nametable,
'entity_id=single_category_id',
array('single_category_name' => 'value'),
"attribute_id=$nameattrid",
'left'
);
This will add a column single_category_name to our result rows.
Remember that we still have one row per category for multiple-category products. That’s what we’re going to fix next. To do that, we’ll have to group the resulting rows by the product ID and simultaneously concatenate all those single_category_name columns.
Grouping is relatively easy:
$collection->groupByAttribute('entity_id');
However, you should insert this before the code that joins the category name table. Don’t worry, I’ll show you a correctly sorted chunk of code at the bottom.
Concatenating the category names is somewhat harder. Since we manually brought in an EAV table, we cannot use addExpressionAttributeToSelect() on the category name attribute. Instead, we have to go down all the way to the Zend Framework database classes and manipulate the query there:
$collection->getSelect()->columns(
array('category_names' => new Zend_Db_Expr(
"IFNULL(GROUP_CONCAT(`$nametable`.`value` SEPARATOR '; '), '')"
)));
This retrieves the underlying Zend_Db_Select and adds a new expression column to it, which will concatenate the category names, separated by semicolon-space. Additionally, the IFNULL will take care of products not having any category at all, setting the category_names column to the empty string instead of a MySQL NULL value.
Let’s summarize it up to here:
$collection->joinTable('catalog/category_product',
'product_id=entity_id', array('single_category_id' => 'category_id'),
null, 'left')
->groupByAttribute('entity_id')
->joinTable($nametable,
"entity_id=single_category_id", array('single_category_name' => 'value'),
"attribute_id=$nameattrid", 'left')
->getSelect()->columns(array('category_names' => new Zend_Db_Expr("IFNULL(GROUP_CONCAT(`$nametable`.`value` SEPARATOR '; '), '')")));
In order to show the column, you have to add something like this to prepareColumns():
$this->addColumn('category_ids',
array(
'header' => Mage::helper('catalog')->__('Categories'),
'index' => 'category_names',
'width' => '150px',
'filter' => false,
'sortable' => false,
));
The filter and sortable flags will prevent the column header to be clickable and also remove the filter text box for that column. Since we have done some heavy workarounding to get the categories column into the grid, these features won’t work anyway. I don’t need them, therefore I have not looked into how hard it is to make them work.
Now, if you have copied these two chunks of code into your installation, you’ll note that while the grid will correctly show the first page of results, above the table it will say that only one product has been returned and you won’t be able to paginate through the results. That’s because Magento uses a separate, automatically generated SQL query to count the number of results, and this method does not work with GROUP BY clauses. To fix that, we’ll have to override the collection class and add a workaround to it.
This is a class with that workaround:
class Our_Catalog_Model_Resource_Eav_Mysql4_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection {
public $calculateSizeWithoutGroupClause = false;
public function getSelectCountSql()
{
if (!$this->calculateSizeWithoutGroupClause) {
return parent::getSelectCountSql();
}
$this->_renderFilters();
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
$countSelect->reset(Zend_Db_Select::COLUMNS);
$countSelect->reset(Zend_Db_Select::GROUP);
$countSelect->from('', 'COUNT(DISTINCT `e`.`entity_id`)');
return $countSelect;
}
}
The getSelectCountSql() method is based on the original one (and even calls it if $calculateSizeWithoutGroupClause is not set), but additionally resets the GROUP BY clause.
Save this new class as app/code/local/Our/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php (or replace Our by whatever your module name is) and enable the rewrite by changing your app/code/local/Our/Catalog/etc/config.xml to contain a <models> block:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Our_Catalog>
<version>1.2.3</version>
</Our_Catalog>
</modules>
<global>
<models>
<catalog_resource_eav_mysql4>
<rewrite>
<product_collection>Our_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</product_collection>
</rewrite>
</catalog_resource_eav_mysql4>
</models>
</global>
</config>
Finally, setting
$collection->calculateSizeWithoutGroupClause = true;
in _prepareCollection() will enable our workaround for the admin grid and all is fine.
Per the quote above.
The filter and sortable flags will prevent the column header to be clickable and also remove the filter text box for that column. Since we have done some heavy workarounding to get the categories column into the grid, these features won’t work anyway. I don’t need them, therefore I have not looked into how hard it is to make them work.
All you need to do is paste the code below
$collection = Mage::getModel('catalog/category')->getCollection()->addAttributeToSelect('name');
$options = array();
foreach ($collection as $item){
if($item->getId() != ''){
$options[$item->getId()] = $item->getName();
}
}
$this->addColumn('category_ids',
array(
'header' => Mage::helper('catalog')->__('Categories'),
'index' => 'single_category_id',
'width' => '150px',
'type' => 'options',
'options' => $options
));
in place of
$this->addColumn('category_ids',
array(
'header' => Mage::helper('catalog')->__('Categories'),
'index' => 'category_names',
'width' => '150px',
'filter' => false,
'sortable' => false,
));
if you just want to add the category (not the category path) and if the product has only one category, add this to the collection-setup:
$collection->joinAttribute('catname','catalog_category/name','category_ids',null,'left');
to display the name o all categories you can use
$this->addColumn('category_ids',
array(
'header'=> Mage::helper('catalog')->__('Category'),
'type' => 'options',
'index' => 'category_ids',
'options' => $this->catOptions,
'renderer' => 'Your_Module_Block_Adminhtml_List_Cat',
));
in your class block
class Your_Module_Block_Adminhtml_List_Cat extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
public function render(Varien_Object $row)
{
$product = Mage::getModel('catalog/product')->load($row->getEntityId());
$cats = $product->getCategoryIds();
$allCats = '';
foreach($cats as $key => $cat)
{
$_category = Mage::getModel('catalog/category')->load($cat);
$allCats.= $_category->getName();
if($key < count($cats)-1)
$allCats.= ' ,';
}
return $allCats;
}
}
I know it is too late to answer but recently i saw this question so i'm answering as it can help others too.
Reference here: here
You have to create an extension to display category in product grid. Please create following files and it will work for you:
Create a new file on app/code/local/SoftProdigy/AdminGridCategoryFilter/Block/Catalog/Product/Grid/Render/Category.php location and add following code:
<?php
class SoftProdigy_AdminGridCategoryFilter_Block_Catalog_Product_Grid_Render_Category extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
public function render(Varien_Object $row)
{
$product = Mage::getModel('catalog/product')->load($row->getEntityId());
$cats = $product->getCategoryIds();
$allCats = '';
foreach($cats as $key => $cat)
{
$_category = Mage::getModel('catalog/category')->load($cat);
$allCats.= $_category->getName();
if($key < count($cats)-1)
$allCats.= ',<br />';
}
return $allCats;
}
}
Create a new file on app/code/local/SoftProdigy/AdminGridCategoryFilter/etc/config.xml location and add following code:
<?xml version="1.0"?>
<config>
<modules>
<SoftProdigy_AdminGridCategoryFilter>
<version>0.0.0.1</version>
</SoftProdigy_AdminGridCategoryFilter>
</modules>
<global>
<models>
<admingridcategoryfilter>
<class>SoftProdigy_AdminGridCategoryFilter_Model</class>
</admingridcategoryfilter>
</models>
<helpers>
<admingridcategoryfilter>
<class>SoftProdigy_AdminGridCategoryFilter_Helper</class>
</admingridcategoryfilter>
</helpers>
<blocks>
<admingridcategoryfilter>
<class>SoftProdigy_AdminGridCategoryFilter_Block</class>
</admingridcategoryfilter>
</blocks>
</global>
<adminhtml>
<events>
<core_block_abstract_prepare_layout_before>
<observers>
<admingridcategoryfilter>
<class>admingridcategoryfilter/observer</class>
<method>addCategoryFilterToProductGrid</method>
</admingridcategoryfilter>
</observers>
</core_block_abstract_prepare_layout_before>
</events>
</adminhtml>
</config>
Create a new file on app/code/local/SoftProdigy/AdminGridCategoryFilter/Helper/Data.php location and add following code:
<?php
class SoftProdigy_AdminGridCategoryFilter_Helper_Data extends Mage_Core_Helper_Abstract
{
}
Create a new file on app/code/local/SoftProdigy/AdminGridCategoryFilter/Model/Observer.php location and add following code:
<?php
class SoftProdigy_AdminGridCategoryFilter_Model_Observer
{
public function addCategoryFilterToProductGrid(Varien_Event_Observer $observer)
{
$block = $observer->getEvent()->getBlock();
if( ($block instanceof Mage_Adminhtml_Block_Catalog_Product_Grid) ) {
$block->addColumnAfter('softprodigy_category_list', array(
'header' => Mage::helper('admingridcategoryfilter')->__('Category'),
'index' => 'softprodigy_category_list',
'sortable' => false,
'width' => '250px',
'type' => 'options',
'options' => Mage::getSingleton('admingridcategoryfilter/system_config_source_category')->toOptionArray(),
'renderer' => 'admingridcategoryfilter/catalog_product_grid_render_category',
'filter_condition_callback' => array($this, 'filterCallback'),
),'name');
}
}
public function filterCallback($collection, $column)
{
$value = $column->getFilter()->getValue();
$_category = Mage::getModel('catalog/category')->load($value);
$collection->addCategoryFilter($_category);
return $collection;
}
}
Create a new file on app/code/local/SoftProdigy/AdminGridCategoryFilter/Model/System/Config/Source/Category.php location and add following code:
<?php
class SoftProdigy_AdminGridCategoryFilter_Model_System_Config_Source_Category
{
public function toOptionArray($addEmpty = true)
{
$options = array();
foreach ($this->load_tree() as $category) {
$options[$category['value']] = $category['label'];
}
return $options;
}
public function buildCategoriesMultiselectValues(Varien_Data_Tree_Node $node, $values, $level = 0)
{
$level++;
$values[$node->getId()]['value'] = $node->getId();
$values[$node->getId()]['label'] = str_repeat("--", $level) . $node->getName();
foreach ($node->getChildren() as $child)
{
$values = $this->buildCategoriesMultiselectValues($child, $values, $level);
}
return $values;
}
public function load_tree()
{
$store = Mage::app()->getFrontController()->getRequest()->getParam('store', 0);
$parentId = $store ? Mage::app()->getStore($store)->getRootCategoryId() : 1; // Current store root category
$tree = Mage::getResourceSingleton('catalog/category_tree')->load();
$root = $tree->getNodeById($parentId);
if($root && $root->getId() == 1)
{
$root->setName(Mage::helper('catalog')->__('Root'));
}
$collection = Mage::getModel('catalog/category')->getCollection()
->setStoreId($store)
->addAttributeToSelect('name')
->addAttributeToSelect('is_active');
$tree->addCollectionData($collection, true);
return $this->buildCategoriesMultiselectValues($root, array());
}
}
Create a new file on app/etc/modules/SoftProdigy_AdminGridCategoryFilter.xml location and add following code:
<?xml version="1.0"?>
<config>
<modules>
<SoftProdigy_AdminGridCategoryFilter>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Catalog />
<Mage_Adminhtml />
</depends>
</SoftProdigy_AdminGridCategoryFilter>
</modules>
</config>
Now clear cache from cache management and you can see category column in product grid.