以编程方式更新后缺少Magento产品


Missing Magento products after updating programmatically

我在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表中的时间戳。然而,所有索引都显示为"Pending",.lock文件存在于var/locks中,并且没有任何index_event条目报告有关reindex的任何信息。

我在大容量更新脚本中添加了代码,该脚本在更新、执行更新、执行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时设置的时间戳相同的时间戳。

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

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

  Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Mode‌l_App::ADMIN_STORE_ID));