Magento:如何在观察者内部合并两个集合?

Magento:如何在观察者内部合并两个集合?,magento,Magento,我需要重新组织产品列表类别页面。 我的产品中有一个日期字段属性,需要遵循以下排名: 日期字段>=今天的产品首先出现 将其合并到日期字段AddExpressionAttributeToSelectt()! 我在排序方面遇到了一些问题,因为在观察者之前还有其他字段被排序。所以我重新安置了他们 我的代码: $observer->getEvent()->getCollection() ->addExpressionAttributeToSelect( 'fut

我需要重新组织产品列表类别页面。 我的产品中有一个日期字段属性,需要遵循以下排名:

  • 日期字段>=今天的产品首先出现
  • 将其合并到日期字段<今天的产品
因此,我使用以下代码为catalog\u block\u product\u list\u collection dispatcher创建了一个观察者:

$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上再次应用相同的筛选器时,会引发以下错误:

您不能再定义相关名称“\u table\u data\u inicio\u default” 不止一次

只有过滤器的第一部分工作正常。
有更好的方法吗?

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
,用于比较日期,然后首先与今天或更大的行进行排序。它不是按
数据\u inicio
排序。它可能会覆盖任何默认排序,并且-我没有测试过-可能会在用户排序后应用。

技巧在于->AddExpressionAttributeToSelectt()! 我在排序方面遇到了一些问题,因为在观察者之前还有其他字段被排序。所以我重新安置了他们

我的代码:

$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-inside,并添加了第二列进行排序


再次感谢@clockworkgeek。

嗨@clockworkgeek。这是一个非常好的解决方案。我只是不能通过添加->addAttributeToSort来更改默认顺序,对吗?如何更改观察者中的默认顺序?如果您使用
->addAttributeToSort
设置默认顺序,则它将被修复,用户将无法使用前端的“排序依据”下拉列表更改。事实上,我们的自定义模板不允许用户选择排序顺序。我在->getSelect()上看到正在应用排序,但是在
cat索引位置
产品id
之后如下:按
cat索引位置
asc排序,
cat索引
产品idasc,如果(如果(\u table\u data\u inicio.value\u id>0,\u table\u data\u inicio.value,\u table\u data\u inicio.value)>=“2012-09-27”,1,0)descI明白了!@clockworkgeek我以前需要使用getSelect()->reset('order')。=]非常感谢。我只知道在其他子句之前插入order的一种方法,它并不漂亮,我已经更新了我的答案来显示,但由于您现在可以使用它,所以可能不需要它。