2

我在 Magento 中以编程方式批量更新产品时遇到了一个奇怪的问题。

我有一个脚本,它获取类别模型,然后是制造商过滤的该类别中产品的产品集合(因此我正在更新给定类别中制造商的所有产品)。然后我遍历产品并更新属性(尺寸表),并保存产品。

这是执行此操作的函数:

<?php

function updateManufacturerSizingTable($store, $categoryId, $manufacturerId, $tableHtml) {
        $categoryObject = Mage::getModel('catalog/category')->load($categoryId);

        $collection = Mage::getResourceModel('catalog/product_collection')
                                        ->addCategoryFilter($categoryObject)
                                        ->addAttributeToSelect('*')
                                        ->addAttributeToFilter('manufacturer', $manufacturerId)
                                        ->setStore($store)
                                        ->addStoreFilter($store)
                                        ->setOrder('name')
                                        ->load();

        foreach ($collection as $product) {
                $data = $product->getData();
                echo '--> Updating ' . $data['name']. PHP_EOL;
                $product->setData('sizing', $tableHtml);
                $product->save();
        }
}

?>

它工作正常,但它对前端的 Magento 类别(更新脚本中涉及的类别)产生了奇怪的副作用。看似随意地,产品将从它们所属的某些(不是全部)类别中消失。例如,产品将属于类别 A 和类别 B,其中 B 是 A 的子级,并且在大规模更新尺寸属性后将出现在 A 而不是 B。

我认为这是与索引有关的问题。我试过用

php path/to/mage/shell/indexer.php reindexall

它似乎执行得很好,并更新了 index_process 表中的时间戳。但是,所有索引都显示为“待处理”,并且 .lock 文件存在于 var/locks 中,并且 index_event 没有任何条目报告有关重新索引的任何内容。

我已将代码添加到批量更新脚本中,该脚本在更新、执行更新、执行 reindexAll 并将索引恢复为实时之前将索引变为手动。它有效(如,未报告错误),但前端的类别列表仍然损坏/奇怪。

<?php

/* Set indexing to manual for the updating */
echo '== Disabling indexing before the import ==' . PHP_EOL;
$processes = Mage::getSingleton('index/indexer')->getProcessesCollection();
$processes->walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL));
$processes->walk('save');

echo '== Beginning update ==' . PHP_EOL;

/* In a loop call the updateManufacturerSizingTable function */

echo '== Reindexing and re-enabling indexing  ==' . PHP_EOL;
/* Set indexing back to on-save and reindex */
$processes->walk('reindexAll');
$processes->walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME));
$processes->walk('save');

?>

就在我写完这篇文章并刷新了一个之前没有产品展示的类别页面(由于这个问题),产品已经返回。index_event 中没有新条目,并且 index_process 仍然报告运行命令行 reindexall 时设置的相同时间戳。

是否有可能重新索引实际上并未在 reindexall 进程中运行,并且它可能正在其他地方执行?这也许可以解释为什么它在脚本运行后逐渐恢复损坏的类别(相当长一段时间后,我们谈论了将近一个小时),但 Magento 没有报告索引正在处理的任何地方?

4

1 回答 1

1

更新产品时需要将store id设置为Admin,尝试添加

  Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Mode‌l_App::ADMIN_STORE_ID));
于 2013-07-10T02:22:44.287 回答