2

I need to find a way to enhance the admin products grid with capability to fill in the SKU field more than one reference.

For example, get copy/paste from an Excel list multiple sku and get the matching list on Magento.

I've already a solution in place based on default grid block rewriting but there is a conflict with a new cleaner extension I want to use with (Enhanced Admin Grids from Magento connect).

What is the best way to achieve this? Rewriting how the default sku field is working or adding a new custom one?

5

In my opinion adding a new custom clumn is better because of two reasons:

  1. The core team may modify the existing sku column any time. Additionally, as you said any extension developer may rewrite this grid or more specific this column given it's a very basic one. If you create your own column probably nobody else knows about it what makes it less likely that somebody will screw around with your column

  2. It's hard (if not impossible) to modify the existing columns without rewrites or observer a very generic event and therefore possibly slowing down the page generation.

Having said that and contra-dicting myself there is a way to use a product-grid-specific event and modify the original sku column. You should document this though as it's not very intuitive if you find the code again two years later.

The solution is: observe the event adminhtml_catalog_product_grid_prepare_massaction amd manipulate the already existing column.

  1. I'll assume that you created an extension before so I'll skip Magento extension creation basics. I call my example extension Emzee_MultiSkuFilter.

  2. Add an observer for adminhtml_catalog_product_grid_prepare_massaction in app/code/local/Emzee/MultiSkuFilter/etc/config.xml:

    <?xml version="1.0"?>
    <config>
        <modules>
            <Emzee_MultiSkuFilter>
                <version>1.0.0</version>
            </Emzee_MultiSkuFilter>
        </modules>
        <adminhtml>
            <events>
                <adminhtml_catalog_product_grid_prepare_massaction>
                    <observers>
                        <emzee_multiskufilter>
                            <class>emzee_multiskufilter/observer</class>
                            <method>adminhtmlCatalogProductGridPrepareMassaction</method>
                        </emzee_multiskufilter>
                    </observers>
                </adminhtml_catalog_product_grid_prepare_massaction>
            </events>
        </adminhtml>
        <global>
            <models>
                <emzee_multiskufilter>
                    <class>Emzee_MultiSkuFilter_Model</class>
                    <resourceModel>emzee_multiskufilter_resource</resourceModel>
                </emzee_multiskufilter>
                <emzee_multiskufilter_resource>
                    <class>Emzee_MultiSkuFilter_Model_Resource</class>
                </emzee_multiskufilter_resource>
            </models>
            <helpers>
                <emzee_multiskufilter>
                    <class>Emzee_MultiSkuFilter_Helper</class>
                </emzee_multiskufilter>
            </helpers>
        </global>
    </config>
    
  3. In the observer class app/code/local/Emzee/MultiSkuFilter/Model/Observer.php you receive the grid block. Find the sku column and define a filter condition callback which will be used to query the database when you filter by sku:

    <?php
    
    class Emzee_MultiSkuFilter_Model_Observer
    {
        public function adminhtmlCatalogProductGridPrepareMassaction(Varien_Event_Observer $observer)
        {
            $block = $observer->getEvent()->getBlock();
            $column = $block->getColumn('sku');
            $column->setData('filter_condition_callback', array(
                Mage::getResourceModel('emzee_multiskufilter/filter'), 'multiSkuFilter'
            ));
            return $this;
        }
    }
    
  4. In the filter callback app/code/local/Emzee/MultipleSkuFilter/Model/Resource/Filter.php, split up the SKUs and construct your SQL. It's not the most elegant code but it works. By default the SKUs have to be an exact match but you also can search for %test% to use wildcards.

    <?php
    
    class Emzee_MultiSkuFilter_Model_Resource_Filter
    {
        public function multiSkuFilter($collection, $column)
        {
            if (!$value = $column->getFilter()->getValue()) {
                return $this;
            }
    
            /**
             * @var Mage_Catalog_Model_Resource_Product_Collection $collection
             * @var Zend_Db_Select $select
             */
            $select = $collection->getSelect();
            $connection = $collection->getConnection();
            $conditions = array();
            $skus = explode(' ', $value);
            foreach ($skus as $sku)  {
                $condition = $connection->quoteInto('`e`.' . $column->getIndex() . ' LIKE ?', $sku);
                $conditions[] = $condition;
    
            }
    
            $sql = implode(' ' . Zend_Db_Select::SQL_OR . ' ', $conditions);
            $select->where($sql);
            return $this;
        }
    
    }
    

This is what the result looks like:

Grid without filtering

Filtering by 2 SKUs

Filtering by exact match

Filtering by wild card

| improve this answer | |
  • nice solution, but why do you write custom SQL instead of using magentos addAttributeToFilter() method? – Fabian Blechschmidt Aug 31 '14 at 17:55
  • These are multiple OR clauses enclosed by an AND clause. Wasn't sure if that can be easily done with addAttributeToFilter? – Matthias Zeis Aug 31 '14 at 18:49
  • Theoretical it should work like here magento.stackexchange.com/questions/7908/… but I wasn't able to reproduce this – Fabian Blechschmidt Aug 31 '14 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.