Magento系列Catch-22 [英] Magento Collection Catch-22

查看:109
本文介绍了Magento系列Catch-22的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I don't really understand how Magento collections work, so hopefully this is a simple question...

随着这句古老谚语的到来,您不能观察一个实验,而无需以某种方式对其进行修改.对于Magento系列来说,这似乎是正确的.我已经编写了一个精选产品模块,该模块运行良好.我们最近将客户评论添加到了我们的商店.查看类别页面时,它会随机显示该类别中的产品.这也很好.我将评论栏添加到了特色产品"页面,这很容易做到,但是由于这些产品不在特定类别中,因此它会随机抽取一个通常不相关的评论.为了解决这个问题,我在我的 Featured 模块中修改了我的 getProductCollection 函数,并在创建/保存收藏集后在末尾添加了以下内容:

As the old adage goes, you can't observe an experiment without somehow altering it. This seems to hold true for Magento collections. I have a Featured Products module that I've written that works quite well. We have recently added Customer Reviews to our store. When viewing a category page it shows a random review of products in that category. This also works great. I added the review block to my Featured Products page, which was easy to do, but since those products aren't in a specific category, it just pulls a random, usually unrelated, review. To fix this, I modified my getProductCollection function in my Featured module and added the following to the end, after the collection has been created/saved:

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

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

不幸的是,仅仅在集合中的第一项的行为就破坏了工具栏中的寻呼机.无论选择哪种分页选项,在使用上述代码时,它始终显示所有项.如果我将该部分注释掉,则效果很好.

Unfortunately, the mere act of looking at the first item in the collection breaks the pager in the toolbar. No matter which of the paging options I choose, it always shows all items when the above code is in place. If I comment out that section it works fine.

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

添加我的代码以帮助进一步解释该问题:

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;
    }
}

推荐答案

感谢@clockworkgeek将此答案发布在我的

Thanks to @clockworkgeek for this answer he posted in my followup question:

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

The reason is because when you call getFirstItem() (or just about any other retrieval method) on a collection that collection is loaded. Any subsequent operation ignores the database and uses only the loaded data, filters have no effect because they are SQL only, ditto for pagination and selected columns. The workaround is to use a second collection based on the first.

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

clear()方法卸载该集合的数据,迫使其下次再次访问数据库

The clear() method unloads the data for that collection, forcing it to access the database again next time

这篇关于Magento系列Catch-22的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆