我需要重新组织产品列表类别页面。 我的产品中有 date_field 属性需要遵循此排名:
因此,我使用以下代码为 catalog_block_product_list_collection 调度程序创建了一个观察者:
$original_collection = clone $observer->getEvent()->getCollection();
$observer->getEvent()->getCollection()
->addAttributeToFilter('data_inicio', array('gteq' => date('Y-m-d')));
$collection2 = $original_collection
->addAttributeToFilter('data_inicio', array('lt' => date('Y-m-d')));
//and after I will merge both collections by adding each item from $collection2 into $observer
但是当在 $ collection2 上再次应用相同的过滤器时,会引发以下错误:
您无法更多地定义相关名称'_table_data_inicio_default' 不止一次
只有过滤器的第一部分可以正常工作。 有没有更好的方法呢?
答案 0 :(得分:3)
PHP克隆的问题是它不是深克隆,因此一些资源是共享的,因此您看到的名称冲突。我发现最佳做法是在SQL中尽可能多地完成工作,然后很少出现这些小问题。
$collection = $observer->getEvent()->getCollection();
// store old ordering
$orderBys = $collection->getSelect()->getPart(Zend_Db_Select::ORDER)
$collection->getSelect()->reset(Zend_Db_Select::ORDER);
// set first order part
$collection->addExpressionAttributeToSelect(
'future',
'IF({{data_inicio}}>="' . date('Y-m-d') . '",1,0)',
'data_inicio')
->addAttributeToSort('future', 'desc');
// reinstate old ordering afterwards
foreach ($orderBys as $orderBy) {
$collection->getSelect()
->order(is_array($orderBy) ? implode(' ', $orderBy) : $orderBy);
}
此处,创建表达式future
以比较日期,然后首先使用今天或更大的行进行排序。它不按data_inicio
排序。它可能会覆盖任何默认排序 - 我没有测试过 - 可能会在用户排序后应用。
答案 1 :(得分:0)
- > addExpressionAttributeToSelect()就是诀窍! 我在排序方面遇到了一些问题,因为在观察者之前还有其他字段被排序。所以我重新设置了它们......
我的代码:
$observer->getEvent()->getCollection()
->addExpressionAttributeToSelect(
'future',
'IF({{data_inicio}}="' . date('Y-m-d') . '",2, IF({{data_inicio}}>="' . date('Y-m-d') . '",1,0))',
'data_inicio')
->getSelect()->reset('order')->order(array('future desc', 'data_inicio asc'));
我还在里面添加了另一个IF,并添加了第二列进行排序。
再次感谢@clockworkgeek。