【问题标题】:Magento Collection Catch-22Magento 系列 Catch-22
【发布时间】:2011-06-16 04:09:32
【问题描述】:

我不太了解 Magento 集合的工作原理,所以希望这是一个简单的问题...

正如古老的格言所说,你不能观察一个实验而不以某种方式改变它。这似乎适用于 Magento 集合。我有一个我编写的特色产品 模块,效果很好。我们最近向我们的商店添加了客户评论。查看类别页面时,它会显示对该类别中产品的随机评论。这也很好用。我将评论块添加到我的特色产品页面,这很容易做到,但由于这些产品不属于特定类别,它只是随机抽取一个通常不相关的评论。为了解决这个问题,我在我的 Featured 模块中修改了我的 getProductCollection 函数,并在集合创建/保存后将以下内容添加到末尾:

$_product = $this->_productCollection->getFirstItem();
$_catIDs = $_product->getCategoryIds();

if(count($_catIDs) > 0)
{
    $_cat = Mage::getModel('catalog/category')->load($_catIDs[0]); 
    Mage::register('current_category', $_cat);
}

不幸的是,仅仅查看集合中的第一个项目的行为就会破坏工具栏中的寻呼机。无论我选择哪种分页选项,当上述代码到位时,它总是显示所有项。如果我注释掉该部分,它就可以正常工作。

所以我的问题是:如何在不以某种方式更改集合或破坏分页的情况下获取有关集合中产品的任何信息?

添加我的代码以帮助更多地解释问题:

class VPS_Featured_Block_List extends Amasty_Sorting_Block_Catalog_Product_List//Mage_Catalog_Block_Product_List
{
    protected function _getProductCollection()
    {
        if (is_null($this->_productCollection))
        {
            $_attributeNames = 'featured';
            if($this->getAttributeName() != '')
            $_attributeNames = $this->getAttributeName();

            $_attrArray = explode(',', $_attributeNames);

            $this->_productCollection = Mage::getModel('catalog/product')->getCollection();

            $this->_productCollection->addAttributeToSelect('*');

            $_filters = array();

            foreach($_attrArray as $_attr)
            $_filters[] = array('attribute' => $_attr, 'eq' => true);

            $this->_productCollection->addFieldToFilter($_filters);
            //$this->_productCollection->addFieldToFilter(array(array('attribute' => $_attr, 'eq' => true),));

            Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($this->_productCollection);
            Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($this->_productCollection);
            Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($this->_productCollection);

            //Get category of first product in collection (used for featured review)
            $_catIDs = array();

            $_product = $this->_productCollection->getFirstItem();
            $_catIDs = $_product->getCategoryIds();

            if(count($_catIDs) > 0)
            {
                $_cat = Mage::getModel('catalog/category')->load($_catIDs[0]);
                Mage::register('current_category', $_cat);
            }
        }
        return $this->_productCollection;
    }
}

【问题讨论】:

    标签: magento


    【解决方案1】:

    感谢@clockworkgeek 他在我的followup question 中发布的这个答案:

    原因是当您在集合上调用 getFirstItem()(或几乎任何其他检索方法)时,该集合被加载。任何后续操作都会忽略数据库并仅使用加载的数据,过滤器无效,因为它们仅是 SQL,分页和选定列也是如此。解决方法是在第一个集合的基础上使用第二个集合。

    $secondCollection = clone $firstCollection;
    $secondCollection->clear();
    $_foo123 = $secondCollection->getFirstItem();
    

    clear() 方法卸载该集合的数据,强制它下次再次访问数据库

    【讨论】:

      【解决方案2】:

      如果没有更多上下文(magento 版本,您所在的班级等),很难说发生了什么。但是,我认为(60% 的信心)发生的事情是您正在获得对产品集合的引用 在添加过滤器之前。 Magento 集合延迟加载,这意味着在您显式调用 load 您尝试访问项目之前,不会运行数据库查询。我的猜测(再次猜测)是当您访问上面的项目时,集合会加载(没有过滤器)。然后,系统的其他部分添加过滤器但它们被忽略,因为集合已加载

      如果没有更多上下文,就不可能回答您的更大问题。

      【讨论】:

      • 谢谢@alan-storm。我已经为上面的 list.php 类添加了代码。这就是它的全部内容。在 CMS 页面上,我将这个块添加到 XML 中,并传递给它一个要过滤的属性。我希望这已经足够了,但是如果您需要更多信息,请告诉我。非常感谢你的帮助。需要注意的一件事是它正确地应用了过滤器,而不是分页。如果我有 20 种产品的集合并且我的寻呼机设置为显示 9,那么当获取第一个产品类别的代码块就位时,我将看到所有 20 种产品。如果我把那部分注释掉,我只会看到 9 个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-24
      • 2010-11-04
      • 2016-03-06
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 2023-03-05
      相关资源
      最近更新 更多