0

I have meta field with key"app_i_have" and values in my mysql db like: a:3:{i:0;s:14:"mobile studio";i:1;s:12:"own studio";i:2;s:9:"makeup artist";} Now i want to query posts through the pre_get_posts hook like this:

add_action( 'pre_get_posts', 'rt_tax_archive' );
function rt_tax_archive($query) {
    if (is_admin()) {
        return; /* If we're in the admin panel - drop out */
    }
    global $wp_query;
//For searching
    if ($query->is_main_query() && isset($_GET['ls'])) {
    $rt_field_id_i_have = $_GET['listing_i_have'];
        //Filter posts by what they have
        if (isset($rt_field_id_i_have) && 
        !empty($rt_field_id_i_have[0])) {
            $meta_query[] = array(
                    'key'=>'app_i_have',
                    'value'=>$rt_field_id_i_have[0],
                    'compare'=>'LIKE',
                );
        }
$query->set('meta_query', $meta_query);
}
}

This works, but when i want to filter on people with, for instance, "own studio" the 'compare'=>'LIKE' is also showing people with a "mobile studio". I guess because the word "studio" is in there.

How can i correctly filter the posts in this situation? Thanks

  • What does the URL look like that would do this filtering? To use LIKE you typically need to include wildcards (%), so unless $rt_field_id_i_have[0] includes those characters, I don't see how this works at all. – Jacob Peattie Oct 30 '17 at 14:11
  • Hi, the url would look like ?ls=&listing_i_have=own%20studio. It seems to be working. Any suggestions are welcome. – RobbTe Oct 30 '17 at 14:17
1

If the query string contains, as you say:
listing_i_have=own%20studio

It's not working because $rt_field_id_i_have[0] is equal to the first character in the string (it's not an array), it's a string. The 0 index position is the letter o, which matches A LOT of things.

You can add the proper meta query like so.

<?php
function rt_tax_archive($query) {
    if (is_admin()) {
        return;
    } elseif ( ! $query->is_main_query() ) {
        return;
    } elseif ( ! isset( $_GET['ls'] ) ) {
       return;
    } elseif ( empty( $_GET['listing_i_have'] ) ) {
       return;
    } elseif ( ! is_string( $_GET['listing_i_have'] ) ) {
       return;
    }
    $rt_field_id_i_have = wp_unslash( $_GET['listing_i_have'] );
    $rt_field_id_i_have = sanitize_text_field( $rt_field_id_i_have );

    $query->set('meta_query', array(
        'key'    => 'app_i_have',
        'value'  => $rt_field_id_i_have,
        'compare'=> 'LIKE',
    ));
}
add_action( 'pre_get_posts', 'rt_tax_archive' );

It's worth noting that when using LIKE, WordPress automatically wraps the value inside %[value]%, so you don't need to include the LIKE wildcards yourself. You weren't doing so, just thought I'd mention that for posterity.

  • Thanks, Ive found however that compare => 'REGEXP' works. Is that a solution that's good? – RobbTe Nov 6 '17 at 18:37
  • Yes, and that can be more effective when searching through serialized data, which is a hackety thing to do to begin with, but made slightly more intelligent when using REGEXP. That is slower though, so don't use it unless you have a good use case for it such as this one. – jaswrks Nov 6 '17 at 18:39

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.