自定义搜索|错误的输出和问题

时间:2018-05-11 作者:marvinpoo

UPDATE: 我想实现的是,用户在搜索文本输入中输入XXX中的,然后选择是购买(meta\\u key=kauf,meta\\u value=1)还是租赁(meta\\u key=miete,meta\\u value=1),然后按下“搜索”。

然后需要搜索“XXX”作为meta\\u键“plz”、“ort”或“land”的meta\\u值。如果其中一个是真的?s=XXX,根据用户的选择,它可以是“买”或“租”。这是定制的post_type=immomakler_object.

目前,我正在开发一个自定义帖子类型的搜索功能。自定义post类型“posts”每X小时从XML转换到数据库。可能需要休息,但是的。。。利用现有资源。

无论如何,我添加了一个函数,可以使用搜索直接在主搜索输入中搜索邮政编码或位置。但出于某种原因,即使我搜索一个zip,它非常清晰,不应该显示错误的结果,它也会显示错误的结果。

function abc18_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\\(\\s*".$wpdb->posts.".post_title\\s+LIKE\\s*(\\\'[^\\\']+\\\')\\s*\\)/",
                        "((abc18meta.meta_key = \'plz\') AND (abc18meta.meta_value = $1))
                        OR ((abc18meta.meta_key = \'ort\') AND (abc18meta.meta_value = $1))
                        OR ((abc18meta.meta_key = \'bundesland\') AND (abc18meta.meta_value = $1))
                        OR ((abc18meta.meta_key = \'regionaler_zusatz\') AND (abc18meta.meta_value = $1))
                        AND (".$wpdb->posts.".post_type != \'post\')", $where );
    }

    return $where;
}
add_filter( \'posts_where\', \'abc18_search_where\' );
所有与搜索相关的代码如下:

/* Immo Search */
// Join left
function abc18_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {
        $join .=\' LEFT JOIN \'.$wpdb->postmeta. \' abc18meta ON \'. $wpdb->posts . \'.ID = abc18meta.post_id \';
    }

    return $join;
}
add_filter(\'posts_join\', \'abc18_search_join\' );
// include in search query
function abc18_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\\(\\s*".$wpdb->posts.".post_title\\s+LIKE\\s*(\\\'[^\\\']+\\\')\\s*\\)/",
                        "((abc18meta.meta_key = \'plz\') AND (abc18meta.meta_value = $1))
                        OR ((abc18meta.meta_key = \'ort\') AND (abc18meta.meta_value = $1))
                        OR ((abc18meta.meta_key = \'bundesland\') AND (abc18meta.meta_value = $1))
                        OR ((abc18meta.meta_key = \'regionaler_zusatz\') AND (abc18meta.meta_value = $1))
                        AND (".$wpdb->posts.".post_type != \'post\')", $where );
    }

    return $where;
}
add_filter( \'posts_where\', \'abc18_search_where\' );
//prevent dubs
function abc18_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( \'posts_distinct\', \'abc18_search_distinct\' );
下一个问题是,我试图让人们过滤他们需要的任何类型的对象,如果他们搜索要购买或租赁的对象,所以我制作了一个自定义搜索表单和一个结果页,但问题是,XML基于一个名为OpenImmo的德国标准,并且(为什么会这样)将分发导出为“buy=1/0”和/或“rent 1/0”,而不是“distribution=1/2/3/4”,我仍然需要手工检查它是miete(rent)还是kauf(buy)。现在它一点也不好用。如果有人能帮我,那就太棒了。

搜索表单:

<div id="search_header" class="pure-u-1">
  <form role="search" method="get" id="searchform" action="http://192.168.9.49/back16/">
    <div class="form-wrapper">
      <input type="text" value="" name="s" id="s" placeholder="Wo suchen Sie?" autofocus />
      <input type="hidden" name="post_type" value="immomakler_object" />
      <div class="searchexpander">
        <select class="immosearch_objart" value="" name="objektart" id="objektart">
          <option value="haus" selected="true" name="objektart" id="objektart-haus">Haus</option>
          <option value="wohnung" name="objektart" id="objektart-wohn">Wohnung</option>
          <option value="grundstück" name="objektart" id="objektart-grund">Grundstück</option>
          <option value="gewerbe" name="objektart" id="objektart-gew">Gewerbe</option>
          <option value="renditeobjekt" name="objektart" id="objektart-rend">Anlageobjekt</option>
        </select>
        <select class="immosearch_vertrieb" value="1" name="kauf" onChange="this.name = this.value; document.getReportAll.submit()" id="vertriebsart">
          <option value="kauf" name="kauf" title="kauf" id="vertrieb-kauf">Kaufen</option>
          <option value="miete" name="miete" title="miete" id="vertrieb-miete">Mieten</option>
        </select>
        <input type="submit" id="searchsubmit" value="Jetzt finden!" />
      </div>
    </div>
  </form>
</div>
结果:

<?php
$args2 = array(
    \'posts_per_page\' => 10,
    \'post_type\' => \'immomakler_object\',
    \'meta_query\' => array(
    \'relation\' => \'AND\',
    array(
        \'key\' => \'objektart\',
        \'value\' => $_GET[\'objektart\'],
        \'compare\' => \'=\'
    ),
    array(
        \'relation\' => \'OR\',
        array(
            \'key\' => \'kauf\',
            \'value\' => $_GET[\'kauf\'],
            \'compare\' => \'EXISTS\'
        ),
        array(
            \'key\' => \'miete\',
            \'value\' => $_GET[\'miete\'],
            \'compare\' => \'EXISTS\'
        )
    )
)
);
$loop2 = new WP_Query( $args2 );
while ( $loop2->have_posts() ) : $loop2->the_post();
echo \'<h3><a href="\';
the_permalink();
echo \'">\';
the_title();
echo \'</a></h3>\';
endwhile;
?>

1 个回复
最合适的回答,由SO网友:Clemens Tolboom 整理而成

==简短回答==

如果您使用Find$1 你应该使用LIKE和not= 当你与标题的LIKE. 所以更换

((abc18meta.meta_key = \'plz\') AND (abc18meta.meta_value = $1))
进入

((abc18meta.meta_key = \'plz\') AND (abc18meta.meta_value LIKE $1))
您可以通过忽略**ABC*的包装(见下文)来更改preg\\u replace搜索,但是您应该自己注意SQL注入!

==长答案==

假设我们正在搜索ABC.

preg\\u replace正在搜索prepares$where

"/\\(\\s*".$wpdb->posts.".post_title\\s+LIKE\\s*(\\\'[^\\\']+\\\')\\s*\\)/"
但它找到了什么$1 里面有一个包裹的**ABC*

{f5fd7...deb8c1b}ABC{f5fd7...deb8c1b}
然后在SQL中使用

((abc18meta.meta_key = \'plz\') AND (abc18meta.meta_value = $1))
                    OR ((abc18meta.meta_key = \'ort\') AND 
(abc18meta.meta_value = $1))
                    OR ((abc18meta.meta_key = \'bundesland\') AND 
(abc18meta.meta_value = $1))
                    OR ((abc18meta.meta_key = \'regionaler_zusatz\') AND 
(abc18meta.meta_value = $1))
此已包装ABC 的值{f5fd7...deb8c1b}ABC{f5fd7...deb8c1b} 稍后“扩展”为%ABC%

//wp-includes/wp-db.php:1789
$query = apply_filters( \'query\', $query );

结束