From 069526f1ece34cc7619e7e079e7e5d18fc535581 Mon Sep 17 00:00:00 2001 From: Sven Axelsson Date: Mon, 23 Jan 2017 17:18:31 +0100 Subject: [PATCH 1/3] Added Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract from 1.9.2.4 --- .../Resource/Product/Indexer/Eav/Abstract.php | 287 ++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php diff --git a/app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php b/app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php new file mode 100644 index 0000000..fe8558b --- /dev/null +++ b/app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php @@ -0,0 +1,287 @@ + + */ +abstract class Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract + extends Mage_Catalog_Model_Resource_Product_Indexer_Abstract +{ + /** + * Rebuild all index data + * + * + * @return Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract + */ + public function reindexAll() + { + $this->useIdxTable(true); + $this->beginTransaction(); + try { + $this->clearTemporaryIndexTable(); + $this->_prepareIndex(); + $this->_prepareRelationIndex(); + $this->_removeNotVisibleEntityFromIndex(); + + $this->syncData(); + $this->commit(); + } catch (Exception $e) { + $this->rollBack(); + throw $e; + } + + return $this; + } + + /** + * Rebuild index data by entities + * + * + * @param int|array $processIds + * @return Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract + * @throws Exception + */ + public function reindexEntities($processIds) + { + $adapter = $this->_getWriteAdapter(); + + $this->clearTemporaryIndexTable(); + + if (!is_array($processIds)) { + $processIds = array($processIds); + } + + $parentIds = $this->getRelationsByChild($processIds); + if ($parentIds) { + $processIds = array_unique(array_merge($processIds, $parentIds)); + } + $childIds = $this->getRelationsByParent($processIds); + if ($childIds) { + $processIds = array_unique(array_merge($processIds, $childIds)); + } + + $this->_prepareIndex($processIds); + $this->_prepareRelationIndex($processIds); + $this->_removeNotVisibleEntityFromIndex(); + + $adapter->beginTransaction(); + try { + // remove old index + $where = $adapter->quoteInto('entity_id IN(?)', $processIds); + $adapter->delete($this->getMainTable(), $where); + + // insert new index + $this->useDisableKeys(false); + $this->insertFromTable($this->getIdxTable(), $this->getMainTable()); + $this->useDisableKeys(true); + + $adapter->commit(); + } catch (Exception $e) { + $adapter->rollBack(); + throw $e; + } + + return $this; + } + + /** + * Rebuild index data by attribute id + * If attribute is not indexable remove data by attribute + * + * + * @param int $attributeId + * @param bool $isIndexable + * @return Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract + */ + public function reindexAttribute($attributeId, $isIndexable = true) + { + if (!$isIndexable) { + $this->_removeAttributeIndexData($attributeId); + } else { + $this->clearTemporaryIndexTable(); + + $this->_prepareIndex(null, $attributeId); + $this->_prepareRelationIndex(); + $this->_removeNotVisibleEntityFromIndex(); + + $this->_synchronizeAttributeIndexData($attributeId); + } + + return $this; + } + + /** + * Prepare data index for indexable attributes + * + * @param array $entityIds the entity ids limitation + * @param int $attributeId the attribute id limitation + */ + abstract protected function _prepareIndex($entityIds = null, $attributeId = null); + + /** + * Remove Not Visible products from temporary data index + * + * @return Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract + */ + protected function _removeNotVisibleEntityFromIndex() + { + $write = $this->_getWriteAdapter(); + $idxTable = $this->getIdxTable(); + + $select = $write->select() + ->from($idxTable, null); + + $condition = $write->quoteInto('=?',Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE); + $this->_addAttributeToSelect( + $select, + 'visibility', + $idxTable . '.entity_id', + $idxTable . '.store_id', + $condition + ); + + $query = $select->deleteFromSelect($idxTable); + $write->query($query); + + return $this; + } + + /** + * Prepare data index for product relations + * + * @param array $parentIds the parent entity ids limitation + * @return Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract + */ + protected function _prepareRelationIndex($parentIds = null) + { + $write = $this->_getWriteAdapter(); + $idxTable = $this->getIdxTable(); + + $select = $write->select() + ->from(array('l' => $this->getTable('catalog/product_relation')), 'parent_id') + ->join( + array('cs' => $this->getTable('core/store')), + '', + array()) + ->join( + array('i' => $idxTable), + 'l.child_id = i.entity_id AND cs.store_id = i.store_id', + array('attribute_id', 'store_id', 'value')) + ->group(array( + 'l.parent_id', 'i.attribute_id', 'i.store_id', 'i.value' + )); + if (!is_null($parentIds)) { + $select->where('l.parent_id IN(?)', $parentIds); + } + + /** + * Add additional external limitation + */ + Mage::dispatchEvent('prepare_catalog_product_index_select', array( + 'select' => $select, + 'entity_field' => new Zend_Db_Expr('l.parent_id'), + 'website_field' => new Zend_Db_Expr('cs.website_id'), + 'store_field' => new Zend_Db_Expr('cs.store_id') + )); + + $query = $write->insertFromSelect($select, $idxTable, array(), Varien_Db_Adapter_Interface::INSERT_IGNORE); + $write->query($query); + + return $this; + } + + /** + * Retrieve condition for retrieve indexable attribute select + * the catalog/eav_attribute table must have alias is ca + * + * @return string + */ + protected function _getIndexableAttributesCondition() + { + $conditions = array( + 'ca.is_filterable_in_search > 0', + 'ca.is_visible_in_advanced_search > 0', + 'ca.is_filterable > 0' + ); + + return implode(' OR ', $conditions); + } + + /** + * Remove index data from index by attribute id + * + * @param int $attributeId + * @return Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract + */ + protected function _removeAttributeIndexData($attributeId) + { + $adapter = $this->_getWriteAdapter(); + $adapter->beginTransaction(); + try { + $where = $adapter->quoteInto('attribute_id = ?', $attributeId); + $adapter->delete($this->getMainTable(), $where); + $adapter->commit(); + } catch (Exception $e) { + $adapter->rollback(); + throw $e; + } + + return $this; + } + + /** + * Synchronize temporary index table with index table by attribute id + * + * @param int $attributeId + * @return Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract + * @throws Exception + */ + protected function _synchronizeAttributeIndexData($attributeId) + { + $adapter = $this->_getWriteAdapter(); + $adapter->beginTransaction(); + try { + // remove index by attribute + $where = $adapter->quoteInto('attribute_id = ?', $attributeId); + $adapter->delete($this->getMainTable(), $where); + + // insert new index + $this->insertFromTable($this->getIdxTable(), $this->getMainTable()); + + $adapter->commit(); + } catch (Exception $e) { + $adapter->rollback(); + throw $e; + } + + return $this; + } +} From 0c987b01d9ce41e9f2b70a5dc38bb692298ee981 Mon Sep 17 00:00:00 2001 From: Sven Axelsson Date: Tue, 24 Jan 2017 09:58:37 +0100 Subject: [PATCH 2/3] Improve performance in attribute indexer by casting all product ids to int --- .../Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php b/app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php index fe8558b..9235044 100644 --- a/app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php +++ b/app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php @@ -88,6 +88,7 @@ public function reindexEntities($processIds) $processIds = array_unique(array_merge($processIds, $childIds)); } + $processIds = array_map('intval', $processIds); $this->_prepareIndex($processIds); $this->_prepareRelationIndex($processIds); $this->_removeNotVisibleEntityFromIndex(); From 26c6dc05f2903f48630f374acff57d0b0b08d973 Mon Sep 17 00:00:00 2001 From: Sven Axelsson Date: Tue, 24 Jan 2017 10:01:31 +0100 Subject: [PATCH 3/3] Updated composer file mapping --- composer.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/composer.json b/composer.json index b56e71b..ce4068d 100755 --- a/composer.json +++ b/composer.json @@ -49,6 +49,10 @@ "app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Price.php", "app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Price.php" ], + [ + "app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php", + "app/code/community/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php" + ], [ "app/code/community/Mage/Catalog/Model/Url.php", "app/code/community/Mage/Catalog/Model/Url.php"