How to Create a Custom Indexer in Magento 1.9

indexermagento-1.9

I'm trying to create a custom indexer for a particular product attribute.
I need to:

  • read the product attribute value
  • process it in some way ( not relevant )
  • save it in a index table

The above steps could be implemented in a custom script but I would like integrate the indexer using the patter used by other indexer in Magento.

I can see that Magento default indexer implement this abstract class Mage_Index_Model_Indexer_Abstract
… It looks not easy to understand the process from the code and I cannot find any documentation for it.

Any help is appreciate thanks.

Best Answer

Following info should be a generic guide line that lead to a basic understanding of the whole indexer thing, so are not a complete 'walkthrough' ... ( if you want to contribute to this answer you are welcome )

There are at least 3 steps required here:

  1. Create an index table and related resource model
  2. Create an Indexer model that implement Mage_Index_Model_Indexer_Abstract
  3. add your indexer to Magento configuration

Suggested documentation:

  1. Probably the best way to dig into this is to give a look at Mage_Catalog_Model_Product_Indexer_Price ( this is one of the easier index implementation ).
  2. This resource, at the moment, looks the best guide to understand the whole process to decide what it is the action that is required.

STEP 1
Just add your index table in the installer, as for any other module table.
Your resource model needs to implement the logic for Reindex All in the reindexAll() method: you would probably process all entities here an extract all data.

STEP 2
_registerEvent(),_processEvent() are the important method here, you will need to dig a bit in the below guide to understand the logic behind them

Basically _registerEvent() add some data to the $event, on the base of the 'event type' and the 'entity type'. This extra data will be used in _processEvent() method.

You will need to implement at least the following methods in your model.

/**
 * Data key for matching result to be saved in
 */
const EVENT_MATCH_RESULT_KEY = 'some_key';

/**
 * Initialize resource model
 *
 */
protected function _construct()
{
    $this->_init('module/resource_model');
}

/**
 * @var  Used by matchEvent()
 * for example if you are processing products ...
 */
protected $_matchedEntities = array(
    Mage_Catalog_Model_Product::ENTITY => array(
        Mage_Index_Model_Event::TYPE_SAVE,
        Mage_Index_Model_Event::TYPE_MASS_ACTION,
        Mage_Index_Model_Event::TYPE_DELETE
    )
);

 /**
 * Get Indexer name
 *
 * @return string
 */
public function getName(){
    return 'My indexer Name';
}

/**
 * Get Indexer description
 *
 * @return string
 */
public function getDescription()
{
    return 'My indexer Description';
}

/**
 * Register indexer required data inside event object
 *
 * @param   Mage_Index_Model_Event $event
 *
 * Register data required by process in event object
 * @param Mage_Index_Model_Event $event
 */
protected function _registerEvent(Mage_Index_Model_Event $event)
{
    $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
    $entity = $event->getEntity();
    $dataObj = $event->getDataObject();

    if ($entity == Mage_Catalog_Model_Product::ENTITY) {
        if ($event->getType() == Mage_Index_Model_Event::TYPE_SAVE) {
            $event->addNewData('yourmodule_update_product_id', $dataObj->getId());
        } elseif ($event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
            $event->addNewData(' yourmodule _delete_product_id', $dataObj->getId());
        } elseif ($event->getType() == Mage_Index_Model_Event::TYPE_MASS_ACTION) {
            $event->addNewData(' yourmodule _mass_action_product_ids', $dataObj->getProductIds());
        }
    }
}

/**
 * Process event based on event state data
 *
 * @param   Mage_Index_Model_Event $event
 */
protected function _processEvent(Mage_Index_Model_Event $event){
    /** DO STUFF **/
    return $this;
}

STEP 3
Add this to your configuration, [module/model] is the model created in step 2. So at this point if you go in system->indexer you will see a new entry

<global>
    ......
    <index>
        <indexer>
            <some_key>
                <model>module/model</model>
            </some_key>
        </indexer>
    </index>
    ......
</global> 

Sources:

Related Topic