【问题标题】:Magento product collection pagination with custom sort具有自定义排序的 Magento 产品集合分页
【发布时间】:2018-11-12 06:46:50
【问题描述】:

我通过添加以下内容来覆盖 Mage_Catalog_Block_Product_List 的 _getProductCollection

foreach ($this->_productCollection as $product) {
     $product->setDistance(Mage::helper('myhelper')->getDistance($product));
}

现在我想按距离对集合进行排序,我尝试了以下方法:

 $this->_productCollection = Mage::helper('myhelper')->sortProductByDist($this->_productCollection);

排序的助手如下(从SO偷来的):

public function sortProductByDist($products) {

      $sortedCollection = Mage::getSingleton('catalog/layer')
         ->getProductCollection()->addFieldToFilter('entity_id', 0);

      $sortedCollection = $sortedCollection->clear();
      $collectionItems = $products->getItems();
      usort($collectionItems, array($this,'_sortItems'));

      foreach ($collectionItems as $item) {
          $sortedCollection->addItem($item);              
      }
      return $sortedCollection;
}

protected function _sortItems($a, $b) {
        $order = 'asc';
        $al = strtolower($a->getDistance());
        $bl = strtolower($b->getDistance());

        if ($al == $bl) {
            return 0;
        }

        if ($order == 'asc') {
            return ($al < $bl) ? -1 : 1;
        } else {
            return ($al > $bl) ? -1 : 1;
        }
}

问题是应用此附加排序时产品集合不再分页。

有人知道如何解决这个问题吗?

【问题讨论】:

    标签: php sorting magento collections


    【解决方案1】:

    你的方法不对,也没有简单的解决方案。您需要使用数据库进行排序。

    _productCollection 不是数组,它是一个有引用的对象,此时的查询仍然可以更新,分页将由对数据库的查询处理。

    如果你做一个

    Mage::log((string) $this->_productCollection->getSelect()); 
    

    您将在日志中看到查询

    您所做的是加载当前页面的产品,在页面的所有产品上添加距离,并创建一个新集合,将您的项目强制放入其中。因此该集合的数据不是来自数据库,而只是包含当前页面的元素。

    使用 php 排序是个坏主意,因为如果您有很多产品,这意味着您需要从数据库中加载它们。那会很慢。

    解决方案

    通过修改查询直接在数据库中计算距离。

    您可以编辑选择查询并在数据库中进行距离计算

    $this->_productCollection
        ->getSelect()
            ->columns("main.distance as distance")
    

    现在您可以在产品集合上添加排序

    $this->_productCollection->setOrder('distance');
    

    复杂的部分将是在 mysql 中编写与您的 getDistance 方法等效的部分。在我的示例中,我假设距离已经在数据库中。

    不要犹豫,在各个步骤打印查询以了解发生了什么。

    【讨论】:

    • 感谢您的回答。是的,我知道 setOrder 方法仅适用于数据库查询。不幸的是,getDistance 方法太复杂了,无法用 sql 编写(或者我应该进一步挖掘)
    猜你喜欢
    • 1970-01-01
    • 2011-08-09
    • 2016-11-13
    • 1970-01-01
    • 2011-08-08
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多