0

UPDATE: What I want to achieve is, that a user put's in XXX into the search text input and selects wether it is buy (meta_key=kauf, meta_value=1) or rent (meta_key=miete, meta_value=1) and then pushes "search".

Then it needs to search for "XXX" as meta_value of the meta_keys "plz", "ort" or "land". If one of these is exactly ?s=XXX and it is either buy or rent, as the user selected. This is for the custom post_type=immomakler_object.


Currently I am working on a search function for a custom post type. The custom post type "posts" are transformed from an XML to the database every X hours. Would use rest but yeah ... work with what you have.

Anyway, I have added a function to use the search to search directly for the ZIP code or Location in the main search input. But for some reason, even if I search for a zip, which is pretty clear and shouldn't show wrong results, it shows wrong results.

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' );

The whole code for all that's related to the search is:

/* 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' );

Next problem is, I am trying to let people filter whatever kind of object they need and if they search for something to buy or to rent, so I've made a custom search form and a result page, but the problem is, that the XML is based on a german standard called OpenImmo and (why the hell ever) exports the distribution like "buy=1/0" and/or "rent 1/0" instead of making it "distribution=1/2/3/4" I still have to check if it is EITHER miete (rent) OR kauf (buy) by hand. Right now it is not really working fine at all. So if anyone could help me, that would be super awesome.

Search form:

<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>

Result:

<?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;
?>
7
  • opened bounty as absolutely no interaction has happened yet.
    – marvinpoo
    May 14, 2018 at 10:05
  • 1
    what is the result with this code ? edit you question to explain the debug you have done.
    – mmm
    May 14, 2018 at 11:46
  • If I search for 12555 (zip) as example it shows me results for 15569. Not even all results from all zips, but only from this specific post code. -|- All the related code is already in the initial question. The first code-panel is what I have added to search for the specific meta-key-value (which are the ZIP/plz, the Location/Ort, the State/Bundesland and the regional-addition/regionaler-zusatz (not yet used anyway)
    – marvinpoo
    May 14, 2018 at 12:04
  • The question is way to specific as in 'not easily testable'. Have you tried to reduce it to a single meta filter query? May 17, 2018 at 17:35
  • It's not very "specific" Basically it is: Search custom post_type for value of custom meta. Filtered by either Y or X. It's not very specific, it's just that almost no-one knows how to professionally use the search or is not willing to help.
    – marvinpoo
    May 18, 2018 at 8:58

1 Answer 1

1
+50

== Short answer ==

If you use the found $1 you should use LIKE and not = as you match against the title's LIKE. So replace

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

into

((abc18meta.meta_key = 'plz') AND (abc18meta.meta_value LIKE $1))

You could change your preg_replace search by ignore the wrapping (see below) of **ABC* but then you should take care for SQL-injection yourself!

== Long answer ==

Say we are searching for ABC.

Your preg_replace is searching for the prepares $where

"/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/"

but what it finds for $1 in there is a wrapped **ABC*

{f5fd7...deb8c1b}ABC{f5fd7...deb8c1b}

which you then use in your 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))

This wrapped ABC value of {f5fd7...deb8c1b}ABC{f5fd7...deb8c1b} is later 'expanded' into %ABC%

//wp-includes/wp-db.php:1789
$query = apply_filters( 'query', $query );
3
  • Well, I used that way before (LIKE instead of = ). It's not having a difference, but the long answer helped me elsewise. Thanks.
    – marvinpoo
    May 22, 2018 at 7:20
  • 1
    Nice it helped. I'm curious what you changed to make it work. Maybe add a section to your question? Cheers! May 22, 2018 at 7:56
  • Thanks @Clemens Tolboom, I will make an detailed summary after I am back from my holiday trip and have access to the code :P
    – marvinpoo
    May 23, 2018 at 7:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.