magento限制产品集合调用中返回的项目数

时间:2010-05-18 01:44:28

标签: php collections magento pagination

我试图在list.phtml模板的副本中手动限制返回结果的数量,但它的结果比我预期的要难得多。

我已经尝试过手动设置集合大小,但是你再一次没有工作。有人能告诉我怎么做吗?非常感谢!

6 个答案:

答案 0 :(得分:21)

快速的方法是使用此方法I recently discovered。您甚至可以直接在模板中使用它。

$_productCollection = clone $this->getLoadedProductCollection();
$_productCollection->clear()
                   ->setPageSize(3)
                   ->load();

答案 1 :(得分:7)

@joseph的类似方法是覆盖Mage_Catalog_Block_Product_List,但在新类中插入以下代码:

const PAGE_SIZE = 3;

protected function _getProductCollection(){
    $collection = parent::_getProductCollection();
    $yourCustomBoolean = someFunctionThatDetectsYourCustomPage();
    if($yourCustomBoolean) {
        $collection->setPageSize(self::PAGE_SIZE);
    }
    return $collection;
}

通过这种方式,您将从父块继承Mage_Catalog代码中的任何未来更改,但仍设置页面限制。

理想情况下,您可以使用system.xml节点创建一个可由管理员编辑的字段,而无需对page_size进行硬编码。 xml看起来像:

<config>
<sections>
    <catalog>
        <groups>
            <frontend>
                <fields>
                    <custom_page_size translate="label">
                        <label>Page Size for Custom Page Type</label>
                        <frontend_type>text</frontend_type>
                        <sort_order>9999</sort_order>
                        <show_in_default>1</show_in_default>
                        <show_in_website>1</show_in_website>
                        <show_in_store>1</show_in_store>
                    </custom_page_size>
                </fields>
            </frontend>
        </groups>
    </catalog>
</sections>
</config>

然后使用以下代码检索代码中的值:

$page_size = Mage::getStoreConfig('catalog/frontend/custom_page_size');

HTH,
JD

答案 2 :(得分:5)

遗憾的是它不起作用,因为在_getProductCollection()方法中,Collection已经使用页面大小进行了初始化。

更灵活的解决方案可能是观察catalog_product_collection_load_before事件,顾名思义,该事件在加载集合之前就会被调度。

下面是一个示例(假设在yourmodule下写下yourpackage扩展名):

步骤1:在config.xml中定义观察者

global扩展名文件的config.xml部分插入如下内容:

<events>
  <catalog_product_collection_load_before>
    <observers>
      <yourpackage_yourmodule_catalog_observer>
        <type>singleton</type>
        <class>yourpackage_yourmodule/catalog_observer</class>
        <method>limitPageSize</method>
      </yourpackage_yourmodule_catalog_observer>
    </observers>
  </catalog_product_collection_load_before>
</events>    

第2步:在Model\Catalog文件夹下定义Observer类:

<?php
class Yourpackage_Yourmodule_Model_Catalog_Observer
{
  public function limitPageSize($observer)
  {
    #TODO: Insert the logic you need to differentiate when to apply the following
    $event = $observer->getEvent();
    $collection = $event->getCollection();
    $collection->setPageSize(3);
    return $this;
  }
}

希望它有所帮助。 此致 Alessandro Ronchi

答案 3 :(得分:3)

我收到了用户代码:clockworkgeek,但这里有一些问题,正确的代码如下,它工作并感谢clockworkgeek。

$_productCollection = $this->getLoadedProductCollection();
$_productCollection->clear();
$_productCollection->setPageSize(3)
$_productCollection->load();

您还可以通过修改为

来编写enter code here或解决此问题
$this->getLoadedProductCollection()->clear();
$_productCollection = $this->getLoadedProductCollection();

谢谢, 如果它对你有所帮助那么评论。

答案 4 :(得分:2)

看起来list.phtml中返回的集合已经调用了load(),这意味着当我们到达模板时,我们失去了设置页面大小的机会。所以,这会变得有点混乱!

生成该集合的块是Mage_Catalog_Block_Product_List,我们可以使用我们自己的类扩展并同时覆盖它。创建一个扩展Mage_Catalog_Block_Product_List的新块并覆盖方法_getProductCollection,如下所示:

/**
 * Retrieve loaded category collection
 *
 * @return Mage_Eav_Model_Entity_Collection_Abstract
 */
protected function _getProductCollection()
{
    if (is_null($this->_productCollection)) {
        $layer = Mage::getSingleton('catalog/layer');
        /* @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->_productCollection = $layer->getProductCollection();

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

        // OUR CODE MODIFICATION ////////////////////
        $yourCustomPage = someFunctionThatDetectsYourCustomPage();
        if($yourCustomPage) {
            $this->_productCollection->setPageSize(1);
            $this->_productCollection->setCurPage(3);
            $this->_productCollection->load();
        }
        /////////////////////////////////////////////

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

重要的是找到一些方法来检测你是否使用自定义list.phtml页面。然后你需要在你的班级覆盖布局中对<block type='catalog/product_list' />的引用,你应该设置为go。

希望有所帮助!

谢谢, 乔

答案 5 :(得分:0)

如前所述,productCollection已设置页面大小。还有另一种获得收藏的方法;通过catalog/product模型:

$productCollection = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect(
        array('name', 'image', 'price')
    )
    ->addIdFilter( 
        array('1', '2')
    )
    ->setPageSize( 2 )
    ->load();
;

return $productCollection->getSelect()->__toString();

生成的查询(最终 object )包含LIMIT语法:

SELECT `e`.* ... WHERE (`e`.`entity_id` IN('1', '2')) LIMIT 2;

这就是你问的问题吗?