Magento 自定义集合打破了分页

Posted

技术标签:

【中文标题】Magento 自定义集合打破了分页【英文标题】:Magento custom collection breaks pagination 【发布时间】:2012-01-20 06:47:39 【问题描述】:

我通过向 Varien_Data_Collection 集合对象添加项目来创建集合。

$collection = new Varien_Data_Collection();
  foreach($array_of_products as $productId)
    $collection->addItem(Mage::getModel('catalog/product')->load($productId));

但是,当这个对象被传递给 Magento 分页器块时,如下所示,它会破坏我的自定义页面中的分页。

$pager = $this->getLayout()->createBlock('page/html_pager', 'retailerfe.analysis.pager')
            ->setCollection($collection);

P.S 我从来没有遇到过从 模型集合,例如 Mage::getModel('module/modelname')->getCollection()。它只是通过将项目添加到 Varien_Data_Collection 对象而创建的集合。

【问题讨论】:

请发布错误消息的文本,并告诉我们 Magento 的版本。 v1.4 改变了分页的工作方式。 没有错误信息。只是分页变得有点奇怪。寻呼机正确计算页码。它似乎无法对集合应用限制。所有项目都显示在所有页面上。我使用 Magento v 1.5.0.1 每当通过向空的 Varien_Data_Collection 对象添加项目创建的集合进行分页时,似乎都会发生这种行为。 你能解决这个问题吗? 【参考方案1】:

寻呼机正在调用您的集合上的setPageSize,如果您跟踪它,该集合仅由getLastPageNumber 使用。这意味着寻呼机可以准确地显示页数,仅此而已。实际上,Varien_Data_Collection_Db 通过将它们呈现为 SQL 的 LIMIT 子句来对当前页码和大小进行任何操作。

要创建符合页面标准的集合,您必须创建该类的后代。有关想法,请查看 the source of Varien_Data_Collection_Filesystem 以及它如何实现 loadData


我刚刚重新阅读了您的问题并意识到您可以这样做:

$collection = Mage::getModel('catalog/product')->getCollection()
            ->addIdFilter($array_of_products);

这个集合会很开心地翻页。

【讨论】:

谢谢,发条极客。你的解释是正确的。如果我能从中得到一个好的解决方案,我会在这里发布。 我必须创建一个自定义集合并将两个 Magento 集合合并到其中...实际上上述建议效果很好:它修复了分页。我只是实现了一个扩展 Varien_Data_Colletion 的集合,并以 Varien_Data_Collection_Filesystem 中描述的类似方式实现 loadData。 谁能在我们的自定义 Varien_Data_Collection 中发布如何实现“Varien_Data_Collection_Filesystem”loadData 方法的代码?我试图解决这个分页问题几个小时没有成功:(@Francesco sorry right now 它过去了很多时间,不记得了。看看 Varien_Data_Collection_Filesystem 及其 loadData() 方法。 我的建议是查看loadData() 只是为了获得灵感,而不是从字面上实现它,也不要完全重新创建它。看看它如何计算$from$to$isPaginated,然后在调用$this->addItem() 之前检查它们。秘诀是只为您知道当前页面中的项目致电addItem()。如果您对此有更具体的问题,请尝试提出一个新问题。【参考方案2】:

我只是怀疑(可能是我错了):

$collection->addItem(Mage::getModel('catalog/product')->load($productId));

应该是这样的:

$collection->addItem(Mage::getModel('catalog/product')->load($productId)->getData());

让我知道这是否适合您。 谢谢

编辑: 最后我想通了。 以下是你应该怎么做:

<?php
$collection = new Varien_Data_Collection();
foreach($array_of_products as $productId)
    $product = Mage::getModel('catalog/product')->load($productId); 
    $_rowObject = new Varien_Object();
    $_rowObject->setData($product->getData());
    $collection->addItem($_rowObject);

【讨论】:

addItem 需要 Varien_Object,而不是数组。 同意@clockworkgeek。反正我试过了。给我一个错误。在第 390 行的 /var/www/magento/lib/Varien/Data/Collection.php 中的非对象上调用成员函数 getId()。感谢您的回复。 这对我的分页没有帮助。正如@clockworkgeek 所说, Varien_Data_Collection 本身无助于分页。感谢您的回复。【参考方案3】:

提供了解决方案。

class Test_Featuredsalons_Block_Featuredsalons extends Mage_Core_Block_Template


    public function __construct()
    
        parent::__construct();
        $collection = Mage::getModel('featuredsalons/featuredsalons')->getCollection();
        $this->setCollection($collection);
    

    protected function _prepareLayout()
    
        parent::_prepareLayout();

        $pager = $this->getLayout()->createBlock('page/html_pager', 'custom.pager');
        $pager->setCollection($this->getCollection());
        $this->setChild('pager', $pager);
        $this->getCollection()->load();

        return $this;
    

    public function getPagerHtml()
    
        return $this->getChildHtml('pager');
    

    public function getCollection()     
                 
        $limit      =   10;
        $curr_page  =   1;

        if(Mage::app()->getRequest()->getParam('p'))
        
            $curr_page  =   Mage::app()->getRequest()->getParam('p');
        
        //Calculate Offset  
        $offset     =   ($curr_page - 1) * $limit;

        $collection =   Mage::getModel('featuredsalons/featuredsalons')->getCollection()
                                                    ->addFieldToFilter('status',1);     
        $collection->getSelect()->limit($limit,$offset);

        return $collection;
       

谢谢, 卡西夫

【讨论】:

【参考方案4】:

使用以下类来扩展 Varien Data Collection 类:

class Pageable_Varien_Data_Collection extends Varien_Data_Collection

    /**
     * Load data
     *
     * @param   bool $printQuery
     * @param   bool $logQuery
     *
     * @return  Pageable_Varien_Data_Collection
     */
    public function load($printQuery = false, $logQuery = false)
    
        if ($this->isLoaded()) 
            return $this;
        
        $this->_renderLimit();
        $this->_setIsLoaded();
        return $this;
    

    /**
     * @return  Pageable_Varien_Data_Collection
     */
    protected function _renderLimit()
    
        if ($this->_pageSize) 
            $currentPage = $this->getCurPage();
            $pageSize = $this->_pageSize;
            $firstItem = (($currentPage - 1) * $pageSize + 1);
            $lastItem = $firstItem + $pageSize;
            $iterator = 1;
            foreach ($this->getItems() as $key => $item) 
                $pos = $iterator;
                $iterator++;
                if ($pos >= $firstItem && $pos <= $lastItem) 
                    continue;
                
                $this->removeItemByKey($key);
            
        
        return $this;
    

    /**
     * Retrieve collection all items count
     *
     * @return int
     */
    public function getSize()
    
        if (is_null($this->_totalRecords)) 
            $this->_totalRecords = count($this->getItems());
        
        return intval($this->_totalRecords);
    

    /**
     * Retrieve collection items
     *
     * @return array
     */
    public function getItems()
    
        return $this->_items;
    

【讨论】:

以上是关于Magento 自定义集合打破了分页的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.2 分页自定义

php 分页自定义查询

php 分页自定义查询

PHP wordpress分页自定义查询

swift 中心分页自定义布局

页面分页自定义插件