Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Индексация в MagentoВиктор ТихончукMagento System Architect
Модуль Mage_IndexСобытияИндексаторИндексПроцесс
СобытиеMage_Index_Model_EventСобытие – то, что происходит в некоторый момент времени и рассматривается как изменение состояния сущности.Событие хранит информацию о сущности, с которой произошло действие и тип действия.Типы изменений сущности (event type)Сохранение (SAVE)Удаление (DELETE)Групповая обработка (MASS_ACTION)
ОбработчикMage_Index_Model_IndexerprocessEntityAction($entity, $entityType, $eventType)logEvent($entity, $entityType, $eventType)registerEvent(Mage_Index_Model_Event $event)indexEvent(Mage_Index_Model_Event $event)indexEvents($entity = null, $type = null)
Изменения в абстрактной моделиПроцесс сохранения_getResource()->beginTransaction()_beforeSave()_getResource()->save()_afterSave()_getResource()->commit()afterCommitCallback()Новые событияmodel_save_commit_after{eventPrefix}_save_commit_after
Изменения в абстрактной моделиПроцесс удаления_getResource()->beginTransaction()_beforeDelete()_getResource()->delete()_afterDelete()_getResource()->commit()_afterDeleteCommit()Новые событияmodel_delete_commit_after{eventPrefix}_delete_commit_after
Сущностиcatalog/product (SAVE, DELETE, MASS_ACTION)catalog/category (SAVE, DELETE)catalog/resource_eav_attribute (SAVE, DELETE)customer/group (SAVE)cataloginventory/stock_item (SAVE)tag/tag (SAVE)core/store (SAVE, DELETE)core/store_group (SAVE, DELETE)core/website (SAVE, DELETE)
Процессы и индексаторыИндексатор может работать в 2х режимах:в режиме реального времени (MODE_REAL_TIME)в ручном режиме (MODE_MANUAL)У каждого индексатора есть текущий статус:работает (STATUS_RUNNING)режим ожидания (STATUS_PENDING)необходимо перестроить (STATUS_REQUIRE_REINDEX)СобытиеREQUIRE_REINDEXMODE MANUALNew Indexer
ПроцессMage_Index_Model_ProcessmatchEvent(Mage_Index_Model_Event $event)register(Mage_Index_Model_Event $event)processEvent(Mage_Index_Model_Event $event)reindexAll()reindexEverything()indexEvents()changeStatus($status)getIndexer()
CatalogInventory Stock StatusЦель     оптимизировать затраты на подсчет возможности покупки товара при отображении товаров в каталоге, поиске и т.д.Мотивация     для простых (simple) товаров - динамически определить доступность не является трудозатратной операцией, чего не скажешь о составных (composite), для которых нужно учитывать статус всех его составляющихЗадача     сделать предварительно подсчитанный статус для каждого товара с учетом склада и веб сайта
Шаг 1: Структура данных индекса
Шаг 2: Создаем индексаторMage_CatalogInventory_Model_Indexer_Stock
Шаг 2: Создаем индексаторMage_Index_Model_Indexer_AbstractMage_CatalogInventory_Model_Indexer_Stock
Шаг 2: Создаем индексаторMage_Core_Model_AbstractMage_Index_Model_Indexer_AbstractMage_CatalogInventory_Model_Indexer_Stock
Шаг 2: Создаем индексаторMage_Core_Model_Mysql4_AbstractMage_Index_Model_Mysql4_Indexer_AbstractMage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_AbstractMage_CatalogInventory_Model_Mysql4_Indexer_Stock
Шаг 2: Создаем индексаторАбстрактные методы индексатораgetName()getDescription()_registerEvent()_processEvent()
Шаг 3: Событияprotected$_matchedEntities = array(    Mage_CatalogInventory_Model_Stock_Item::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ),    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    ),    Mage_Core_Model_Store::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ),    Mage_Core_Model_Store_Group::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ),    Mage_Core_Model_Config_Data::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ),    Mage_Catalog_Model_Convert_Adapter_Product::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ));
Шаг 4: Изменение конфигурацииprotected$_relatedConfigSettings = array(    Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK,    Mage_CatalogInventory_Helper_Data::XML_PATH_SHOW_OUT_OF_STOCK);public functionmatchEvent(Mage_Index_Model_Event$event){// check saved result in $event and return it    if ($entity == Mage_Core_Model_Config_Data::ENTITY) {$configData= $event->getDataObject();$path = $configData->getPath();if (in_array($path, $this->_relatedConfigSettings)) {$result = $configData->isValueChanged();        } else {$result = false;        }   } else {$result = parent::matchEvent($event);   }// save result in $event and return it}
Шаг 5: Регистрация событияprotected function _registerEvent(Mage_Index_Model_Event$event){    switch ($event->getEntity()) {        caseMage_Catalog_Model_Product::ENTITY:            $this->_registerCatalogProductEvent($event);            break;        // skip some cases        caseMage_Core_Model_Store::ENTITY:        caseMage_Core_Model_Config_Data::ENTITY:$reindex = Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX;            $event->addNewData('skip_call_event_handler', true);            $process = $event->getProcess();            $process->changeStatus($reindex);             if ($event->getEntity() == Mage_Core_Model_Config_Data::ENTITY) {                $configData = $event->getDataObject();$indexer = Mage::getSingleton('index/indexer');                if ($configData->getPath() == XML_PATH_SHOW_OUT_OF_STOCK) {                    $index->getProcessByCode('catalog_product_price')                        ->changeStatus($reindex);                    $indexer->getProcessByCode('catalog_product_attribute')                        ->changeStatus($reindex);                }            }            break;    }}
Шаг 5: Регистрация событияprotected function _registerCatalogProductDeleteEvent(Mage_Index_Model_Event$event){    /**@var $product Mage_Catalog_Model_Product */    $product = $event->getDataObject();     $parentIds = $this->_getResource()->getProductParentsByChild($product->getId());    if ($parentIds) {        $event->addNewData('reindex_stock_parent_ids', $parentIds);    }     return$this;}
Шаг 6: Обработка событияprotected function _processEvent(Mage_Index_Model_Event$event){$data = $event->getNewData();if (!empty($data['cataloginventory_stock_reindex_all'])) {$this->reindexAll();    }if (empty($data['skip_call_event_handler'])) {$this->callEventHandler($event);    }}
Шаг 7: Ресурс модельResource ModelType Indexer InterfaceType Indexer DefaultType Indexer Configurable
Шаг 7: Ресурс модельprotected function _getTypeIndexers()    {if (is_null($this->_indexers)) {$this->_indexers = array();$types = Mage::getSingleton('catalog/product_type')                ->getTypesByPriority();foreach ($typesas$typeId => $typeInfo) {if (isset($typeInfo['stock_indexer'])) {$modelName = $typeInfo['stock_indexer'];                } else {$modelName = $this->_defaultIndexer;                }$isComposite = !empty($typeInfo['composite']);$indexer = Mage::getResourceModel($modelName)                    ->setTypeId($typeId)                    ->setIsComposite($isComposite);$this->_indexers[$typeId] = $indexer;            }        }return$this->_indexers;    }
Шаг 7: Ресурс модельpublic functionreindexAll()    {$this->useIdxTable(true);$this->clearTemporaryIndexTable();foreach ($this->_getTypeIndexers() as$indexer) {$indexer->reindexAll();        }$this->syncData();return$this;    }
Шаг 7: Ресурс модельpublic functioncatalogProductDelete(Mage_Index_Model_Event$event)    {$data = $event->getNewData();if (empty($data['reindex_stock_parent_ids'])) {return$this;        }$adapter = $this->_getWriteAdapter();$parentIds  = array();foreach ($data['reindex_stock_parent_ids'] as$parentId => $parentType) {$parentIds[$parentType][$parentId] = $parentId;        }$adapter->beginTransaction();try {foreach ($parentIdsas$parentType => $entityIds) {$this->_getIndexer($parentType)->reindexEntity($entityIds);            }        } catch (Exception $e) {$adapter->rollback();throw$e;        }$adapter->commit();return$this;    }
Шаг 8: Ресурс модели (TYPE Default)public functionsetTypeId($typeId)    {$this->_typeId = $typeId;return $this;    }public function getTypeId()    {if (is_null($this->_typeId)) {            Mage::throwException(Mage::helper('cataloginventory')->__('Undefined product type.'));        }return$this->_typeId;    }public function reindexAll()    {$this->useIdxTable(true);$this->_prepareIndexTable();return$this;    }public function reindexEntity($entityIds)    {$this->_updateIndex($entityIds);return$this;    }
Шаг 9: Декларация индексатора<config><!-- ... --><global><!-- ... --><index>            <indexer><cataloginventory_stock>                    <model>cataloginventory/indexer_stock</model>                </cataloginventory_stock>                <catalog_product_attribute>                    <depends>                        <cataloginventory_stock />                    </depends>                </catalog_product_attribute>                <catalog_product_price>                    <depends>                        <cataloginventory_stock />                    </depends>                </catalog_product_price>            </indexer>        </index>    </global></config>
Индекс цен для B2BЦель     Создать новый тип товара B2BСправка     В2В – сокращение от английских слов «businesstobusiness», в буквальном переводе – бизнес для бизнеса. Это сектор рынка, который работает не на конечного, рядового потребителя, а на такие же компании, то есть на другой бизнес.Задача     Новый тип товара, который наследует поведение простого товара (simple), но имеет возможность указать цену для каждой группы пользователей (customer group)
Индекс цен для B2BЗнакомство с интерфейсом Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Interfacepublic functionreindexAll();public functionreindexEntity($entityIds);public functionregisterEvent(Mage_Index_Model_Event$event);Создаем свой индексаторclass Mageconf_B2b_Model_Mysql4_Indexer_Price   extendsMage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Default{}
Индекс цен для B2BЗнакомство с …Indexer_Price_Defaultpublic functionreindexAll(){$this->useIdxTable(true);$this->_prepareFinalPriceData();$this->_applyCustomOption();$this->_movePriceDataToIndexTable();return$this;}public functionreindexEntity($entityIds){$this->_prepareFinalPriceData($entityIds);$this->_applyCustomOption();$this->_movePriceDataToIndexTable();return$this;}
Индекс цен для B2Bprotected function _getDefaultFinalPriceTable(){if($this->useIdxTable()) {return$this->getTable('catalog/product_price_indexer_final_idx');}return$this->getTable('catalog/product_price_indexer_final_tmp');}
Индекс цен для B2B
Индекс цен для B2Bprotected function _prepareFinalPriceData($entityIds = null){   // удаляем данные из таблицы, если они есть$this->_prepareDefaultFinalPriceTable();$write  = $this->_getWriteAdapter();$select = $write->select()        ->from(array('e' => $this->getTable('catalog/product')), array('entity_id'))        ->joinCross(array('cg' => $this->getTable('customer/customer_group')),array('customer_group_id'))->joinCross(array('cw' => $this->getTable('core/website')),array('website_id'))        ->join(array('cwd' => $this->_getWebsiteDateTable()),'cw.website_id = cwd.website_id',array())        ->join(array('csg' => $this->getTable('core/store_group')),'csg.website_id = cw.website_id AND cw.default_group_id = csg.group_id',array())        ->join(array('cs' => $this->getTable('core/store')),'csg.default_store_id = cs.store_id AND cs.store_id != 0',array());// next slide
Индекс цен для B2B// protected function _prepareFinalPriceData($entityIds = null)    $select       ->join(array('pw' => $this->getTable('catalog/product_website')),'pw.product_id = e.entity_id AND pw.website_id = cw.website_id',array())->joinLeft(array('tp' => $this->_getTierPriceIndexTable()),'tp.entity_id = e.entity_id AND tp.website_id = cw.website_id'. ' AND tp.customer_group_id = cg.customer_group_id',array())       ->join(array('b2d' => $this->getTable('b2b/price')),'b2d.entity_id = e.entity_id AND b2d.customer IS NULL AND website_id=0'array())->join(array('b2w'=> $this->getTable('b2b/price')),'b2w.entity_id = e.entity_id AND b2w.customer = cg.customer_group_id'                . ' AND b2w.website_id = cw.website_id', array())        ->where('e.type_id=?', $this->getTypeId());$statusCond = $write->quoteInto('=?',Mage_Catalog_Model_Product_Status::STATUS_ENABLED);$this->_addAttributeToSelect($select, 'status', 'e.entity_id', 'cs.store_id', $statusCond, true);
Индекс цен для B2B// protected function _prepareFinalPriceData($entityIds = null)$taxClassId = $this->_addAttributeToSelect($select, 'tax_class_id', 'e.entity_id','cs.store_id');$select->columns(array('tax_class_id' => $taxClassId));$finalPrice= newZend_Db_Expr('IFNULL(b2w.price, b2d.price)');    $select->columns(array('orig_price'    => $price,'price'         => $finalPrice,'min_price'     => $finalPrice,'max_price'     => $finalPrice,'tier_price'    => newZend_Db_Expr('NULL'),'base_tier'     => newZend_Db_Expr('NULL'),));if(!is_null($entityIds)) {$select->where('e.entity_id IN(?)', $entityIds);    }
Индекс цен для B2B// protected function _prepareFinalPriceData($entityIds = null)Mage::dispatchEvent('prepare_catalog_product_index_select', array('select'        => $select,'entity_field'  => newZend_Db_Expr('e.entity_id'),'website_field' => newZend_Db_Expr('cw.website_id'),'store_field'   => newZend_Db_Expr('cs.store_id')));$query = $select->insertromSelect($this->_getDefaultFinalPriceTable());$write->query($query);return$this;}public functionregisterEvent(Mage_Index_Model_Event$event){$entity = $event->getEntity();if($entity == Mage_Catalog_Model_Product::ENTITY) {if ($event->getType() == Mage_Index_Model_Event::TYPE_SAVE) {// check attributes           // add data to event         }   }}
Обзор индексаторов в MagentoProduct AttributesProduct PricesCatalog URL RewritesProduct Flat DataCategory Flat DataCategory ProductsCatalog Search IndexStock StatusTag Aggregation Data
Спасибо за вниманиеEmail: victor@magento.com

More Related Content

Индексирование в Magento

  • 1. Индексация в MagentoВиктор ТихончукMagento System Architect
  • 3. СобытиеMage_Index_Model_EventСобытие – то, что происходит в некоторый момент времени и рассматривается как изменение состояния сущности.Событие хранит информацию о сущности, с которой произошло действие и тип действия.Типы изменений сущности (event type)Сохранение (SAVE)Удаление (DELETE)Групповая обработка (MASS_ACTION)
  • 4. ОбработчикMage_Index_Model_IndexerprocessEntityAction($entity, $entityType, $eventType)logEvent($entity, $entityType, $eventType)registerEvent(Mage_Index_Model_Event $event)indexEvent(Mage_Index_Model_Event $event)indexEvents($entity = null, $type = null)
  • 5. Изменения в абстрактной моделиПроцесс сохранения_getResource()->beginTransaction()_beforeSave()_getResource()->save()_afterSave()_getResource()->commit()afterCommitCallback()Новые событияmodel_save_commit_after{eventPrefix}_save_commit_after
  • 6. Изменения в абстрактной моделиПроцесс удаления_getResource()->beginTransaction()_beforeDelete()_getResource()->delete()_afterDelete()_getResource()->commit()_afterDeleteCommit()Новые событияmodel_delete_commit_after{eventPrefix}_delete_commit_after
  • 7. Сущностиcatalog/product (SAVE, DELETE, MASS_ACTION)catalog/category (SAVE, DELETE)catalog/resource_eav_attribute (SAVE, DELETE)customer/group (SAVE)cataloginventory/stock_item (SAVE)tag/tag (SAVE)core/store (SAVE, DELETE)core/store_group (SAVE, DELETE)core/website (SAVE, DELETE)
  • 8. Процессы и индексаторыИндексатор может работать в 2х режимах:в режиме реального времени (MODE_REAL_TIME)в ручном режиме (MODE_MANUAL)У каждого индексатора есть текущий статус:работает (STATUS_RUNNING)режим ожидания (STATUS_PENDING)необходимо перестроить (STATUS_REQUIRE_REINDEX)СобытиеREQUIRE_REINDEXMODE MANUALNew Indexer
  • 10. CatalogInventory Stock StatusЦель оптимизировать затраты на подсчет возможности покупки товара при отображении товаров в каталоге, поиске и т.д.Мотивация для простых (simple) товаров - динамически определить доступность не является трудозатратной операцией, чего не скажешь о составных (composite), для которых нужно учитывать статус всех его составляющихЗадача сделать предварительно подсчитанный статус для каждого товара с учетом склада и веб сайта
  • 11. Шаг 1: Структура данных индекса
  • 12. Шаг 2: Создаем индексаторMage_CatalogInventory_Model_Indexer_Stock
  • 13. Шаг 2: Создаем индексаторMage_Index_Model_Indexer_AbstractMage_CatalogInventory_Model_Indexer_Stock
  • 14. Шаг 2: Создаем индексаторMage_Core_Model_AbstractMage_Index_Model_Indexer_AbstractMage_CatalogInventory_Model_Indexer_Stock
  • 15. Шаг 2: Создаем индексаторMage_Core_Model_Mysql4_AbstractMage_Index_Model_Mysql4_Indexer_AbstractMage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_AbstractMage_CatalogInventory_Model_Mysql4_Indexer_Stock
  • 16. Шаг 2: Создаем индексаторАбстрактные методы индексатораgetName()getDescription()_registerEvent()_processEvent()
  • 17. Шаг 3: Событияprotected$_matchedEntities = array(    Mage_CatalogInventory_Model_Stock_Item::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ),    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    ),    Mage_Core_Model_Store::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ),    Mage_Core_Model_Store_Group::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ),    Mage_Core_Model_Config_Data::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ),    Mage_Catalog_Model_Convert_Adapter_Product::ENTITY => array(        Mage_Index_Model_Event::TYPE_SAVE    ));
  • 18. Шаг 4: Изменение конфигурацииprotected$_relatedConfigSettings = array(    Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK,    Mage_CatalogInventory_Helper_Data::XML_PATH_SHOW_OUT_OF_STOCK);public functionmatchEvent(Mage_Index_Model_Event$event){// check saved result in $event and return it if ($entity == Mage_Core_Model_Config_Data::ENTITY) {$configData= $event->getDataObject();$path = $configData->getPath();if (in_array($path, $this->_relatedConfigSettings)) {$result = $configData->isValueChanged(); } else {$result = false; } } else {$result = parent::matchEvent($event); }// save result in $event and return it}
  • 19. Шаг 5: Регистрация событияprotected function _registerEvent(Mage_Index_Model_Event$event){    switch ($event->getEntity()) {        caseMage_Catalog_Model_Product::ENTITY:            $this->_registerCatalogProductEvent($event);            break;  // skip some cases        caseMage_Core_Model_Store::ENTITY:        caseMage_Core_Model_Config_Data::ENTITY:$reindex = Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX;            $event->addNewData('skip_call_event_handler', true);            $process = $event->getProcess();            $process->changeStatus($reindex);             if ($event->getEntity() == Mage_Core_Model_Config_Data::ENTITY) {                $configData = $event->getDataObject();$indexer = Mage::getSingleton('index/indexer');                if ($configData->getPath() == XML_PATH_SHOW_OUT_OF_STOCK) {                    $index->getProcessByCode('catalog_product_price')                        ->changeStatus($reindex);                    $indexer->getProcessByCode('catalog_product_attribute')                        ->changeStatus($reindex);                }            }            break;    }}
  • 20. Шаг 5: Регистрация событияprotected function _registerCatalogProductDeleteEvent(Mage_Index_Model_Event$event){    /**@var $product Mage_Catalog_Model_Product */    $product = $event->getDataObject();     $parentIds = $this->_getResource()->getProductParentsByChild($product->getId());    if ($parentIds) {        $event->addNewData('reindex_stock_parent_ids', $parentIds);    }     return$this;}
  • 21. Шаг 6: Обработка событияprotected function _processEvent(Mage_Index_Model_Event$event){$data = $event->getNewData();if (!empty($data['cataloginventory_stock_reindex_all'])) {$this->reindexAll(); }if (empty($data['skip_call_event_handler'])) {$this->callEventHandler($event); }}
  • 22. Шаг 7: Ресурс модельResource ModelType Indexer InterfaceType Indexer DefaultType Indexer Configurable
  • 23. Шаг 7: Ресурс модельprotected function _getTypeIndexers() {if (is_null($this->_indexers)) {$this->_indexers = array();$types = Mage::getSingleton('catalog/product_type') ->getTypesByPriority();foreach ($typesas$typeId => $typeInfo) {if (isset($typeInfo['stock_indexer'])) {$modelName = $typeInfo['stock_indexer']; } else {$modelName = $this->_defaultIndexer; }$isComposite = !empty($typeInfo['composite']);$indexer = Mage::getResourceModel($modelName) ->setTypeId($typeId) ->setIsComposite($isComposite);$this->_indexers[$typeId] = $indexer; } }return$this->_indexers; }
  • 24. Шаг 7: Ресурс модельpublic functionreindexAll() {$this->useIdxTable(true);$this->clearTemporaryIndexTable();foreach ($this->_getTypeIndexers() as$indexer) {$indexer->reindexAll(); }$this->syncData();return$this; }
  • 25. Шаг 7: Ресурс модельpublic functioncatalogProductDelete(Mage_Index_Model_Event$event) {$data = $event->getNewData();if (empty($data['reindex_stock_parent_ids'])) {return$this; }$adapter = $this->_getWriteAdapter();$parentIds = array();foreach ($data['reindex_stock_parent_ids'] as$parentId => $parentType) {$parentIds[$parentType][$parentId] = $parentId; }$adapter->beginTransaction();try {foreach ($parentIdsas$parentType => $entityIds) {$this->_getIndexer($parentType)->reindexEntity($entityIds); } } catch (Exception $e) {$adapter->rollback();throw$e; }$adapter->commit();return$this; }
  • 26. Шаг 8: Ресурс модели (TYPE Default)public functionsetTypeId($typeId) {$this->_typeId = $typeId;return $this; }public function getTypeId() {if (is_null($this->_typeId)) { Mage::throwException(Mage::helper('cataloginventory')->__('Undefined product type.')); }return$this->_typeId; }public function reindexAll() {$this->useIdxTable(true);$this->_prepareIndexTable();return$this; }public function reindexEntity($entityIds) {$this->_updateIndex($entityIds);return$this; }
  • 27. Шаг 9: Декларация индексатора<config><!-- ... --><global><!-- ... --><index> <indexer><cataloginventory_stock> <model>cataloginventory/indexer_stock</model> </cataloginventory_stock> <catalog_product_attribute> <depends> <cataloginventory_stock /> </depends> </catalog_product_attribute> <catalog_product_price> <depends> <cataloginventory_stock /> </depends> </catalog_product_price> </indexer> </index> </global></config>
  • 28. Индекс цен для B2BЦель Создать новый тип товара B2BСправка В2В – сокращение от английских слов «businesstobusiness», в буквальном переводе – бизнес для бизнеса. Это сектор рынка, который работает не на конечного, рядового потребителя, а на такие же компании, то есть на другой бизнес.Задача Новый тип товара, который наследует поведение простого товара (simple), но имеет возможность указать цену для каждой группы пользователей (customer group)
  • 29. Индекс цен для B2BЗнакомство с интерфейсом Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Interfacepublic functionreindexAll();public functionreindexEntity($entityIds);public functionregisterEvent(Mage_Index_Model_Event$event);Создаем свой индексаторclass Mageconf_B2b_Model_Mysql4_Indexer_Price extendsMage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Default{}
  • 30. Индекс цен для B2BЗнакомство с …Indexer_Price_Defaultpublic functionreindexAll(){$this->useIdxTable(true);$this->_prepareFinalPriceData();$this->_applyCustomOption();$this->_movePriceDataToIndexTable();return$this;}public functionreindexEntity($entityIds){$this->_prepareFinalPriceData($entityIds);$this->_applyCustomOption();$this->_movePriceDataToIndexTable();return$this;}
  • 31. Индекс цен для B2Bprotected function _getDefaultFinalPriceTable(){if($this->useIdxTable()) {return$this->getTable('catalog/product_price_indexer_final_idx');}return$this->getTable('catalog/product_price_indexer_final_tmp');}
  • 33. Индекс цен для B2Bprotected function _prepareFinalPriceData($entityIds = null){ // удаляем данные из таблицы, если они есть$this->_prepareDefaultFinalPriceTable();$write = $this->_getWriteAdapter();$select = $write->select() ->from(array('e' => $this->getTable('catalog/product')), array('entity_id')) ->joinCross(array('cg' => $this->getTable('customer/customer_group')),array('customer_group_id'))->joinCross(array('cw' => $this->getTable('core/website')),array('website_id')) ->join(array('cwd' => $this->_getWebsiteDateTable()),'cw.website_id = cwd.website_id',array()) ->join(array('csg' => $this->getTable('core/store_group')),'csg.website_id = cw.website_id AND cw.default_group_id = csg.group_id',array()) ->join(array('cs' => $this->getTable('core/store')),'csg.default_store_id = cs.store_id AND cs.store_id != 0',array());// next slide
  • 34. Индекс цен для B2B// protected function _prepareFinalPriceData($entityIds = null) $select ->join(array('pw' => $this->getTable('catalog/product_website')),'pw.product_id = e.entity_id AND pw.website_id = cw.website_id',array())->joinLeft(array('tp' => $this->_getTierPriceIndexTable()),'tp.entity_id = e.entity_id AND tp.website_id = cw.website_id'. ' AND tp.customer_group_id = cg.customer_group_id',array()) ->join(array('b2d' => $this->getTable('b2b/price')),'b2d.entity_id = e.entity_id AND b2d.customer IS NULL AND website_id=0'array())->join(array('b2w'=> $this->getTable('b2b/price')),'b2w.entity_id = e.entity_id AND b2w.customer = cg.customer_group_id' . ' AND b2w.website_id = cw.website_id', array()) ->where('e.type_id=?', $this->getTypeId());$statusCond = $write->quoteInto('=?',Mage_Catalog_Model_Product_Status::STATUS_ENABLED);$this->_addAttributeToSelect($select, 'status', 'e.entity_id', 'cs.store_id', $statusCond, true);
  • 35. Индекс цен для B2B// protected function _prepareFinalPriceData($entityIds = null)$taxClassId = $this->_addAttributeToSelect($select, 'tax_class_id', 'e.entity_id','cs.store_id');$select->columns(array('tax_class_id' => $taxClassId));$finalPrice= newZend_Db_Expr('IFNULL(b2w.price, b2d.price)'); $select->columns(array('orig_price' => $price,'price' => $finalPrice,'min_price' => $finalPrice,'max_price' => $finalPrice,'tier_price' => newZend_Db_Expr('NULL'),'base_tier' => newZend_Db_Expr('NULL'),));if(!is_null($entityIds)) {$select->where('e.entity_id IN(?)', $entityIds); }
  • 36. Индекс цен для B2B// protected function _prepareFinalPriceData($entityIds = null)Mage::dispatchEvent('prepare_catalog_product_index_select', array('select' => $select,'entity_field' => newZend_Db_Expr('e.entity_id'),'website_field' => newZend_Db_Expr('cw.website_id'),'store_field' => newZend_Db_Expr('cs.store_id')));$query = $select->insertromSelect($this->_getDefaultFinalPriceTable());$write->query($query);return$this;}public functionregisterEvent(Mage_Index_Model_Event$event){$entity = $event->getEntity();if($entity == Mage_Catalog_Model_Product::ENTITY) {if ($event->getType() == Mage_Index_Model_Event::TYPE_SAVE) {// check attributes // add data to event } }}
  • 37. Обзор индексаторов в MagentoProduct AttributesProduct PricesCatalog URL RewritesProduct Flat DataCategory Flat DataCategory ProductsCatalog Search IndexStock StatusTag Aggregation Data