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;
?>
  • opened bounty as absolutely no interaction has happened yet. – marvinpoo May 14 '18 at 10:05
  • 1
    what is the result with this code ? edit you question to explain the debug you have done. – mmm May 14 '18 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 '18 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? – Clemens Tolboom May 17 '18 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 '18 at 8:58
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 );
  • 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 '18 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! – Clemens Tolboom May 22 '18 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 '18 at 7:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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