Magento产品集合分页与自定义排序



我通过添加来覆盖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;
}
}

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

有人知道怎么解决这个问题吗?

您做这件事的方式不对,也没有简单的解决方案。您需要使用数据库进行排序。

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

如果你做

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

您将在日志中看到查询

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

使用php进行排序是个坏主意,因为如果你有很多产品,这意味着你需要从数据库中全部加载它们。这将是缓慢的。

解决方案

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

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

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

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

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

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

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

最新更新