2012-08-15 64 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).")"); 
    } 

没有测试的代码中,例子很简单,但我想你明白的想法;)祝你好运!

相关问题