在Config.xml中重写Magento Block类 - 第二次猜测我的方法论

时间:2014-01-31 18:24:30

标签: php magento collections rewrite

所以我写了一个非常好用的模块。但是,我正在努力确保尽可能无冲突地编写所有模块。简短:我的模块在父产品页面和列表上显示分组和可配置产品的关联产品的评论。

在catalog / product / list.phtml中有3行代码,如果父产品没有评论,即使子产品有评论,它也不会满足这个条件以显示摘要html。

<?php if($_product->getRatingSummary()): ?>
<?php echo $this->getReviewsSummaryHtml($_product) ?>
<?php endif; ?>

因此,我的目标是在数据到达模板文件之前将数据添加到此集合中的每个元素。

$_productCollection=$this->getLoadedProductCollection();

所以,我重写了Mage_Catalog_Block_Product_List并重写了下面的方法。

protected function _getProductCollection()

实际上,我复制了确切的方法并将我的简单代码添加到它的底部,它确实完全按照我的意愿去做。

protected function _getProductCollection()
{
  if (is_null($this->_productCollection)) {
      $layer = $this->getLayer();
      /* @var $layer Mage_Catalog_Model_Layer */
      if ($this->getShowRootCategory()) {
          $this->setCategoryId(Mage::app()->getStore()->getRootCategoryId());
      }

      // if this is a product view page
      if (Mage::registry('product')) {
          // get collection of categories this product is associated with
          $categories = Mage::registry('product')->getCategoryCollection()
              ->setPage(1, 1)
              ->load();
          // if the product is associated with any category
          if ($categories->count()) {
              // show products from this category
              $this->setCategoryId(current($categories->getIterator()));
          }
      }

      $origCategory = null;
      if ($this->getCategoryId()) {
          $category = Mage::getModel('catalog/category')->load($this->getCategoryId());
          if ($category->getId()) {
              $origCategory = $layer->getCurrentCategory();
              $layer->setCurrentCategory($category);
              $this->addModelTags($category);
          }
      }
      $this->_productCollection = $layer->getProductCollection();

      $this->prepareSortableFieldsByCategory($layer->getCurrentCategory());

      if ($origCategory) {
          $layer->setCurrentCategory($origCategory);
      }
  }

  foreach($this->_productCollection as $product){
    if(($product->getTypeId() == 'configurable' || $product->getTypeId() == 'grouped') 
    && !$product->getRatingSummary()) {
        $product->setRatingSummary(1);
    }
  }

  return $this->_productCollection;
}

我无法帮助,但第二个猜测是,我真的需要重写此函数只是为了将数据添加到它返回的集合中,或者是否有一种方法可以在数据到达模板文件之前简单地将我的数据添加到集合中像我上面所做的那样进行实际重写。类别产品列表是Magento网站上的主要数据集之一,我并不是因为添加一小段数据而搞乱它。此外,我担心与未来扩展的冲突。

如果可能,请告诉我如何在不重写的情况下更改收藏对象。

谢谢。

1 个答案:

答案 0 :(得分:2)

如果您要进行重写,我建议使用这样的方法。

protected function _getProductCollection()
{
    $collection = parent::_getProductCollection();
    //do your stuff to the collection here
    return $collection;
}

您的块类扩展了现有的块类。这意味着您可以调用parent方法并运行相同的代码。当您像在示例中一样复制和粘贴代码时,您的扩展可能会在此代码已更改的Magento的过去/未来版本中无效。

我使用重写的一般经验法则是:如果您保持对代码的控制并且可以调试潜在的冲突,那么重写就可以了。如果您不能控制代码,则不应重写方法。

如果你想避免重写,你的另一个选择是Magento的事件系统。 Magento中的每个集合在加载之前和之后都会触发一个事件。诀窍是找到您所追踪的事件的名称,这需要挖掘Mage::dispatch的来源,或使用工具like Commerce Bug(警告:自我链接)来追踪您的事件'之后。

我更喜欢第二种方法,因此使用Commerce Bug的观察者选项卡(显示在页面上设置的任何现有Magento观察者),我们可以看到Magento本身具有产品集合的监听器设置。具体而言,适用于catalog_product_collection_load_after事件。

enter image description here

如果你看一下Magento cataloginventory/observer的来源,你甚至可以看到Magento在加载后如何修改它?

#File: app/code/core/Mage/CatalogInventory/Model/Observer.php
public function addStockStatusToCollection($observer)
{
    $productCollection = $observer->getEvent()->getCollection();
    if ($productCollection->hasFlag('require_stock_items')) {
        Mage::getModel('cataloginventory/stock')->addItemsToProducts($productCollection);
    } else {
        Mage::getModel('cataloginventory/stock_status')->addStockStatusToProducts($productCollection);
    }
    return $this;
}

如果是您的情况,请检查系统状态,而不是检查产品系列上的require_stock_items标记,并说明它正在加载您希望添加信息的页面。

这应该足以让你开始使用自己的听众。祝你好运!