0

I have a text field and a drop down with country names. If I use OR and only fill in the text field with a person's name it brings back incorrect results. If I type in the name and select a country, I get correct results. If I input a name and purposefully chose the incorrect country that they are not in, I get results for the country I selected. So, something is not working correctly here.

If I use AND and only type in the persons name and leave out the country, I get no results where I would like to at least see some results based on the name search. Neither fields are required, you should be able to only search by 1 or both.

If you search only by location it should show all users for that country and if you only input a name it should show all users with that name in any country and if you search with both fields it should only show you people with that name in the specified country.

$s_query = $_GET['s'];
$country = $_GET['location'];

$args = array(
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'first_name',
            'value' => $s_query,
            'compare' => 'LIKE'
        ) ,
        array(
            'key' => 'last_name',
            'value' => $s_query,
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'location',
            'value' => $country,
            'compare' => 'LIKE'
        )
    )
);



$wp_user_query = new WP_User_Query($args);


$authors = $wp_user_query->get_results();


if (!empty($authors)) {
    echo '<ul>';

    foreach ($authors as $author) {

        $author_info = get_userdata($author->ID);
        echo '<li>' . $author_info->first_name . ' ' . $author_info->last_name . ' - ' . $author->location . '</li>';
    }
    echo '</ul>';
} else {
    echo 'No authors found';
}

1 Answer 1

1

Note that the s query arg/string is reserved for posts, so you should use a different name for your custom user search.

So basically, you just need to "play" with the meta query nesting.

Yes, just like common (PHP) arrays can be in a multi-dimensional/multi-level format, so does the meta_query parameter, be it for WP_Query or the WP_User_Query in your case. So you could have a meta query clause in a meta query clause in a meta query clause in... well, you get the idea. :-)

And in this revised version, we're expecting the name parameter ($s_query) to always be in the <first name> <last name> format like John Doe or maybe Jane Doe Jr., so for example, if only the first name is specified, then we search in that meta only — and the location meta if a country value is specified:

// Parse the first and last names into an array.
$names = preg_split( '/ +/', trim( $s_query ), 2 );

// Then, define the meta query variable.
$meta_query = [];

// If a name if specified, add the first and last name queries to the $meta_query.
// So we're using a nested meta query clause to search in either the first and last
// name meta.
if ( $s_query ) {
    $name_query = [];

    if ( ! empty( $names[0] ) ) {
        $name_query[] = [ // child clause
            'key'     => 'first_name',
            'value'   => $names[0],
            'compare' => 'LIKE',
        ];
    }

    if ( ! empty( $names[1] ) ) {
        $name_query[] = [ // child clause
            'key'     => 'last_name',
            'value'   => $names[1],
            'compare' => 'LIKE',
        ];
    }

    // Add a top-level clause for $s_query
    if ( ! empty( $name_query ) ) {
        $name_query['relation'] = 'AND';
        $meta_query[] = $name_query;
    }
}

// If a country is specified, add the country query to the $meta_query.
if ( $country ) {
    $meta_query[] = [ // top-level clause
        'key'     => 'location',
        'value'   => $country,
        'compare' => 'LIKE',
    ];
}

// Now set the relationship for the top-level meta query clauses.
$meta_query['relation'] = ( $s_query && $country ) ? 'AND' : 'OR';

// Then add the meta query to the main query args (for WP_User_Query).
$args = [
    'meta_query' => $meta_query,
];
9
  • Hi, apologies for delayed response. I will only be back at my desk tomorrow and will most certainly try this out and give you feedback. Thanks again for your answer, it is much appreciated. Commented Jun 17, 2020 at 17:41
  • Take your time. :)
    – Sally CJ
    Commented Jun 18, 2020 at 6:35
  • Hi again, so I have implemented your code and it works pretty nicely except for when I search by first name AND last name. If I copy and paste the name exactly as it should be in the text field I get no results. So, if I search for just 'John' I get results but if I search for 'John Smith' I get no results even though there is a user with first name John and last name Smith Commented Jun 18, 2020 at 9:04
  • Hi, I don't see how are you parsing the first and last names from the s parameter - you used $s_query = $_GET['s']; - so do you actually have two name fields in your form, or you just want to parse the names from that s field?
    – Sally CJ
    Commented Jun 18, 2020 at 9:43
  • 1
    You are a lifesaver, thank you so very much! Commented Jun 18, 2020 at 18:30

Your Answer

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

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