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
