Magento对未定义对象的count()分层导航调用

时间:2015-03-28 10:51:24

标签: magento magento-1.9

我在分层导航块中遇到了一个问题,我认为这可能是个错误。

在块Mage_Catalog_Block_Navigation中,方法_renderCategoryMenuItemHtml:

    // get all children
    // If Flat Data enabled then use it but only on frontend
    $flatHelper = Mage::helper('catalog/category_flat');
    if ($flatHelper->isAvailable() && $flatHelper->isBuilt(true) && !Mage::app()->getStore()->isAdmin()) {
        $children = (array)$category->getChildrenNodes();
        $childrenCount = count($children);
    } else {
        $children = $category->getChildren();
        $childrenCount = $children->count();
    }

我启用了平面类别索引,并且在计划(每分钟)时重建索引。 Magento版本是1.14.0.1,有时我收到一条错误消息:

Call to a member function count() on a non-object

基于if子句,我假设当有人在重建索引时访问页面时会发生这种情况(isAvailable)。

问题是,else块中的代码似乎在理论上似乎不起作用,因为$ category-> getChildren()返回一个字符串。我在这里错过了什么吗?这是一个错误还是我有一些错误的配置somwhere。

2 个答案:

答案 0 :(得分:0)

这可能是您可以通过启用缓存(所有cms / catalog / category / 404页面是企业版中缓存的完整页面)以及在重建索引完成后具有预定缓存刷新来避免的。考虑增加重新索引之间的间隔。

如果使用内置设置进行调整并不起作用,您可以随时调试:

  

创建日志文件并使其可写

touch mage-root/var/log/counts.log
chmod 755 mage-root/var/log/counts.log
  

用以下内容替换子呼叫:

// get all children
// If Flat Data enabled then use it but only on frontend
$flatHelper = Mage::helper('catalog/category_flat');
Mage::log( 'Flat data enabled: '  . $flatHelper, null, 'counts.log', FALSE );
if ($flatHelper->isAvailable() && $flatHelper->isBuilt(true) && !Mage::app()->getStore()->isAdmin()) {
    $children = (array)$category->getChildrenNodes();
    Mage::log( 'Children in if: '  . $children, null, 'counts.log', FALSE );
    $childrenCount = count($children);
} else {
    $children = $category->getChildren();
    Mage::log( 'Children in else: '  . $children, null, 'counts.log', FALSE );
    $childrenCount = $children->count();
}

最后,你可以通过将vanilla类复制到:

来覆盖它
  

应用\代码\本地\法师\目录\块\ Navigation.php

然后在违规声明上方添加if( !empty( $children ) )并使用此补丁'长期。

答案 1 :(得分:0)

进一步研究之后,它看起来像是一个bug。问题是竞争条件:

  • Mage_Catalog_Model_Category :: _ construct 决定使用什么,EAV或Flat资源
  • 然后Mage_Catalog_Helper_Category :: getStoreCategories 会根据它返回不同的集合。
  • Mage_Catalog_Block_Navigation :: _ renderCategoryMenuItemHtml 中, $ category 对象基于先前的决定 Mage_Catalog_Model_Category Varien_Data_Tree_Node 使用Flat或EAV。
  • Mage_Catalog_Block_Navigation :: _ renderCategoryMenuItemHtml 再次检查是将对象视为Flat还是EAV,并根据此调用不同的方法。

因此,如果使用Flat资源初始化类别,并且类别索引进程在最后一个方法之后但在最后一个方法之前被锁定,Magento将处理 $ category 作为错误的对象类型。

我的解决方案是另外检查else部分中的 $ category 类型。

} else {
        if( $category instanceof Varien_Data_Tree_Node )
        {
            $children = $category->getChildren();
        } else
        {
            $children = $category->getChildrenCategories();
        }
    }

我有点害怕是一个问题,因为我在锁定时访问类别索引。