2

私は、Magento ベースのストアを所有するクライアントのために働いています。製品がぎっしり詰まっていますが、その製品の名前は少し乱雑です. 彼は 1 つの命名規則に固執せず、何年にもわたってさまざまな規則を使用していました。そのため、[管理者] -> [製品の管理] セクションで [名前] フィルターを使用して何かを検索するときはいつでも、結果には多くの要望が残されています。

そのため、特に語順に関して、フィルタリングアルゴリズムをもう少し緩くする方法があるかどうか疑問に思っていました. ' word1 word2 word3 ' のような名前の製品があり、' word1 word3 ' を検索すると、その製品は結果に表示されないためです。

ヒントをいただければ幸いです。乾杯!

8 月 28 日更新:私の検索でクラス *Mage_Adminhtml_Block_Widget_Grid*、さらに正確にはその保護されたメソッド *_addColumnFilterToCollection()* にたどり着きました。ここには$cond変数があり、これを印刷すると次のようになります。

Array ([like] => Zend_Db_Expr Object([_expression:protected] => '%search term%' ))

ここで、*Zend_Db_Expr* オブジェクトにサブミットされる前に、その検索語をインターセプトして ' %search%term% ' にすることができれば、おそらく問題は解決するでしょう。それで、何かアイデアはありますか?

4

4 に答える 4

3

それには、ある程度複雑なカスタムモジュールをコーディングする必要があります。

word1 word3のフィルタリングは少なくとも一致のサブセットを返す必要があり、によるフィルタリングは返すという期待は、 Magentoがこのグリッドフィルターの検索をword1 word2 word3実行するという誤った仮定に基づいています。OR

これは当てはまりません。Magentoは実行しませんがORLIKEこの場合は検索します。

それはまた、なぜ結果セットの

LIKE name = '%word1 word2 word3%'

通常、*はの結果セットと一致することはありません

LIKE name = '%word1 word3%'

Mage_Adminhtml_Block_Catalog_Product_Grid::_prepareCollection()始めるために、コードでオーバーライドする必要がある最小限のものになると思います。

幸運を!


*word2 == word3もちろん、

于 2012-08-15T21:42:41.843 に答える
2

Magento の任意のグリッドに「filter_condition_callback」を追加できます。Magento 製品グリッドのリライトを作成し、このパラメーターを「名前」フィールドに追加します。お気に入り

$this->addColumn('name',
            array(
                'header'=> Mage::helper('catalog')->__('Name'),
                'index' => 'name',
                'filter_condition_callback' => array($this, 'filter_name_callback'),
        ));

そして、同じクラスで filter_name_callback メソッドを決定します。このようなもの:

protected function filter_name_callback($collection, $column)
    {
        $names = $column->getFilter()->getValue();
        $namesArray = explode(' ', $names);
        $cond = array();
        foreach ($namesArray as $item)
        {
            $cond[] = 'main_table.name LIKe %'.$item.'%';
        }

        $collection->getSelect()->where("(".implode(' OR ', $cond).")");
    }

コードはテストされていません。例は単純ですが、アイデアは理解できたと思います ;) 頑張ってください!

于 2012-09-06T22:15:44.997 に答える
1

OK、これがこの問題の解決策です。私はこれをあまりテストしていないことに注意してください。私のローカルテストマゼントだけです。そのため、問題が発生する可能性があります。

私たちの作業クラスは、「app / code / core / Mage / Adminhtml / Block / Widget/Grid.php」にあるMage_Adminhtml_Block_Widget_Gridです。コアクラスを上書きしないように、このファイルを「app / code / local / Mage / Adminhtml / Block / Widget/Grid.php」にコピーする必要があります。

次に、そのファイルで_addColumnFilterToCollectionという名前の関数に移動します。ここで、'} else {'ステートメント内のすべてを削除し、次のように置き換えます。

$cond = $column->getFilter()->getCondition();
if ($field == "name" && isset($cond)) {
$filterOrig = $cond['like'];
$filterReplaced = str_replace(" ", "%", $filterOrig);
$newZendDbExpr = new Zend_Db_Expr($filterReplaced);
$modifCond = array('like'=>$newZendDbExpr);
$this->getCollection()->addFieldToFilter($field , $modifCond);
} else if ($field && isset($cond)) {
$this->getCollection()->addFieldToFilter($field , $cond);
}

ここで重要なのは「$cond」変数です。印刷すると、次のようになります。

Array([like] => Zend_Db_Expr Object([_expression:protected] => '%filter term%'));

そのコードスニペットは基本的に、Zend_Db_Exprオブジェクトに渡されたフィルター用語をインターセプトし、それをstr_replace()に渡して、空白を「%」ワイルドカードに置き換えてから、オブジェクトに送り返します。

したがって、「word1 word2word3」のような名前の製品があり、「word1word3」という用語でフィルターを検索すると、適切な結果が得られます。私は提案を受け入れています、これは最善のアプローチではないかもしれません。これを適切にテストした後、更新します。乾杯!

9月6日更新:いくつかのライブテストの後、結果は良好で、まさに私が望んでいたものです。パフォーマンスへの悪影響もないようです。

そして興味深い事実は、この小さな変更が、管理インターフェースに製品グリッドがあるすべての場所でのフィルタリングに適用されることです(たとえば、新しい注文を手動で作成して[製品の追加]をクリックする場合、または[カテゴリの管理]->[カテゴリ]- > [カテゴリ製品]タブ)

9月6日更新2:問題があります。Ordersグリッドを使用していて、ステータスでフィルタリングしようとすると、エラーがスローされます。このフィルターを[名前]フィールドにのみ適用するようにする必要があります。何か案は?

SEP 06 UPDATE 3:製品グリッドの[名前]フィールドにのみ適用されるようにスクリプトを修正しました。これで、可視性によるフィルター製品やステータスなどによる注文との競合は発生しません。

于 2012-09-01T12:52:48.150 に答える