【问题标题】:Magento: admin - product search filterMagento:管理员 - 产品搜索过滤器
【发布时间】:2012-08-15 13:03:06
【问题描述】:

我正在为拥有基于 Magento 的商店的客户工作。它塞满了产品,但所说产品的名称有点乱。他没有坚持一种命名约定,而是多年来使用不同的约定。因此,每当他使用“管理”->“管理产品”部分中的“名称”过滤器查找某些内容时,结果仍有很多不足之处。

所以我想知道是否有办法让过滤算法更加宽松,特别是在词序方面。因为如果您有一个名称为“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%',我可能会解决我的问题。那么,有什么想法吗?

【问题讨论】:

  • 我认为“内部搜索”功能会更容易实现 - 因此您可以缩小结果范围...模糊搜索需要将表格重新格式化为 MyISAM 全文,甚至使用 Solr 之类的工具。跨度>

标签: magento admin filtering


【解决方案1】:

这需要编写一个具有一定复杂性的自定义模块。

对于word1 word3 的过滤应该至少返回匹配的子集,word1 word2 word3 的过滤确实返回,这是基于 Magento 确实执行 OR 搜索此网格过滤器的错误假设。

不是的情况。 Magento 不执行OR,但在这种情况下LIKE 搜索。

这也解释了,为什么 a 的结果集

LIKE name = '%word1 word2 word3%'

通常从不*可以匹配a的结果集

LIKE name = '%word1 word3%'

我认为Mage_Adminhtml_Block_Catalog_Product_Grid::_prepareCollection() 将是您的代码需要覆盖的最小值,以帮助您入门。

祝你好运!


* 除了word2 == word3,当然

【讨论】:

  • 由于 Magento 执行 LIKE 搜索,我想知道是否可以拦截插入过滤器框中的过滤词并在提交之前更改它以添加 '%' 通配符而不是空格。就像您在过滤器框中插入“word1 word3”一样,它会将其更改为“word1 % word3”。我想这会产生更好的结果。
【解决方案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).")");
    }

代码没有经过测试,例子很简单,但我想你理解了这个想法;)祝你好运!

【讨论】:

    【解决方案3】:

    好的,这是解决此问题的方法。请注意,我没有对此进行太多测试,只是在我的本地测试 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%'));
    

    该代码 sn-p 基本上拦截了传递给 Zend_Db_Expr 对象的过滤器项,将其传递给 str_replace() 以用 '%' 通配符替换任何空格,然后将其发送回对象。

    所以现在,如果您有一个名称为“word1 word2 word3”的产品并按“word1 word3”搜索过滤器,您将获得正确的结果。我愿意接受建议,这可能不是最好的方法。我会在正确测试后更新。干杯!

    9 月 06 日更新:嗯,经过一些现场测试,结果很好,正是我想要的。似乎也没有负面的性能影响。

    有趣的事实是,这个小修改适用于在管理界面中有产品网格的每个地方进行过滤(例如,当您手动创建新订单并单击添加产品时,或在管理类别中 ->任何类别 -> 类别产品选项卡)

    9 月 06 日更新 2:存在问题。如果您在订单网格中并尝试​​按状态过滤,则会引发错误。我需要使此过滤器仅适用于名称字段。有什么想法吗?

    SEP 06 UPDATE 3:我将脚本修改为仅适用于产品网格的名称字段。现在与按可见性过滤产品或按状态排序等没有冲突。

    【讨论】:

    • @Eugen Pop:真的很有帮助:)
    【解决方案4】:

    要对给定的列进行通配符 % 搜索,如果您可以覆盖核心 Grid.php,那么您可以在网格类中执行以下操作:

    protected function _prepareColumns()
    {
        parent::_prepareColumns();   
    
        // assuming the column is 'name' for product name in the product grid
        $this->getColumn('name')->setFilterConditionCallback([$this, 'allowWildcardInFilter']);
        ...
    }
    
    /**
     * Allow wildcard % in column search
     */
    public function allowWildcardInFilter($collection, $column)
    {
        if ($value = $column->getFilter()->getValue()) {
            if ($field = $column->getFilterIndex() ? $column->getFilterIndex() : $column->getIndex()) {
                /**
                 * @var $helper Mage_Core_Model_Resource_Helper_Mysql4
                 */
                $helper = Mage::getResourceHelper('core');
                $likeExpression = $helper->addLikeEscape($value, [
                    'position' => 'any',
                    'allow_string_mask' => true
                ]);
                $collection->addFieldToFilter($field, ['like' => $likeExpression]);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多