2012-08-15 67 views
2

我正在爲擁有基於Magento的商店的客戶工作。它充滿了產品,但所述產品的名稱有點混亂。他並不拘泥於一個命名約定,而是多年來使用不同的約定。因此,無論何時使用管理 - >管理產品部分中的名稱過濾器查找某些內容,結果都會很不理想。Magento:管理員 - 產品搜索過濾器

所以我想知道是否有辦法讓過濾算法有點鬆懈,特別是關於詞序。因爲如果您的產品名稱爲'word1 word2 word3',並且您搜索'word1 word3',那麼產品不會顯示在結果中。

任何提示,將不勝感激。乾杯!

8月28日更新:我搜索我帶到類* Mage_Adminhtml_Block_Widget_Grid *,更確切地說,它的保護方法* _addColumnFilterToCollection()*。在這裏你有$ COND變量,如果你要打印出它給你這樣的事情:

陣列([狀] => Zend_Db_Expr對象([_表達:保護] =>「%搜索詞%」))

在這裏,如果我能攔截搜索詞,使之變成‘之前被提交到* Zend_Db_Expr *對象我可能會解決我的問題%的搜索項%%’。那麼,有什麼想法?

+1

我認爲'搜索範圍內'功能會更容易實現 - 所以您可以縮小結果範圍......模糊搜索需要將表格重新格式化爲MyISAM全文,或者甚至使用Solr等工具。 – philwinkle 2012-08-15 21:44:48

回答

1

OK的,下面是這個問題的解決方案。請注意,我沒有太多測試,只是在我的本地測試magento。所以可能會出現問題。

我們的工作班級是Mage_Adminhtml_Block_Widget_Grid,位於'app/code/core/Mage/Adminhtml/Block/Widget/Grid.php'中。你應該在'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 word2 word3'和搜索過濾術語'word1 word3',你會得到正確的結果。我接受建議,這可能不是最好的方法。我將在正確測試之後進行更新。乾杯!

SEP 06 UPDATE:好吧,經過一些現場測試,結果很好,正是我想要的時候。看起來也沒有負面的業績影響。

而有趣的事實是,這個小小的修改適用於在管理界面中您擁有產品網格的每個地方進行過濾(例如,手動創建新訂單並單擊添加產品時或在管理類別 - >無論類別 - >類別產品選項卡)

SEP 06 UPDATE 2:有一個問題。如果您處於訂單網格並嘗試按狀態過濾,則會引發錯誤。我需要使這個過濾器只適用於名稱字段。有任何想法嗎?

SEP 06 UPDATE 3:我將腳本修改爲僅適用於產品網格的名稱字段。現在,通過可見性或按狀態排序的過濾器產品沒有任何衝突。

+0

我有同樣的問題可以提供代碼請 – 2013-05-03 12:05:36

+0

@Eugen Pop:真的很有用:) – 2017-01-27 07:51:19

3

這將需要編寫一個具有一定複雜性的自定義模塊。

,但預期濾波word1 word3至少應該返回匹配的一個子集,即通過過濾並word1 word2 word3返回,是基於錯誤的假設的Magento不執行OR搜索該電網濾波器。

這是不是的情況。在這種情況下,Magento不執行OR,但LIKE搜索。

這也解釋了,爲什麼結果集的

LIKE name = '%word1 word2 word3%' 

通常從未 *能匹配結果集的

LIKE name = '%word1 word3%' 

我認爲Mage_Adminhtml_Block_Catalog_Product_Grid::_prepareCollection()將是需求降到最低限度被你的代碼覆蓋,讓你開始。

祝你好運!


*除了word2 == word3,當然

+0

由於Magento執行LIKE搜索,我想知道是否可以攔截過濾器框中插入的過濾術語,並在提交之前更改它以添加'%'通配符而不是空白。就像在插入框中插入「word1 word3」一樣,它會將其更改爲「word1%word3」。這將產生我想象的更好的結果。 – 2012-08-16 08:16:43

2

您可以將'filter_condition_callback'添加到Magento中的任何網格中。爲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).")"); 
    } 

沒有測試的代碼中,例子很簡單,但我想你明白的想法;)祝你好運!

相關問題