我通过添加以下内容来覆盖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;
}
}
问题在于,应用此附加排序后,产品集合将不再被分页。
有人知道如何解决此问题吗?
答案 0 :(得分:0)
您没有以正确的方式进行操作,并且没有简单的解决方案。您需要使用数据库进行排序。
_productCollection不是数组,它是具有引用的对象,此时查询仍可以更新,分页将由查询处理到数据库。
如果您进行
Mage::log((string) $this->_productCollection->getSelect());
您将在日志中看到查询
您要做的是加载当前页面的产品,在页面的所有产品上添加距离,并创建一个新集合,在其中您将项目强制放入。因此,集合的数据不是来自数据库,而仅来自数据库包含当前页面的元素。
使用php排序不是一个好主意,因为如果您有很多产品,则意味着您需要从数据库中全部加载它们。那会很慢。
通过修改查询直接在数据库中计算距离。
您可以编辑选择查询并在数据库中进行距离计算
$this->_productCollection
->getSelect()
->columns("main.distance as distance")
现在您可以在产品集合上添加排序
$this->_productCollection->setOrder('distance');
复杂的部分是在mysql中编写与getDistance方法等效的方法。在我的示例中,我假设距离已经在数据库中。
不要犹豫,在各个步骤中打印查询以了解发生了什么。