2

商品リストのカテゴリページを再編成する必要があります。このランキングに従う必要がある製品に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'を複数回定義することはできません

フィルタの最初の部分だけが正常に機能します。それを行うためのより良い方法はありますか?

4

2 に答える 2

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。これはデフォルトの並べ替えを上書きする可能性があり、ユーザーの並べ替え後に適用される可能性があります(これについてはテストしていません)。

于 2012-09-27T19:38:56.780 に答える
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を追加し、並べ替えるために2番目の列を追加しました。

もう一度@clockworkgeekに感謝します。

于 2012-09-27T20:58:40.417 に答える