这不是问题,而是信息。
数据韭菜发生在平面表行的类别刷新上。
错误重现步骤:
检查平面表,发现该属性已复制到位于包含该属性的类别之后的所有类别。
发生数据泄漏是因为类别加载是在没有重置先前加载的值的情况下完成的。
在文件中: 企业\目录\模型\索引\操作\类别\平面\Refresh.php
搜索_reindex函数(第828行)
您将看到模型正在加载
$category = Mage::getModel('catalog/category');
修复方法是在加载新类别之前在
foreach ($categoriesIdsChunk as $categoryId) {
的每个循环上重置 $category 变量。
简单修复:
foreach ($categoriesIdsChunk as $categoryId) {
if (!isset($attributesData[$categoryId])) {
continue;
}
//add this line to reset the category data.
$category = Mage::getModel('catalog/category');
if ($category->load($categoryId)->getId()) {
$data[] = $this->_prepareValuesToInsert(
array_merge(
$category->getData(),
$attributesData[$categoryId],
array('store_id' => $store->getId())
)
);
}
}
因此,我将详细阐述这个主题,因为它很重要,但原始主题/答案有点不完整(从 Enterprise 1.14.1 开始)。
简单地重写
a/c/c/E/Catalog/Model/Index/Action/Category/Flat/Refresh.php
只是解决方案的一半。 在类别拖放重新排序期间,观察者中会调用以下代码来监视类别保存和移动事件...
public function processCategorySaveEvent(Varien_Event_Observer $observer)
{
if ($this->_isLiveCategoryReindexEnabled()) {
// ...
$client->execute('enterprise_catalog/index_action_category_flat_refresh_row', $arguments);
}
}
public function processCategoryMoveEvent(Varien_Event_Observer $observer)
{
if ($this->_isLiveCategoryReindexEnabled()) {
// ...
$client->execute('enterprise_catalog/index_action_category_flat_refresh_changelog');
}
};
不幸的是,
enterprise_catalog/index_action_category_flat_refresh_row
和enterprise_catalog/index_action_category_flat_refresh_changelog
直接扩展了a/c/c/E/Catalog/Model/Index/Action/Category/Flat/Refresh.php
,因此也需要重写。
最后,最终的修复看起来更像是这样......
a/c/local/Namespace/Modulename/etc/config.xml
<config>
<global>
<models>
<modulename>
<class>Namespace_Modulename_Model</class>
</modulename>
<!-- Enterprise_Catalog_Model_Index_Action_Category_Flat_Refresh_Row -->
<!-- Enterprise_Catalog_Model_Index_Action_Category_Flat_Refresh_Changelog -->
<!-- Enterprise_Catalog_Model_Index_Action_Category_Flat_Refresh -->
<enterprise_catalog>
<rewrite>
<index_action_category_flat_refresh_row>Namespace_Modulename_Model_Catalog_Index_Action_Category_Flat_Refresh_Row</index_action_category_flat_refresh_row>
<index_action_category_flat_refresh_changelog>Namespace_Modulename_Model_Catalog_Index_Action_Category_Flat_Refresh_Changelog</index_action_category_flat_refresh_changelog>
<index_action_category_flat_refresh>Namespace_Modulename_Model_Catalog_Index_Action_Category_Flat_Refresh</index_action_category_flat_refresh>
</rewrite>
</enterprise_catalog>
</models>
</global>
</config>
a/c/local/Namespace/Modulename/Model/Catalog/Index/Action/Category/Flat/Refresh/Row.php
class Namespace_Module_Model_Catalog_Index_Action_Category_Flat_Refresh_Row extends Namespace_Module_Model_Catalog_Index_Action_Category_Flat_Refresh
{
protected $_keyColumnIdValue;
public function __construct(array $args)
{
parent::__construct($args);
if (isset($args['value'])) {
$this->_keyColumnIdValue = $args['value'];
}
}
public function execute()
{
if (!$this->_isFlatIndexerEnabled()) {
return $this;
}
$this->_validate();
$this->_reindex(array($this->_keyColumnIdValue));
return $this;
}
}
a/c/local/Namespace/Modulename/Model/Catalog/Index/Action/Category/Flat/Refresh/Changelog.php
class Namespace_Module_Model_Catalog_Index_Action_Category_Flat_Refresh_CHangelog extends Namespace_Module_Model_Catalog_Index_Action_Category_Flat_Refresh
{
public function execute()
{
if (!$this->_isFlatIndexerEnabled()) {
return $this;
}
$this->_validate();
$changedIds = $this->_selectChangedIds();
if (is_array($changedIds) && count($changedIds) > 0) {
$idsBatches = array_chunk($changedIds, Mage::helper('enterprise_index')->getBatchSize());
foreach ($idsBatches as $changedIds) {
$this->_reindex($changedIds);
}
$this->_setChangelogValid();
}
return $this;
}
}
a/c/local/Namespace/Modulename/Model/Catalog/Index/Action/Category/Flat/Refresh.php
foreach ($categoriesIdsChunk as $categoryId) {
if (!isset($attributesData[$categoryId])) {
continue;
}
// Flat Reindexing Fix
// Flat Reindexing Fix
$category = Mage::getModel('catalog/category');
// Flat Reindexing Fix
// Flat Reindexing Fix
if ($category->load($categoryId)->getId()) {
$data[] = $this->_prepareValuesToInsert(
array_merge(
$category->getData(),
$attributesData[$categoryId],
array('store_id' => $store->getId())
)
);
}
}
我觉得可能有一种更好的方法来实现这一点,这种方法侵入性较小,但确实有效。 更新时请注意此代码,因为可能需要注意它。