m2如何创建自定义的reindex索引
m2如何创建自定义的reindex索引
比如,创建一个reindex,更新无库存的bundle产品id到stock表。
一,在indexer.xml里定义
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nOnamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd"> <indexer id="zou_test_indexer" view_id="zou_test_indexer" class="ZouTestModelIndexerFixBundleProductStock"> <title translate="true">Zou Test Indexer</title> <description translate="true">Fix Bundle Product Stock</description> </indexer> </config>
二,在mview.xml里定义
当产品保存时,监听catalog_product_entity表的数据改动,返回产品id给索引器。我们自定义定义的索引获取该产品id,更新无库存的bundle产品id到stock表。
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nOnamespaceSchemaLocation="urn:magento:framework:Mview/etc/mview.xsd"> <view id="zou_test_indexer" class="ZouTestModelIndexerFixBundleProductStock" group="indexer"> <subscriptions> <table name="catalog_product_entity" entity_column="entity_id" /> </subscriptions> </view> </config>
三,在逻辑代码
<?php namespace ZouTestModelIndexer; use MagentoFrameworkAppObjectManager; use MagentoFrameworkAppResourceConnection; class FixBundleProductStock implements MagentoFrameworkIndexerActionInterface, MagentoFrameworkMviewActionInterface { protected $_connection; public function __construct( ResourceConnection $resource, MagentoCatalogInventoryModelResourceModelIndexerStockFactory $indexerFactory, MagentoCatalogModelProductType $catalogProductType ) { $this->_resource = $resource; $this->_indexerFactory = $indexerFactory; $this->_catalogProductType = $catalogProductType; } protected function _getTable($entityName) { return $this->_resource->getTableName($entityName); } public function executeAllBundleProducts($ids=null){ $connection = $this->_getConnection();// retrieve product types by processIds $select = $connection->select()->from($this->_getTable('catalog_product_entity'), ['entity_id', 'type_id'])->where('type_id = "bundle"'); if($ids){ $select->where('entity_id IN(?)', $ids); } $pairs = $connection->fetchPairs($select); $bundleProductIds = array_keys($pairs); $tableName = $this->_getTable('cataloginventory_stock_status'); $select = $connection->select()->from($tableName, ['product_id'])->where('product_id IN(?)', $bundleProductIds); $stockProducts = $connection->fetchAll($select); foreach ($stockProducts as $row) { if(isset($pairs[$row['product_id']])){ unset($pairs[$row['product_id']]); } } echo "START ... rn"; if($pairs){ $num = 0; $total = count($pairs); foreach ($pairs as $productId => $typeId) { $num ++; echo "{$productId} ({$num}/{$total}) ... "; $bind = ['product_id' => $productId,'website_id' => 0,'stock_id' => 1,'qty' => '10000','stock_status' => 1,]; $connection->insert($tableName, $bind); echo "ok!rn"; } } echo "ALL DONE!rn"; } protected function _getConnection() { if (null === $this->_connection) { $this->_connection = $this->_resource->getConnection(); } return $this->_connection; } /* * Used by mview, allows process indexer in the "Update on schedule" mode */ public function execute($ids){ $this->executeAllBundleProducts($ids); //code here! } /* * Will take all of the data and reindex * Will run when reindex via command line */ public function executeFull(){ $this->executeAllBundleProducts(); //code here! } /* * Works with a set of entity changed (may be massaction) */ public function executeList(array $ids){ $this->executeAllBundleProducts($ids); //code here! } /* * Works in runtime for a single entity using plugins */ public function executeRow($id){ $this->executeAllBundleProducts([$id]); //code here! } }
四,测试
php bin/magento indexer:reindex zou_test_indexer
参考
https://www.mageplaza.com/magento-2-module-development/magento-2-indexing.html