Magento:如何在Observer中合并两个集合?

时间:2012-09-27 19:08:30

标签: magento

我需要重新组织产品列表类别页面。 我的产品中有 date_field 属性需要遵循此排名:

  • 产品 date_field > =今天首先出现
  • 将其与 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'   不止一次

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

2 个答案:

答案 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。